using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; namespace Questionable.Controller.Steps; internal sealed class TaskQueue { private readonly List _completedTasks = new List(); private readonly List _tasks = new List(); public ITaskExecutor? CurrentTaskExecutor { get; set; } public IEnumerable RemainingTasks => _tasks; public bool AllTasksComplete { get { if (CurrentTaskExecutor == null) { return _tasks.Count == 0; } return false; } } public void Enqueue(ITask task) { _tasks.Add(task); } public void EnqueueAll(IEnumerable tasks) { _tasks.InsertRange(0, tasks); } public bool TryDequeue([NotNullWhen(true)] out ITask? task) { task = _tasks.FirstOrDefault(); if (task == null) { return false; } if (task.ShouldRedoOnInterrupt()) { _completedTasks.Add(task); } _tasks.RemoveAt(0); return true; } public bool TryPeek([NotNullWhen(true)] out ITask? task) { task = _tasks.FirstOrDefault(); return task != null; } public void Reset() { _tasks.Clear(); _completedTasks.Clear(); CurrentTaskExecutor = null; } public void InterruptWith(List interruptionTasks) { List list = new List(); list.AddRange(interruptionTasks); list.AddRange(_completedTasks.Where((ITask x) => x != CurrentTaskExecutor?.CurrentTask).ToList()); list.Add(CurrentTaskExecutor?.CurrentTask); list.AddRange(_tasks); List source = list; Reset(); _tasks.AddRange(source.Where((ITask x) => x != null).Cast()); } }