oecs-sharp/OECS/InterruptStore.cs

70 lines
1.9 KiB
C#
Raw Permalink Normal View History

namespace OECS;
/// <summary>
/// Internal store for pending interrupts. Owned by <see cref="SystemGroup"/>
/// and injected into <see cref="World"/> so the handler's default Execute
/// can access it.
/// </summary>
internal class InterruptStore
{
private readonly Dictionary<Type, object> _interrupts = new();
/// <summary>
/// Stores an interrupt. Only one interrupt of a given type may be pending.
/// </summary>
public void Add<T>(T interrupt) where T : struct, IInterrupt
{
var type = typeof(T);
if (_interrupts.ContainsKey(type))
throw new InvalidOperationException(
$"An interrupt of type {type.Name} is already pending.");
_interrupts[type] = interrupt;
}
/// <summary>
/// Tries to retrieve a pending interrupt of type <typeparamref name="T"/>.
/// </summary>
public bool TryGet<T>(out T interrupt) where T : struct, IInterrupt
{
if (_interrupts.TryGetValue(typeof(T), out var boxed))
{
interrupt = (T)boxed;
return true;
}
interrupt = default;
return false;
}
/// <summary>
/// Removes the pending interrupt of type <typeparamref name="T"/>.
/// No-op if none is pending.
/// </summary>
public bool Remove<T>() where T : struct, IInterrupt
{
return _interrupts.Remove(typeof(T));
}
/// <summary>
/// True if any interrupt is currently pending.
/// </summary>
public bool HasAny => _interrupts.Count > 0;
/// <summary>
/// True if an interrupt of type <typeparamref name="T"/> is pending.
/// </summary>
public bool Has<T>() where T : struct, IInterrupt
{
return _interrupts.ContainsKey(typeof(T));
}
/// <summary>
/// Clears all pending interrupts. Used during world reset or serialization load.
/// </summary>
internal void Clear()
{
_interrupts.Clear();
}
}