123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 |
- //------------------------------------------------------------
- // Game Framework
- // Copyright © 2013-2021 loyalsoft. All rights reserved.
- // Homepage: http://www.game7000.com/
- // Feedback: http://www.game7000.com/
- //------------------------------------------------------------
- using System.Collections.Generic;
- namespace GameFramework
- {
- /// <summary>
- /// 任务池。
- /// </summary>
- /// <typeparam name="T">任务类型。</typeparam>
- internal sealed class TaskPool<T> where T : TaskBase
- {
- private readonly Stack<ITaskAgent<T>> m_FreeAgents;
- private readonly GameFrameworkLinkedList<ITaskAgent<T>> m_WorkingAgents;
- private readonly GameFrameworkLinkedList<T> m_WaitingTasks;
- private bool m_Paused;
- /// <summary>
- /// 初始化任务池的新实例。
- /// </summary>
- public TaskPool()
- {
- m_FreeAgents = new Stack<ITaskAgent<T>>();
- m_WorkingAgents = new GameFrameworkLinkedList<ITaskAgent<T>>();
- m_WaitingTasks = new GameFrameworkLinkedList<T>();
- m_Paused = false;
- }
- /// <summary>
- /// 获取或设置任务池是否被暂停。
- /// </summary>
- public bool Paused
- {
- get
- {
- return m_Paused;
- }
- set
- {
- m_Paused = value;
- }
- }
- /// <summary>
- /// 获取任务代理总数量。
- /// </summary>
- public int TotalAgentCount
- {
- get
- {
- return FreeAgentCount + WorkingAgentCount;
- }
- }
- /// <summary>
- /// 获取可用任务代理数量。
- /// </summary>
- public int FreeAgentCount
- {
- get
- {
- return m_FreeAgents.Count;
- }
- }
- /// <summary>
- /// 获取工作中任务代理数量。
- /// </summary>
- public int WorkingAgentCount
- {
- get
- {
- return m_WorkingAgents.Count;
- }
- }
- /// <summary>
- /// 获取等待任务数量。
- /// </summary>
- public int WaitingTaskCount
- {
- get
- {
- return m_WaitingTasks.Count;
- }
- }
- /// <summary>
- /// 任务池轮询。
- /// </summary>
- /// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
- /// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
- public void Update(float elapseSeconds, float realElapseSeconds)
- {
- if (m_Paused)
- {
- return;
- }
- ProcessRunningTasks(elapseSeconds, realElapseSeconds);
- ProcessWaitingTasks(elapseSeconds, realElapseSeconds);
- }
- /// <summary>
- /// 关闭并清理任务池。
- /// </summary>
- public void Shutdown()
- {
- RemoveAllTasks();
- while (FreeAgentCount > 0)
- {
- m_FreeAgents.Pop().Shutdown();
- }
- }
- /// <summary>
- /// 增加任务代理。
- /// </summary>
- /// <param name="agent">要增加的任务代理。</param>
- public void AddAgent(ITaskAgent<T> agent)
- {
- if (agent == null)
- {
- throw new GameFrameworkException("Task agent is invalid.");
- }
- agent.Initialize();
- m_FreeAgents.Push(agent);
- }
- /// <summary>
- /// 根据任务的序列编号获取任务的信息。
- /// </summary>
- /// <param name="serialId">要获取信息的任务的序列编号。</param>
- /// <returns>任务的信息。</returns>
- public TaskInfo GetTaskInfo(int serialId)
- {
- foreach (ITaskAgent<T> 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);
- }
- /// <summary>
- /// 根据任务的标签获取任务的信息。
- /// </summary>
- /// <param name="tag">要获取信息的任务的标签。</param>
- /// <returns>任务的信息。</returns>
- public TaskInfo[] GetTaskInfos(string tag)
- {
- List<TaskInfo> results = new List<TaskInfo>();
- GetTaskInfos(tag, results);
- return results.ToArray();
- }
- /// <summary>
- /// 根据任务的标签获取任务的信息。
- /// </summary>
- /// <param name="tag">要获取信息的任务的标签。</param>
- /// <param name="results">任务的信息。</param>
- public void GetTaskInfos(string tag, List<TaskInfo> results)
- {
- if (results == null)
- {
- throw new GameFrameworkException("Results is invalid.");
- }
- results.Clear();
- foreach (ITaskAgent<T> 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));
- }
- }
- }
- /// <summary>
- /// 获取所有任务的信息。
- /// </summary>
- /// <returns>所有任务的信息。</returns>
- public TaskInfo[] GetAllTaskInfos()
- {
- int index = 0;
- TaskInfo[] results = new TaskInfo[m_WorkingAgents.Count + m_WaitingTasks.Count];
- foreach (ITaskAgent<T> 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;
- }
- /// <summary>
- /// 获取所有任务的信息。
- /// </summary>
- /// <param name="results">所有任务的信息。</param>
- public void GetAllTaskInfos(List<TaskInfo> results)
- {
- if (results == null)
- {
- throw new GameFrameworkException("Results is invalid.");
- }
- results.Clear();
- foreach (ITaskAgent<T> 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));
- }
- }
- /// <summary>
- /// 增加任务。
- /// </summary>
- /// <param name="task">要增加的任务。</param>
- public void AddTask(T task)
- {
- LinkedListNode<T> 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);
- }
- }
- /// <summary>
- /// 根据任务的序列编号移除任务。
- /// </summary>
- /// <param name="serialId">要移除任务的序列编号。</param>
- /// <returns>是否移除任务成功。</returns>
- 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<ITaskAgent<T>> currentWorkingAgent = m_WorkingAgents.First;
- while (currentWorkingAgent != null)
- {
- LinkedListNode<ITaskAgent<T>> next = currentWorkingAgent.Next;
- ITaskAgent<T> 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;
- }
- /// <summary>
- /// 根据任务的标签移除任务。
- /// </summary>
- /// <param name="tag">要移除任务的标签。</param>
- /// <returns>移除任务的数量。</returns>
- public int RemoveTasks(string tag)
- {
- int count = 0;
- LinkedListNode<T> currentWaitingTask = m_WaitingTasks.First;
- while (currentWaitingTask != null)
- {
- LinkedListNode<T> next = currentWaitingTask.Next;
- T task = currentWaitingTask.Value;
- if (task.Tag == tag)
- {
- m_WaitingTasks.Remove(currentWaitingTask);
- ReferencePool.Release(task);
- count++;
- }
- currentWaitingTask = next;
- }
- LinkedListNode<ITaskAgent<T>> currentWorkingAgent = m_WorkingAgents.First;
- while (currentWorkingAgent != null)
- {
- LinkedListNode<ITaskAgent<T>> next = currentWorkingAgent.Next;
- ITaskAgent<T> 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;
- }
- /// <summary>
- /// 移除所有任务。
- /// </summary>
- /// <returns>移除任务的数量。</returns>
- 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<T> 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<ITaskAgent<T>> 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<ITaskAgent<T>> 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<T> current = m_WaitingTasks.First;
- while (current != null && FreeAgentCount > 0)
- {
- ITaskAgent<T> agent = m_FreeAgents.Pop();
- LinkedListNode<ITaskAgent<T>> agentNode = m_WorkingAgents.AddLast(agent);
- T task = current.Value;
- LinkedListNode<T> 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;
- }
- }
- }
- }
|