EntityEventManager.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Text;
  6. using Base;
  7. namespace Model
  8. {
  9. [Flags]
  10. public enum EntityEventType
  11. {
  12. Awake = 1,
  13. Awake1 = 2,
  14. Awake2 = 4,
  15. Awake3 = 8,
  16. Update = 16,
  17. Load = 32,
  18. LateUpdate = 64
  19. }
  20. public class EntityTypeInfo
  21. {
  22. private readonly Dictionary<EntityEventType, MethodInfo> infos = new Dictionary<EntityEventType, MethodInfo>();
  23. public void Add(EntityEventType type, MethodInfo methodInfo)
  24. {
  25. try
  26. {
  27. this.infos.Add(type, methodInfo);
  28. }
  29. catch (Exception e)
  30. {
  31. throw new Exception($"Add EntityEventType MethodInfo Error: {type}", e);
  32. }
  33. }
  34. public MethodInfo Get(EntityEventType type)
  35. {
  36. MethodInfo methodInfo;
  37. this.infos.TryGetValue(type, out methodInfo);
  38. return methodInfo;
  39. }
  40. public EntityEventType[] GetEntityEventTypes()
  41. {
  42. return this.infos.Keys.ToArray();
  43. }
  44. public override string ToString()
  45. {
  46. StringBuilder sb = new StringBuilder();
  47. foreach (EntityEventType disposerEventType in this.infos.Keys.ToArray())
  48. {
  49. sb.Append($"{disposerEventType} {this.infos[disposerEventType].Name} ");
  50. }
  51. return sb.ToString();
  52. }
  53. }
  54. public sealed class EntityEventManager
  55. {
  56. private readonly Dictionary<string, Assembly> assemblies = new Dictionary<string, Assembly>();
  57. private readonly Dictionary<EntityEventType, HashSet<Disposer>> disposers = new Dictionary<EntityEventType, HashSet<Disposer>>();
  58. private readonly HashSet<Disposer> addDisposers = new HashSet<Disposer>();
  59. private readonly HashSet<Disposer> removeDisposers = new HashSet<Disposer>();
  60. private Dictionary<Type, EntityTypeInfo> eventInfo;
  61. public EntityEventManager()
  62. {
  63. foreach (EntityEventType t in Enum.GetValues(typeof (EntityEventType)))
  64. {
  65. this.disposers.Add(t, new HashSet<Disposer>());
  66. }
  67. }
  68. public void Register(string name, Assembly assembly)
  69. {
  70. this.eventInfo = new Dictionary<Type, EntityTypeInfo>();
  71. this.assemblies[name] = assembly;
  72. foreach (Assembly ass in this.assemblies.Values)
  73. {
  74. Type[] types = ass.GetTypes();
  75. foreach (Type type in types)
  76. {
  77. object[] attrs = type.GetCustomAttributes(typeof (EntityEventAttribute), true);
  78. if (attrs.Length == 0)
  79. {
  80. continue;
  81. }
  82. EntityEventAttribute entityEventAttribute = attrs[0] as EntityEventAttribute;
  83. Type type2 = entityEventAttribute.ClassType;
  84. if (!this.eventInfo.ContainsKey(type2))
  85. {
  86. this.eventInfo.Add(type2, new EntityTypeInfo());
  87. }
  88. foreach (
  89. MethodInfo methodInfo in
  90. type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Public |
  91. BindingFlags.DeclaredOnly))
  92. {
  93. int n = methodInfo.GetParameters().Length;
  94. if (methodInfo.IsStatic)
  95. {
  96. --n;
  97. }
  98. string sn = n > 0? $"{methodInfo.Name}{n}" : methodInfo.Name;
  99. foreach (string s in Enum.GetNames(typeof (EntityEventType)))
  100. {
  101. if (s != sn)
  102. {
  103. continue;
  104. }
  105. EntityEventType t = EnumHelper.FromString<EntityEventType>(s);
  106. this.eventInfo[type2].Add(t, methodInfo);
  107. break;
  108. }
  109. }
  110. }
  111. }
  112. this.Load();
  113. }
  114. public void Add(Disposer disposer)
  115. {
  116. this.addDisposers.Add(disposer);
  117. }
  118. public void Remove(Disposer disposer)
  119. {
  120. this.removeDisposers.Add(disposer);
  121. }
  122. private void UpdateAddDisposer()
  123. {
  124. foreach (Disposer disposer in this.addDisposers)
  125. {
  126. EntityTypeInfo entityTypeInfo;
  127. if (!this.eventInfo.TryGetValue(disposer.GetType(), out entityTypeInfo))
  128. {
  129. continue;
  130. }
  131. foreach (EntityEventType disposerEvent2Type in entityTypeInfo.GetEntityEventTypes())
  132. {
  133. this.disposers[disposerEvent2Type].Add(disposer);
  134. }
  135. }
  136. this.addDisposers.Clear();
  137. }
  138. private void UpdateRemoveDisposer()
  139. {
  140. foreach (Disposer disposer in this.removeDisposers)
  141. {
  142. EntityTypeInfo entityTypeInfo;
  143. if (!this.eventInfo.TryGetValue(disposer.GetType(), out entityTypeInfo))
  144. {
  145. continue;
  146. }
  147. foreach (EntityEventType disposerEvent2Type in entityTypeInfo.GetEntityEventTypes())
  148. {
  149. this.disposers[disposerEvent2Type].Remove(disposer);
  150. }
  151. }
  152. this.removeDisposers.Clear();
  153. }
  154. public Assembly GetAssembly(string name)
  155. {
  156. return this.assemblies[name];
  157. }
  158. public Assembly[] GetAssemblies()
  159. {
  160. return this.assemblies.Values.ToArray();
  161. }
  162. private void Load()
  163. {
  164. HashSet<Disposer> list;
  165. if (!this.disposers.TryGetValue(EntityEventType.Load, out list))
  166. {
  167. return;
  168. }
  169. foreach (Disposer disposer in list)
  170. {
  171. EntityTypeInfo entityTypeInfo = this.eventInfo[disposer.GetType()];
  172. entityTypeInfo.Get(EntityEventType.Load).Run(disposer);
  173. }
  174. }
  175. public void Awake(Disposer disposer)
  176. {
  177. EntityTypeInfo entityTypeInfo;
  178. if (!this.eventInfo.TryGetValue(disposer.GetType(), out entityTypeInfo))
  179. {
  180. return;
  181. }
  182. entityTypeInfo.Get(EntityEventType.Awake)?.Run(disposer);
  183. }
  184. public void Awake(Disposer disposer, object p1)
  185. {
  186. EntityTypeInfo entityTypeInfo;
  187. if (!this.eventInfo.TryGetValue(disposer.GetType(), out entityTypeInfo))
  188. {
  189. return;
  190. }
  191. entityTypeInfo.Get(EntityEventType.Awake1)?.Run(disposer, p1);
  192. }
  193. public void Awake(Disposer disposer, object p1, object p2)
  194. {
  195. EntityTypeInfo entityTypeInfo;
  196. if (!this.eventInfo.TryGetValue(disposer.GetType(), out entityTypeInfo))
  197. {
  198. return;
  199. }
  200. entityTypeInfo.Get(EntityEventType.Awake2)?.Run(disposer, p1, p2);
  201. }
  202. public void Awake(Disposer disposer, object p1, object p2, object p3)
  203. {
  204. EntityTypeInfo entityTypeInfo;
  205. if (!this.eventInfo.TryGetValue(disposer.GetType(), out entityTypeInfo))
  206. {
  207. return;
  208. }
  209. entityTypeInfo.Get(EntityEventType.Awake3)?.Run(disposer, p1, p2, p3);
  210. }
  211. public void Update()
  212. {
  213. UpdateAddDisposer();
  214. UpdateRemoveDisposer();
  215. HashSet<Disposer> list;
  216. if (!this.disposers.TryGetValue(EntityEventType.Update, out list))
  217. {
  218. return;
  219. }
  220. foreach (Disposer disposer in list)
  221. {
  222. try
  223. {
  224. if (this.removeDisposers.Contains(disposer))
  225. {
  226. continue;
  227. }
  228. EntityTypeInfo entityTypeInfo = this.eventInfo[disposer.GetType()];
  229. entityTypeInfo.Get(EntityEventType.Update).Run(disposer);
  230. }
  231. catch (Exception e)
  232. {
  233. Log.Error(e.ToString());
  234. }
  235. }
  236. }
  237. public void LateUpdate()
  238. {
  239. HashSet<Disposer> list;
  240. if (!this.disposers.TryGetValue(EntityEventType.LateUpdate, out list))
  241. {
  242. return;
  243. }
  244. foreach (Disposer disposer in list)
  245. {
  246. try
  247. {
  248. EntityTypeInfo entityTypeInfo = this.eventInfo[disposer.GetType()];
  249. entityTypeInfo.Get(EntityEventType.LateUpdate).Run(disposer);
  250. }
  251. catch (Exception e)
  252. {
  253. Log.Error(e.ToString());
  254. }
  255. }
  256. }
  257. public string MethodInfo()
  258. {
  259. StringBuilder sb = new StringBuilder();
  260. foreach (Type type in this.eventInfo.Keys.ToArray())
  261. {
  262. sb.Append($"{type.Name} {this.eventInfo[type]}\n");
  263. }
  264. return sb.ToString();
  265. }
  266. }
  267. }