using FileTime.Core.Command; namespace FileTime.Core.Timeline { public class ParallelCommands { private static ushort _idCounter; public List _commands; public ushort Id { get; } public IReadOnlyList Commands { get; } public PointInTime? Result { get; private set; } public ParallelCommands(PointInTime? result) : this(new List(), result) { } private ParallelCommands(List commands, PointInTime? result) { Id = _idCounter++; _commands = commands; Commands = _commands.AsReadOnly(); Result = result; } public static async Task Create(PointInTime? startTime, IEnumerable commands) { var commandStates = new List(); var currentTime = startTime; foreach (var command in commands) { CommandTimeState commandTimeState = new(command, currentTime); if (currentTime != null) { var canRun = await command.CanRun(currentTime); if (canRun == CanCommandRun.True) { currentTime = await command.SimulateCommand(currentTime); } else { currentTime = null; } } commandStates.Add(commandTimeState); } return new ParallelCommands(commandStates, currentTime); } public async Task AddCommand(ICommand command) { _commands.Add(new CommandTimeState(command, Result)); if (Result != null) { Result = await command.SimulateCommand(Result); } } public async Task RefreshResult(PointInTime? startPoint) { var result = startPoint; foreach (var command in _commands) { await command.UpdateState(result); if (result != null) { var canRun = await command.Command.CanRun(result); if (canRun == CanCommandRun.True || (canRun == CanCommandRun.Forceable && command.ForceRun)) { result = await command.Command.SimulateCommand(result); } else { result = null; } } } Result = result; return Result; } public void RemoveAt(int number) => _commands.RemoveAt(number); internal void Remove(CommandTimeState command) => _commands.Remove(command); } }