1
0
Fork 0
forked from aly/qstbak
qstbak/Questionable/Questionable.Controller.Steps/TaskQueue.cs
2026-08-17 20:29:32 +10:00

103 lines
2.1 KiB
C#

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<ITask> _completedTasks = new List<ITask>();
private readonly List<ITask> _tasks = new List<ITask>();
private int _levelingTaskCount;
public ITaskExecutor? CurrentTaskExecutor { get; set; }
public IEnumerable<ITask> 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<ITask> 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<ITask> interruptionTasks)
{
List<ITask> list = new List<ITask>();
list.AddRange(interruptionTasks);
list.AddRange(_completedTasks.Where((ITask x) => x != CurrentTaskExecutor?.CurrentTask).ToList());
list.Add(CurrentTaskExecutor?.CurrentTask);
list.AddRange(_tasks);
List<ITask> source = list;
Reset();
_tasks.AddRange(source.Where((ITask x) => x != null).Cast<ITask>());
_levelingTaskCount = _tasks.Count(IsLevelingTask);
}
private static bool IsLevelingTask(ITask task)
{
if (task is Duty.StartLevelingModeTask || task is Duty.WaitLevelingModeTask)
{
return true;
}
return false;
}
}