MapModule.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using XGame.Framework.Asset;
  5. using XGame.Framework.Asyncs;
  6. using XGame.Framework.Interfaces;
  7. namespace XGame.Framework.Map
  8. {
  9. public class MapModule : IMapModule, IUpdate, ILateUpdate, IMapContextSetter, IDisposable
  10. {
  11. private MapContext _context;
  12. private Transform _mapRoot;
  13. private IAssetModule _assetModule;
  14. /// <summary>
  15. /// 加载中的
  16. /// </summary>
  17. private Dictionary<string, IAsync> _loadingMap;
  18. /// <summary>
  19. /// 已打开的
  20. /// </summary>
  21. private Dictionary<string, IMapView> _openedMap;
  22. /// <summary>
  23. /// 已关闭的
  24. /// </summary>
  25. private Dictionary<string, IMapView> _closedMap;
  26. /// <summary>
  27. /// pdate 和 LateUpdate用
  28. /// </summary>
  29. private List<IMapView> _updates;
  30. public MapModule(IAssetModule assetModule, Transform root)
  31. {
  32. _assetModule = assetModule;
  33. _mapRoot = root;
  34. _loadingMap = new Dictionary<string, IAsync>();
  35. _openedMap = new Dictionary<string, IMapView>();
  36. _closedMap = new Dictionary<string, IMapView>();
  37. _updates = new List<IMapView>();
  38. }
  39. #region 接口实现
  40. public MapContext Context { get => _context; set => _context = value; }
  41. IAsync IMapModule.RunAsync(MapKey mapKey, object intent)
  42. {
  43. string key = mapKey;
  44. if (_loadingMap.ContainsKey(key))
  45. {
  46. return _loadingMap[key];
  47. }
  48. var asyncGroup = new AsyncGroup();
  49. if (_openedMap.ContainsKey(key))
  50. {
  51. Log.Warn($"重复打开地图:{key}");
  52. }
  53. else if (_closedMap.TryGetValue(key, out var closedView))
  54. { //已关闭的地图
  55. asyncGroup.On(_ =>
  56. {
  57. _closedMap.Remove(key);
  58. closedView.Behaviour.transform.SetAsLastSibling();
  59. closedView.Enable(intent);
  60. _openedMap.Add(key, closedView);
  61. });
  62. }
  63. else
  64. {
  65. _loadingMap.Add(key, asyncGroup);
  66. var loadAsync = _assetModule.LoadAsync<MapBehaviour>(key);
  67. loadAsync.Join(asyncGroup);
  68. loadAsync.On(_ =>
  69. {
  70. _loadingMap.Remove(key);
  71. var behaviour = loadAsync.GetResult();
  72. if (behaviour == null)
  73. {
  74. Log.Error($"地图加载结果为空. MapKey:{key}");
  75. return;
  76. }
  77. var view = Activator.CreateInstance(mapKey.MapViewType) as IMapView;
  78. (view as IMapContextSetter).Context = _context.Clone();
  79. view.Behaviour = behaviour;
  80. behaviour.transform.SetParent(_mapRoot, false);
  81. view.Enable(intent);
  82. _openedMap.Add(key, view);
  83. });
  84. }
  85. asyncGroup.End();
  86. return asyncGroup;
  87. }
  88. void IMapModule.Close(MapKey mapKey, bool isDestroy)
  89. {
  90. if (mapKey == null)
  91. return;
  92. var key = mapKey.Key;
  93. if (_loadingMap.TryGetValue(key, out var async))
  94. {
  95. _loadingMap.Remove(key);
  96. async.RemoveAll();
  97. return;
  98. }
  99. if (_openedMap.TryGetValue(key, out var mapView))
  100. {
  101. _openedMap.Remove(key);
  102. mapView.Disable();
  103. if (isDestroy)
  104. {
  105. DestroyView(mapView);
  106. }
  107. else
  108. {
  109. _closedMap.Add(key, mapView);
  110. }
  111. return;
  112. }
  113. if (isDestroy && _closedMap.TryGetValue(key, out mapView))
  114. {
  115. _closedMap.Remove(key);
  116. DestroyView(mapView);
  117. }
  118. }
  119. IAsync IMapModule.Preload(MapKey mapKey)
  120. {
  121. var loadAsync = _assetModule.PreloadAsync<MapBehaviour>(mapKey);
  122. return loadAsync;
  123. }
  124. void IUpdate.Update(int millisecond)
  125. {
  126. if (_openedMap.Count == 0)
  127. return;
  128. _updates.Clear();
  129. _updates.AddRange(_openedMap.Values);
  130. for (var i = 0; i < _updates.Count;)
  131. {
  132. var view = _updates[i];
  133. view.Update(millisecond);
  134. if (view.Active)
  135. {
  136. i++;
  137. }
  138. else
  139. {
  140. _updates.RemoveAt(i);
  141. }
  142. }
  143. }
  144. void ILateUpdate.LateUpdate(int millisecond)
  145. {
  146. if (_updates.Count == 0)
  147. return;
  148. foreach (var uiview in _updates)
  149. {
  150. uiview.LateUpdate(millisecond);
  151. }
  152. _updates.Clear();
  153. }
  154. void IDisposable.Dispose()
  155. {
  156. _updates.Clear();
  157. foreach (var async in _loadingMap.Values)
  158. {
  159. async.RemoveAll();
  160. }
  161. _loadingMap.Clear();
  162. foreach (var uiview in _closedMap.Values)
  163. {
  164. DestroyView(uiview);
  165. }
  166. _closedMap.Clear();
  167. foreach (var uiview in _openedMap.Values)
  168. {
  169. DestroyView(uiview);
  170. }
  171. _openedMap.Clear();
  172. GameObject.Destroy(_mapRoot.gameObject);
  173. (_assetModule as IDisposable)?.Dispose();
  174. _assetModule = null;
  175. _context = null;
  176. }
  177. #endregion
  178. private void DestroyView(IMapView view)
  179. {
  180. var behaviour = view.Behaviour;
  181. (view as IDisposable).Dispose();
  182. _assetModule.Recycle(behaviour.gameObject, true);
  183. }
  184. }
  185. }