AssetAsyncPool.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. using XGame.Framework.Asyncs;
  2. using System.Collections.Generic;
  3. namespace XGame.Framework.Asset
  4. {
  5. /// <summary>
  6. /// 加载任务的异步操作池
  7. /// </summary>
  8. internal sealed class AssetAsyncPool
  9. {
  10. /// <summary>
  11. /// 未使用的Agents
  12. /// </summary>
  13. Stack<IAssetAsyncAgent> FreeAgents { set; get; }
  14. /// <summary>
  15. /// 使用中的Agents
  16. /// </summary>
  17. //LinkedList<IAssetAsyncAgent> WorkingAgents { set; get; }
  18. Dictionary<IAssetAsync, IAssetAsyncAgent> WorkingAgents { set; get; }
  19. /// <summary>
  20. /// 等待处理的Async
  21. /// </summary>
  22. LinkedList<IAssetAsync> WaitingAsyncs { set; get; }
  23. /// <summary>
  24. /// 存储所有未完成的Async,方便查找
  25. /// </summary>
  26. Dictionary<string, IAssetAsync> AssetAsyncMap { set; get; }
  27. /// <summary>
  28. /// 是否被暂停。
  29. /// </summary>
  30. public bool Paused { set; get; }
  31. /// <summary>
  32. /// agent的数量上限
  33. /// </summary>
  34. public int AgentLimit { set; get; }
  35. /// <summary>
  36. /// 构造函数。
  37. /// </summary>
  38. public AssetAsyncPool()
  39. {
  40. FreeAgents = new Stack<IAssetAsyncAgent>();
  41. WorkingAgents = new Dictionary<IAssetAsync, IAssetAsyncAgent>();
  42. WaitingAsyncs = new LinkedList<IAssetAsync>();
  43. AssetAsyncMap = new Dictionary<string, IAssetAsync>();
  44. Paused = false;
  45. AgentLimit = 0;
  46. }
  47. /// <summary>
  48. /// 获取代理总数量。
  49. /// 包括使用中和未使用的代理,不一定等于AgentLimit
  50. /// </summary>
  51. public int TotalAgentCount => (FreeAgentCount + WorkingAgentCount);
  52. /// <summary>
  53. /// 获取可用代理数量。
  54. /// 仅返回缓存池中未使用的代理数量
  55. /// </summary>
  56. public int FreeAgentCount => FreeAgents.Count;
  57. /// <summary>
  58. /// 获取工作中代理数量。
  59. /// </summary>
  60. public int WorkingAgentCount => WorkingAgents.Count;
  61. /// <summary>
  62. /// 获取等待Async数量。
  63. /// </summary>
  64. public int WaitingAsyncCount => WaitingAsyncs.Count;
  65. /// <summary>
  66. /// 获取未完成的Async
  67. /// </summary>
  68. /// <param name="addressableName"></param>
  69. /// <returns></returns>
  70. public IAssetAsync GetAssetAsync(string addressableName)
  71. {
  72. AssetAsyncMap.TryGetValue(addressableName, out IAssetAsync assetAsync);
  73. return assetAsync;
  74. }
  75. /// <summary>
  76. /// 是否包含指定的Async
  77. /// </summary>
  78. /// <param name="path"></param>
  79. /// <returns></returns>
  80. public bool ContainsAssetAsync(string addressableName)
  81. {
  82. return AssetAsyncMap.ContainsKey(addressableName);
  83. }
  84. /// <summary>
  85. /// 获取未使用的Agent
  86. /// 可能从缓存里取,也可能是新建的Agent
  87. /// </summary>
  88. /// <returns></returns>
  89. private IAssetAsyncAgent GetFreeAgent()
  90. {
  91. if (FreeAgents.Count > 0)
  92. {
  93. return FreeAgents.Pop();
  94. }
  95. if (TotalAgentCount < AgentLimit)
  96. {
  97. var agent = new AssetAsyncAgent();
  98. return agent;
  99. }
  100. return null;
  101. }
  102. /// <summary>
  103. /// 增加AssetAsync。
  104. /// </summary>
  105. /// <param name="assetAsync"></param>
  106. public void AddAsync(IAssetAsync assetAsync)
  107. {
  108. if (AssetAsyncMap.ContainsKey(assetAsync.AddressableName))
  109. {
  110. //AssetsLog.Debug("Asset Add Async Repeat. Name:{0}", assetAsync.AddressableName);
  111. return;
  112. }
  113. AssetAsyncMap.Add(assetAsync.AddressableName, assetAsync);
  114. LinkedListNode<IAssetAsync> current = WaitingAsyncs.Last;
  115. if (current != null)
  116. {
  117. WaitingAsyncs.AddAfter(current, assetAsync);
  118. }
  119. else
  120. {
  121. WaitingAsyncs.AddFirst(assetAsync);
  122. }
  123. ProcessWaitingAsync();
  124. }
  125. ///// <summary>
  126. ///// 移除任务。
  127. ///// </summary>
  128. ///// <param name="serialId">要移除任务的序列编号。</param>
  129. ///// <returns>被移除的任务。</returns>
  130. //public bool RemoveAsync(int serialId)
  131. //{
  132. // foreach (IAssetAsync waitingAsync in WaitingAsyncs)
  133. // {
  134. // if (waitingAsync.SerialId == serialId)
  135. // {
  136. // WaitingAsyncs.Remove(waitingAsync);
  137. // return true;
  138. // }
  139. // }
  140. // foreach (IAssetAsyncAgent workingAgent in WorkingAgents)
  141. // {
  142. // if (workingAgent.Task.SerialId == serialId)
  143. // {
  144. // workingAgent.Stop();
  145. // m_FreeAgents.Push(workingAgent);
  146. // WorkingAgents.Remove(workingAgent);
  147. // return true;
  148. // }
  149. // }
  150. // return false;
  151. //}
  152. private void ProcessWaitingAsync()
  153. {
  154. LinkedListNode<IAssetAsync> current = WaitingAsyncs.First;
  155. IAssetAsyncAgent agent;
  156. while (current != null && (agent = GetFreeAgent()) != null)
  157. {
  158. LinkedListNode<IAssetAsync> next = current.Next;
  159. AgentStatus status = agent.Start(current.Value);
  160. if (status == AgentStatus.CanResume)
  161. {//设置监听
  162. current.Value.On(OnAsyncCompleted);
  163. WorkingAgents.Add(current.Value, agent);
  164. }
  165. else
  166. {
  167. agent.Stop();
  168. FreeAgents.Push(agent);
  169. if (status == AgentStatus.Done || status == AgentStatus.UnknownError)
  170. {
  171. AssetAsyncMap.Remove(current.Value.AddressableName);
  172. }
  173. }
  174. if (status != AgentStatus.HasToWait)
  175. {
  176. WaitingAsyncs.Remove(current);
  177. }
  178. current = next;
  179. }
  180. }
  181. void OnAsyncCompleted(IAsync aAsync)
  182. {
  183. IAssetAsync assetAsync = aAsync as IAssetAsync;
  184. if (assetAsync != null)
  185. {
  186. if (WorkingAgents.TryGetValue(assetAsync, out IAssetAsyncAgent agent))
  187. {
  188. agent.Stop();
  189. WorkingAgents.Remove(assetAsync);
  190. FreeAgents.Push(agent);
  191. }
  192. AssetAsyncMap.Remove(assetAsync.AddressableName);
  193. }
  194. ProcessWaitingAsync();
  195. }
  196. /// <summary>
  197. /// 移除所有任务。
  198. /// </summary>
  199. public void Clear()
  200. {
  201. WaitingAsyncs.Clear();
  202. AssetAsyncMap.Clear();
  203. foreach (var it in WorkingAgents)
  204. {
  205. it.Value.Stop();
  206. FreeAgents.Push(it.Value);
  207. }
  208. WorkingAgents.Clear();
  209. }
  210. public void Dispose()
  211. {
  212. WaitingAsyncs.Clear();
  213. while (FreeAgentCount > 0)
  214. {
  215. FreeAgents.Pop().Dispose();
  216. }
  217. foreach (var it in WorkingAgents)
  218. {
  219. it.Value.Dispose();
  220. }
  221. WorkingAgents.Clear();
  222. AssetAsyncMap.Clear();
  223. }
  224. }
  225. }