EntityEventManager.cs 6.7 KB

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