84 lines
2.4 KiB
C#
84 lines
2.4 KiB
C#
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.
|
|
/// Uses a constrained generic to avoid boxing struct commands.
|
|
/// </summary>
|
|
public void Enqueue<T>(T command) where T : struct, ICommand
|
|
{
|
|
// Boxing still occurs here because the heterogeneous queue stores
|
|
// ICommand references, but the constrained generic on the method
|
|
// avoids boxing at the call site.
|
|
_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();
|
|
}
|
|
}
|