oecs-sharp/src/OECS/CommandQueue.cs

80 lines
2.1 KiB
C#
Raw Normal View History

namespace OECS;
/// <summary>
/// A FIFO queue of <see cref="ICommand"/> instances with deferred execution.
///
/// Commands are executed in the order they were enqueued. If a command's
/// <see cref="ICommand.Execute"/> throws, the exception is caught and stored;
/// remaining commands continue to execute.
///
/// Commands enqueued during <see cref="ExecuteAll"/> are processed in the
/// same drain cycle — the queue keeps draining until empty.
/// </summary>
public class CommandQueue
{
private readonly List<ICommand> _commands = new();
private readonly List<Exception> _errors = new();
/// <summary>
/// Number of commands currently waiting in the queue.
/// </summary>
public int Count => _commands.Count;
/// <summary>
/// Exceptions thrown by commands during <see cref="ExecuteAll"/> calls.
/// Accumulates across drain cycles. Call <see cref="ClearErrors"/> to reset.
/// </summary>
public IReadOnlyList<Exception> Errors => _errors;
/// <summary>
/// Adds a command to the end of the queue.
/// </summary>
public void Enqueue(ICommand command)
{
_commands.Add(command);
}
/// <summary>
/// Executes all queued commands in FIFO order against the given world.
///
/// The queue is fully drained — commands enqueued by other commands during
/// this call are also executed before the method returns.
/// </summary>
public void ExecuteAll(World world)
{
int index = 0;
while (index < _commands.Count)
{
var command = _commands[index];
index++;
try
{
command.Execute(world);
}
catch (Exception ex)
{
_errors.Add(ex);
}
}
_commands.Clear();
}
/// <summary>
/// Clears all queued commands without executing them.
/// </summary>
public void Clear()
{
_commands.Clear();
}
/// <summary>
/// Clears accumulated error history.
/// </summary>
public void ClearErrors()
{
_errors.Clear();
}
}