NodeGroup.cs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. using System;
  2. using System.Collections.Generic;
  3. using XGame.Framework.Asyncs;
  4. using XGame.Framework.Interfaces;
  5. namespace XGame.Framework.Nodes
  6. {
  7. public class NodeGroup : INodeGroup, IUpdate, ILateUpdate, IDisposable
  8. {
  9. private Dictionary<string, Node> _openedMap;
  10. /// <summary>
  11. /// 加载中,卸载中,关闭的都在这里
  12. /// </summary>
  13. private Dictionary<string, Node> _closedMap;
  14. private List<Node> _updateNodes;
  15. /// <summary>
  16. /// 每个Group单独一个Context
  17. /// </summary>
  18. private NodeContext _context;
  19. public NodeGroup(NodeContext context)
  20. {
  21. _context = context;
  22. _openedMap = new Dictionary<string, Node>();
  23. _closedMap = new Dictionary<string, Node>();
  24. _updateNodes = new List<Node>();
  25. }
  26. #region 接口实现
  27. bool INodeGroup.IsActive(NodeKey nodeKey)
  28. {
  29. if (_openedMap.TryGetValue(nodeKey, out var node))
  30. {
  31. return node.Active;
  32. }
  33. return false;
  34. }
  35. IAsync INodeGroup.AddAsync(NodeKey nodeKey, object intent)
  36. {
  37. var key = nodeKey.Key;
  38. if (_openedMap.ContainsKey(key))
  39. {
  40. Log.Warn($"重复开启Node. Key:{key}");
  41. var asyncGroup = new AsyncGroup();
  42. asyncGroup.End();
  43. return asyncGroup;
  44. }
  45. if (_closedMap.TryGetValue(key, out var node))
  46. {
  47. if (node.State == Loadable.LoadState.Loading)
  48. {
  49. var loadingAsync = node.LoadingAsync;
  50. loadingAsync.On(_ =>
  51. {
  52. ShowNode(key, node, intent);
  53. });
  54. return loadingAsync;
  55. }
  56. if (node.State == Loadable.LoadState.Unloading)
  57. {
  58. Log.Error($"卸载中的Node又开始加载.Key:{key}");
  59. node.ClearAsyncs();
  60. }
  61. }
  62. else
  63. {
  64. node = Activator.CreateInstance(nodeKey.NodeType) as Node;
  65. node.Init(_context);
  66. _closedMap.Add(key, node);
  67. }
  68. var loadAsync = node.LoadAsync();
  69. loadAsync.On(_ =>
  70. {
  71. ShowNode(key, node, intent);
  72. });
  73. return loadAsync;
  74. }
  75. void INodeGroup.Remove(NodeKey nodeKey, bool isDestroy)
  76. {
  77. var key = nodeKey.Key;
  78. if (_closedMap.TryGetValue(key, out var node))
  79. {
  80. if (node.State == Loadable.LoadState.Unloading)
  81. {
  82. Log.Debug($"重复移除Node. Key:{key} isDestroy:{isDestroy}");
  83. if (isDestroy)
  84. { // 保证能执行destroy
  85. node.UnloadingAsync.On(_ =>
  86. {
  87. _closedMap.Remove(key);
  88. DestroyNode(node);
  89. });
  90. }
  91. return;
  92. }
  93. if (node.State == Loadable.LoadState.Unloaded)
  94. { // 已经卸载完成
  95. if (isDestroy)
  96. {
  97. _closedMap.Remove(key);
  98. DestroyNode(node);
  99. }
  100. return;
  101. }
  102. }
  103. else if (_openedMap.TryGetValue(key, out node))
  104. {
  105. _openedMap.Remove(key);
  106. node.Disable();
  107. _closedMap.Add(key, node);
  108. }
  109. else
  110. { // 没有数据
  111. return;
  112. }
  113. var unloadAsync = node.UnloadAsync();
  114. unloadAsync.On(_ =>
  115. {
  116. if (isDestroy)
  117. {
  118. _closedMap.Remove(key);
  119. DestroyNode(node);
  120. }
  121. });
  122. }
  123. IAsync INodeGroup.Preload(NodeKey nodeKey)
  124. {
  125. var key = nodeKey.Key;
  126. if (_openedMap.ContainsKey(key) || _closedMap.ContainsKey(key))
  127. {
  128. return null;
  129. }
  130. var node = Activator.CreateInstance(nodeKey.NodeType) as Node;
  131. node.Init(_context);
  132. _closedMap.Add(key, node);
  133. return node.LoadAsync();
  134. }
  135. void IUpdate.Update(int millisecond)
  136. {
  137. if (_openedMap.Count == 0)
  138. return;
  139. _updateNodes.Clear();
  140. _updateNodes.AddRange(_openedMap.Values);
  141. for (var i = 0; i < _updateNodes.Count;)
  142. {
  143. var node = _updateNodes[i];
  144. node.Update(millisecond);
  145. if (node.Active)
  146. {
  147. i++;
  148. }
  149. else
  150. {
  151. _updateNodes.RemoveAt(i);
  152. }
  153. }
  154. }
  155. void ILateUpdate.LateUpdate(int millisecond)
  156. {
  157. if (_updateNodes.Count == 0)
  158. return;
  159. foreach (var node in _updateNodes)
  160. {
  161. node.LateUpdate(millisecond);
  162. }
  163. _updateNodes.Clear();
  164. }
  165. void IDisposable.Dispose()
  166. {
  167. foreach (var node in _openedMap.Values)
  168. {
  169. DestroyNode(node);
  170. }
  171. _openedMap.Clear();
  172. foreach (var node in _closedMap.Values)
  173. {
  174. DestroyNode(node);
  175. }
  176. _closedMap.Clear();
  177. _updateNodes.Clear();
  178. (_context as IDisposable)?.Dispose();
  179. _context = null;
  180. }
  181. #endregion
  182. public IAsync RemoveAll(bool isDestroy)
  183. {
  184. var asyncGroup = new AsyncGroup();
  185. var copyMap = new Dictionary<string, Node>(_openedMap);
  186. foreach(var item in copyMap)
  187. {
  188. var key = item.Key;
  189. var node = item.Value;
  190. _openedMap.Remove(key);
  191. node.Disable();
  192. if (!isDestroy)
  193. {
  194. _closedMap.Add(key, node);
  195. }
  196. var unloadAsync = node.UnloadAsync();
  197. unloadAsync.Join(asyncGroup);
  198. unloadAsync.On(_ =>
  199. {
  200. if (isDestroy)
  201. {
  202. DestroyNode(node);
  203. }
  204. });
  205. }
  206. copyMap.Clear();
  207. if (isDestroy)
  208. {
  209. foreach (var item in _closedMap)
  210. {
  211. var key = item.Key;
  212. var node = item.Value;
  213. if (node.State == Loadable.LoadState.Unloading)
  214. {
  215. var unloadingAsync = node.UnloadingAsync;
  216. unloadingAsync.Join(asyncGroup);
  217. // 保证能执行destroy
  218. unloadingAsync.On(_ =>
  219. {
  220. DestroyNode(node);
  221. });
  222. continue;
  223. }
  224. if (node.State == Loadable.LoadState.Unloaded)
  225. { // 已经卸载完成
  226. DestroyNode(node);
  227. continue;
  228. }
  229. var unloadAsync = node.UnloadAsync();
  230. unloadAsync.Join(asyncGroup);
  231. unloadAsync.On(_ =>
  232. {
  233. DestroyNode(node);
  234. });
  235. }
  236. _closedMap.Clear();
  237. }
  238. asyncGroup.End();
  239. return asyncGroup;
  240. }
  241. #region 内部函数
  242. private void ShowNode(string key, Node node, object intent)
  243. {
  244. if (_openedMap.ContainsKey(key))
  245. {
  246. Log.Debug($"重复激活Node. Key:{key}");
  247. return;
  248. }
  249. _closedMap.Remove(key);
  250. _openedMap.Add(key, node);
  251. node.Enable(intent);
  252. }
  253. private void DestroyNode(Node node)
  254. {
  255. (node as IDisposable)?.Dispose();
  256. }
  257. #endregion
  258. }
  259. }