EventSystem.cs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Reflection;
  5. using Fort23.UTool;
  6. using UnityEngine.Profiling;
  7. using Utility;
  8. namespace Fort23.Core
  9. {
  10. using OneTypeSystems = UnOrderMultiMap<Type, object>;
  11. public sealed class EventSystem : IDisposable
  12. {
  13. private static EventSystem instance;
  14. public static EventSystem Instance
  15. {
  16. get
  17. {
  18. if (instance == null)
  19. {
  20. instance = new EventSystem();
  21. }
  22. return instance;
  23. }
  24. }
  25. // private readonly Dictionary<long, TypeData> _allEntities = new Dictionary<long, TypeData>();
  26. private readonly Dictionary<string, Assembly> _assemblies = new Dictionary<string, Assembly>();
  27. private readonly UnOrderMultiMapSet<Type, Type> _mapSet = new UnOrderMultiMapSet<Type, Type>();
  28. private Queue<Entity> _updates = new Queue<Entity>();
  29. private Queue<Entity> _updates2 = new Queue<Entity>();
  30. private Queue<Entity> _lateUpdates = new Queue<Entity>();
  31. private Queue<Entity> _lateUpdates2 = new Queue<Entity>();
  32. private readonly Map<Entity, Map<CustomMethodType, List<MethodInfo>>> currEntity =
  33. new Map<Entity, Map<CustomMethodType, List<MethodInfo>>>();
  34. private readonly Map<Type, Map<CustomMethodType, List<MethodInfo>>> allEntityMethodName =
  35. new Map<Type, Map<CustomMethodType, List<MethodInfo>>>();
  36. private EventSystem()
  37. {
  38. // TODO 手动添加所包含的程序集
  39. string[] assemblyNames =
  40. {
  41. "Fort23.Core.dll","Fort23.Mono.dll",
  42. "Fort23.GameData.dll"
  43. };
  44. foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
  45. {
  46. string assemblyName = $"{assembly.GetName().Name}.dll";
  47. if (!((IList)assemblyNames).Contains(assemblyName))
  48. {
  49. continue;
  50. }
  51. Add(assembly);
  52. }
  53. }
  54. public Assembly GetAssembly(string key)
  55. {
  56. if (_assemblies.ContainsKey(key))
  57. {
  58. return _assemblies[key];
  59. }
  60. return null;
  61. }
  62. public void Add(Assembly assembly)
  63. {
  64. this._assemblies[$"{assembly.GetName().Name}.dll"] = assembly;
  65. }
  66. public HashSet<Type> GetTypes(Type systemAttributeType)
  67. {
  68. if (!this._mapSet.ContainsKey(systemAttributeType))
  69. {
  70. return new HashSet<Type>();
  71. }
  72. return this._mapSet[systemAttributeType];
  73. }
  74. public List<Type> GetTypes()
  75. {
  76. List<Type> allTypes = new List<Type>();
  77. foreach (Assembly assembly in this._assemblies.Values)
  78. {
  79. allTypes.AddRange(assembly.GetTypes());
  80. }
  81. return allTypes;
  82. }
  83. public Map<CustomMethodType, List<MethodInfo>> GetCustomMethod(Entity component)
  84. {
  85. Type type = component.GetType();
  86. Map<CustomMethodType, List<MethodInfo>> methodName = null;
  87. if (allEntityMethodName.TryGetValue(type, out methodName))
  88. {
  89. return methodName;
  90. }
  91. methodName = new Map<CustomMethodType, List<MethodInfo>>();
  92. var methodInfos = type.GetMethods();
  93. for (int i = 0; i < methodInfos.Length; i++)
  94. {
  95. CustomMethod customMethod = methodInfos[i].GetCustomAttribute<CustomMethod>();
  96. if (customMethod != null)
  97. {
  98. if (!methodName.TryGetValue(customMethod.CustomMethodType,
  99. out List<MethodInfo> allEntityMethodName))
  100. {
  101. allEntityMethodName = new List<MethodInfo>();
  102. methodName.Add(customMethod.CustomMethodType, allEntityMethodName);
  103. }
  104. allEntityMethodName.Add(methodInfos[i]);
  105. }
  106. }
  107. allEntityMethodName.Add(type, methodName);
  108. return methodName;
  109. }
  110. public void RegisterSystem(Entity component, bool isRegister = true)
  111. {
  112. if (!isRegister)
  113. {
  114. this.Remove(component);
  115. return;
  116. }
  117. if (currEntity.ContainsKey(component))
  118. {
  119. return;
  120. // LogTool.Error("纯在相同的key" + component.InstanceID + "____" + component.GetType());
  121. }
  122. Map<CustomMethodType, List<MethodInfo>> allName = GetCustomMethod(component);
  123. currEntity.Add(component, allName);
  124. for (allName.Begin(); allName.Next();)
  125. {
  126. if (allName.Key == CustomMethodType.Update)
  127. {
  128. _updates.Enqueue(component);
  129. }
  130. if (allName.Key == CustomMethodType.LateUpdate)
  131. {
  132. _lateUpdates.Enqueue(component);
  133. }
  134. }
  135. }
  136. public void Remove(Entity instanceId)
  137. {
  138. this.currEntity.Remove(instanceId);
  139. }
  140. public Map<CustomMethodType, List<MethodInfo>> Get(Entity instanceId)
  141. {
  142. Map<CustomMethodType, List<MethodInfo>> component = null;
  143. this.currEntity.TryGetValue(instanceId, out component);
  144. return component;
  145. }
  146. public bool IsRegister(Entity instanceId)
  147. {
  148. return this.currEntity.ContainsKey(instanceId);
  149. }
  150. public void Awake(Entity component, object[] data)
  151. {
  152. try
  153. {
  154. Dispatch(component, CustomMethodType.Awake, data);
  155. }
  156. catch (Exception e)
  157. {
  158. LogTool.Exception(e);
  159. }
  160. }
  161. public void Dispatch(Entity component, CustomMethodType customMethodType, object[] data)
  162. {
  163. Map<CustomMethodType, List<MethodInfo>> typeData = Get(component);
  164. if (typeData == null)
  165. {
  166. return;
  167. }
  168. if (typeData.TryGetValue(customMethodType, out List<MethodInfo> w))
  169. {
  170. for (int i = 0; i < w.Count; i++)
  171. {
  172. w[i].Invoke(component, data);
  173. }
  174. }
  175. }
  176. public void Destroy(Entity component)
  177. {
  178. try
  179. {
  180. Dispatch(component, CustomMethodType.Destroy, null);
  181. }
  182. catch (Exception e)
  183. {
  184. LogTool.Exception(e);
  185. }
  186. }
  187. public void Update()
  188. {
  189. while (this._updates.Count > 0)
  190. {
  191. Entity instanceId = this._updates.Dequeue();
  192. if (instanceId.IsDisposed)
  193. {
  194. continue;
  195. }
  196. this._updates2.Enqueue(instanceId);
  197. try
  198. {
  199. if (instanceId.IsUpdate())
  200. {
  201. Dispatch(instanceId, CustomMethodType.Update, null);
  202. }
  203. }
  204. catch (Exception e)
  205. {
  206. LogTool.Error(e);
  207. // throw new Exception(e.Message);
  208. }
  209. }
  210. ObjectHelper.Swap(ref this._updates, ref this._updates2);
  211. }
  212. public void LateUpdate()
  213. {
  214. while (this._lateUpdates.Count > 0)
  215. {
  216. Entity instanceId = this._lateUpdates.Dequeue();
  217. if (instanceId.IsDisposed)
  218. {
  219. continue;
  220. }
  221. this._lateUpdates2.Enqueue(instanceId);
  222. try
  223. {
  224. if (instanceId.IsUpdate())
  225. {
  226. Dispatch(instanceId, CustomMethodType.LateUpdate, null);
  227. }
  228. }
  229. catch (Exception e)
  230. {
  231. LogTool.Exception(e);
  232. }
  233. }
  234. ObjectHelper.Swap(ref this._lateUpdates, ref this._lateUpdates2);
  235. }
  236. public void Dispose()
  237. {
  238. instance = null;
  239. }
  240. }
  241. }