using Convention.Collections; using Convention.Collections.Generic; using Convention.ReferenceManagement; using System; using System.Collections.Generic; using System.Runtime.InteropServices; namespace Convention.TaskManagement { /// /// 任务基类 /// public abstract class TaskBase: IReference { /// /// 任务默认优先级。 /// public const int DefaultPriority = 0; private int m_SerialId; private string m_Tag; private int m_Priority; private object m_UserData; private bool m_Done; /// /// 初始化任务基类的新实例 /// public TaskBase() { m_SerialId = 0; m_Tag = null; m_Priority = DefaultPriority; m_Done = false; m_UserData = null; } /// /// 获取任务的序列编号 /// public int SerialId { get { return m_SerialId; } } /// /// 获取任务的标签 /// public string Tag { get { return m_Tag; } } /// /// 获取任务的优先级 /// public int Priority { get { return m_Priority; } } /// /// 获取任务的用户自定义数据 /// public object UserData { get { return m_UserData; } } /// /// 获取或设置任务是否完成 /// public bool Done { get { return m_Done; } set { m_Done = value; } } /// /// 获取任务描述 /// public virtual string Description { get { return null; } } /// /// 初始化任务基类 /// /// 任务的序列编号 /// 任务的标签 /// 任务的优先级 /// 任务的用户自定义数据 internal void Initialize(int serialId, string tag, int priority, object userData) { m_SerialId = serialId; m_Tag = tag; m_Priority = priority; m_UserData = userData; m_Done = false; } /// /// 清理任务基类 /// public virtual void Clear() { m_SerialId = 0; m_Tag = null; m_Priority = DefaultPriority; m_UserData = null; m_Done = false; } } /// /// 开始处理任务的状态 /// public enum StartTaskStatus : byte { /// /// 可以立刻处理完成此任务 /// Done = 0, /// /// 可以继续处理此任务 /// CanResume, /// /// 不能继续处理此任务,需等待其它任务执行完成 /// HasToWait, /// /// 不能继续处理此任务,出现未知错误 /// UnknownError } /// /// 任务代理接口 /// /// 任务类型 public interface ITaskAgent where T : TaskBase { /// /// 获取任务 /// T Task { get; } /// /// 初始化任务代理 /// void Initialize(); /// /// 任务代理轮询 /// /// 逻辑流逝时间,以秒为单位 /// 真实流逝时间,以秒为单位 void Update(float elapseSeconds, float realElapseSeconds); /// /// 关闭并清理任务代理 /// void Shutdown(); /// /// 开始处理任务 /// /// 要处理的任务 /// 开始处理任务的状态 StartTaskStatus Start(T task); /// /// 停止正在处理的任务并重置任务代理 /// void Reset(); } /// /// 任务状态 /// public enum TaskStatus : byte { /// /// 未开始 /// Todo = 0, /// /// 执行中 /// Doing, /// /// 完成 /// Done } /// /// 任务信息 /// [StructLayout(LayoutKind.Auto)] public readonly struct TaskInfo { private readonly bool m_IsValid; private readonly int m_SerialId; private readonly string m_Tag; private readonly int m_Priority; private readonly object m_UserData; private readonly TaskStatus m_Status; private readonly string m_Description; /// /// 初始化任务信息的新实例。 /// /// 任务的序列编号 /// 任务的标签 /// 任务的优先级 /// 任务的用户自定义数据 /// 任务状态 /// 任务描述 public TaskInfo(int serialId, string tag, int priority, object userData, TaskStatus status, string description) { m_IsValid = true; m_SerialId = serialId; m_Tag = tag; m_Priority = priority; m_UserData = userData; m_Status = status; m_Description = description; } /// /// 获取任务信息是否有效 /// public bool IsValid { get { return m_IsValid; } } /// /// 获取任务的序列编号 /// public int SerialId { get { if (!m_IsValid) { throw new InvalidOperationException("Data is invalid."); } return m_SerialId; } } /// /// 获取任务的标签 /// public string Tag { get { if (!m_IsValid) { throw new InvalidOperationException("Data is invalid."); } return m_Tag; } } /// /// 获取任务的优先级 /// public int Priority { get { if (!m_IsValid) { throw new InvalidOperationException("Data is invalid."); } return m_Priority; } } /// /// 获取任务的用户自定义数据 /// public object UserData { get { if (!m_IsValid) { throw new InvalidOperationException("Data is invalid."); } return m_UserData; } } /// /// 获取任务状态 /// public TaskStatus Status { get { if (!m_IsValid) { throw new InvalidOperationException("Data is invalid."); } return m_Status; } } /// /// 获取任务描述 /// public string Description { get { if (!m_IsValid) { throw new InvalidOperationException("Data is invalid."); } return m_Description; } } } /// /// 任务池 /// /// 任务类型 public class TaskPool where T : TaskBase { private readonly Stack> m_FreeAgents; private readonly LinkedCacheList> m_WorkingAgents; private readonly LinkedCacheList m_WaitingTasks; private bool m_Paused; /// /// 初始化任务池的新实例。 /// public TaskPool() { m_FreeAgents = new Stack>(); m_WorkingAgents = new LinkedCacheList>(); m_WaitingTasks = new LinkedCacheList(); m_Paused = false; } /// /// 获取或设置任务池是否被暂停。 /// public bool Paused { get { return m_Paused; } set { m_Paused = value; } } /// /// 获取任务代理总数量。 /// public int TotalAgentCount { get { return FreeAgentCount + WorkingAgentCount; } } /// /// 获取可用任务代理数量。 /// public int FreeAgentCount { get { return m_FreeAgents.Count; } } /// /// 获取工作中任务代理数量。 /// public int WorkingAgentCount { get { return m_WorkingAgents.Count; } } /// /// 获取等待任务数量。 /// public int WaitingTaskCount { get { return m_WaitingTasks.Count; } } /// /// 任务池轮询。 /// /// 逻辑流逝时间,以秒为单位。 /// 真实流逝时间,以秒为单位。 public void Update(float elapseSeconds, float realElapseSeconds) { if (m_Paused) { return; } ProcessRunningTasks(elapseSeconds, realElapseSeconds); ProcessWaitingTasks(elapseSeconds, realElapseSeconds); } /// /// 关闭并清理任务池。 /// public void Shutdown() { RemoveAllTasks(); while (FreeAgentCount > 0) { m_FreeAgents.Pop().Shutdown(); } } /// /// 增加任务代理。 /// /// 要增加的任务代理。 public void AddAgent(ITaskAgent agent) { if (agent == null) { throw new InvalidOperationException("Task agent is invalid."); } agent.Initialize(); m_FreeAgents.Push(agent); } /// /// 根据任务的序列编号获取任务的信息。 /// /// 要获取信息的任务的序列编号。 /// 任务的信息。 public TaskInfo GetTaskInfo(int serialId) { foreach (ITaskAgent workingAgent in m_WorkingAgents) { T workingTask = workingAgent.Task; if (workingTask.SerialId == serialId) { return new TaskInfo(workingTask.SerialId, workingTask.Tag, workingTask.Priority, workingTask.UserData, workingTask.Done ? TaskStatus.Done : TaskStatus.Doing, workingTask.Description); } } foreach (T waitingTask in m_WaitingTasks) { if (waitingTask.SerialId == serialId) { return new TaskInfo(waitingTask.SerialId, waitingTask.Tag, waitingTask.Priority, waitingTask.UserData, TaskStatus.Todo, waitingTask.Description); } } return default(TaskInfo); } /// /// 根据任务的标签获取任务的信息。 /// /// 要获取信息的任务的标签。 /// 任务的信息。 public TaskInfo[] GetTaskInfos(string tag) { List results = new List(); GetTaskInfos(tag, results); return results.ToArray(); } /// /// 根据任务的标签获取任务的信息。 /// /// 要获取信息的任务的标签。 /// 任务的信息。 public void GetTaskInfos(string tag, List results) { if (results == null) { throw new InvalidOperationException("Results is invalid."); } results.Clear(); foreach (ITaskAgent workingAgent in m_WorkingAgents) { T workingTask = workingAgent.Task; if (workingTask.Tag == tag) { results.Add(new TaskInfo(workingTask.SerialId, workingTask.Tag, workingTask.Priority, workingTask.UserData, workingTask.Done ? TaskStatus.Done : TaskStatus.Doing, workingTask.Description)); } } foreach (T waitingTask in m_WaitingTasks) { if (waitingTask.Tag == tag) { results.Add(new TaskInfo(waitingTask.SerialId, waitingTask.Tag, waitingTask.Priority, waitingTask.UserData, TaskStatus.Todo, waitingTask.Description)); } } } /// /// 获取所有任务的信息。 /// /// 所有任务的信息。 public TaskInfo[] GetAllTaskInfos() { int index = 0; TaskInfo[] results = new TaskInfo[m_WorkingAgents.Count + m_WaitingTasks.Count]; foreach (ITaskAgent workingAgent in m_WorkingAgents) { T workingTask = workingAgent.Task; results[index++] = new TaskInfo(workingTask.SerialId, workingTask.Tag, workingTask.Priority, workingTask.UserData, workingTask.Done ? TaskStatus.Done : TaskStatus.Doing, workingTask.Description); } foreach (T waitingTask in m_WaitingTasks) { results[index++] = new TaskInfo(waitingTask.SerialId, waitingTask.Tag, waitingTask.Priority, waitingTask.UserData, TaskStatus.Todo, waitingTask.Description); } return results; } /// /// 获取所有任务的信息。 /// /// 所有任务的信息。 public void GetAllTaskInfos(List results) { if (results == null) { throw new InvalidOperationException("Results is invalid."); } results.Clear(); foreach (ITaskAgent workingAgent in m_WorkingAgents) { T workingTask = workingAgent.Task; results.Add(new TaskInfo(workingTask.SerialId, workingTask.Tag, workingTask.Priority, workingTask.UserData, workingTask.Done ? TaskStatus.Done : TaskStatus.Doing, workingTask.Description)); } foreach (T waitingTask in m_WaitingTasks) { results.Add(new TaskInfo(waitingTask.SerialId, waitingTask.Tag, waitingTask.Priority, waitingTask.UserData, TaskStatus.Todo, waitingTask.Description)); } } /// /// 增加任务。 /// /// 要增加的任务。 public void AddTask(T task) { LinkedListNode current = m_WaitingTasks.Last; while (current != null) { if (task.Priority <= current.Value.Priority) { break; } current = current.Previous; } if (current != null) { m_WaitingTasks.AddAfter(current, task); } else { m_WaitingTasks.AddFirst(task); } } /// /// 根据任务的序列编号移除任务。 /// /// 要移除任务的序列编号。 /// 是否移除任务成功。 public bool RemoveTask(int serialId) { foreach (T task in m_WaitingTasks) { if (task.SerialId == serialId) { m_WaitingTasks.Remove(task); ReferencePool.Release(task); return true; } } LinkedListNode> currentWorkingAgent = m_WorkingAgents.First; while (currentWorkingAgent != null) { LinkedListNode> next = currentWorkingAgent.Next; ITaskAgent workingAgent = currentWorkingAgent.Value; T task = workingAgent.Task; if (task.SerialId == serialId) { workingAgent.Reset(); m_FreeAgents.Push(workingAgent); m_WorkingAgents.Remove(currentWorkingAgent); ReferencePool.Release(task); return true; } currentWorkingAgent = next; } return false; } /// /// 根据任务的标签移除任务。 /// /// 要移除任务的标签。 /// 移除任务的数量。 public int RemoveTasks(string tag) { int count = 0; LinkedListNode currentWaitingTask = m_WaitingTasks.First; while (currentWaitingTask != null) { LinkedListNode next = currentWaitingTask.Next; T task = currentWaitingTask.Value; if (task.Tag == tag) { m_WaitingTasks.Remove(currentWaitingTask); ReferencePool.Release(task); count++; } currentWaitingTask = next; } LinkedListNode> currentWorkingAgent = m_WorkingAgents.First; while (currentWorkingAgent != null) { LinkedListNode> next = currentWorkingAgent.Next; ITaskAgent workingAgent = currentWorkingAgent.Value; T task = workingAgent.Task; if (task.Tag == tag) { workingAgent.Reset(); m_FreeAgents.Push(workingAgent); m_WorkingAgents.Remove(currentWorkingAgent); ReferencePool.Release(task); count++; } currentWorkingAgent = next; } return count; } /// /// 移除所有任务。 /// /// 移除任务的数量。 public int RemoveAllTasks() { int count = m_WaitingTasks.Count + m_WorkingAgents.Count; foreach (T task in m_WaitingTasks) { ReferencePool.Release(task); } m_WaitingTasks.Clear(); foreach (ITaskAgent workingAgent in m_WorkingAgents) { T task = workingAgent.Task; workingAgent.Reset(); m_FreeAgents.Push(workingAgent); ReferencePool.Release(task); } m_WorkingAgents.Clear(); return count; } private void ProcessRunningTasks(float elapseSeconds, float realElapseSeconds) { LinkedListNode> current = m_WorkingAgents.First; while (current != null) { T task = current.Value.Task; if (!task.Done) { current.Value.Update(elapseSeconds, realElapseSeconds); current = current.Next; continue; } LinkedListNode> next = current.Next; current.Value.Reset(); m_FreeAgents.Push(current.Value); m_WorkingAgents.Remove(current); ReferencePool.Release(task); current = next; } } private void ProcessWaitingTasks(float elapseSeconds, float realElapseSeconds) { LinkedListNode current = m_WaitingTasks.First; while (current != null && FreeAgentCount > 0) { ITaskAgent agent = m_FreeAgents.Pop(); LinkedListNode> agentNode = m_WorkingAgents.AddLast(agent); T task = current.Value; LinkedListNode next = current.Next; StartTaskStatus status = agent.Start(task); if (status == StartTaskStatus.Done || status == StartTaskStatus.HasToWait || status == StartTaskStatus.UnknownError) { agent.Reset(); m_FreeAgents.Push(agent); m_WorkingAgents.Remove(agentNode); } if (status == StartTaskStatus.Done || status == StartTaskStatus.CanResume || status == StartTaskStatus.UnknownError) { m_WaitingTasks.Remove(current); } if (status == StartTaskStatus.Done || status == StartTaskStatus.UnknownError) { ReferencePool.Release(task); } current = next; } } } }