using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using Questionable.Controller.Steps.Interactions; namespace Questionable.Controller.Steps; internal sealed class TaskQueue { private readonly List _completedTasks = new List(); private readonly List _tasks = new List(); private int _levelingTaskCount; public ITaskExecutor? CurrentTaskExecutor { get; set; } public IEnumerable RemainingTasks => _tasks; public bool AllTasksComplete { get { if (CurrentTaskExecutor == null) { return _tasks.Count == 0; } return false; } } public bool HasLevelingTasks => _levelingTaskCount > 0; public void Enqueue(ITask task) { _tasks.Add(task); if (IsLevelingTask(task)) { _levelingTaskCount++; } } public void EnqueueAll(IEnumerable tasks) { _tasks.InsertRange(0, tasks); _levelingTaskCount = _tasks.Count(IsLevelingTask); } 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); if (IsLevelingTask(task)) { _levelingTaskCount--; } 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; _levelingTaskCount = 0; } 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()); _levelingTaskCount = _tasks.Count(IsLevelingTask); } private static bool IsLevelingTask(ITask task) { if (task is Duty.StartLevelingModeTask || task is Duty.WaitLevelingModeTask) { return true; } return false; } }