EntityEventManager.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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. }
  19. public class EntityTypeInfo
  20. {
  21. private readonly Dictionary<EntityEventType, MethodInfo> infos = new Dictionary<EntityEventType, MethodInfo>();
  22. public void Add(EntityEventType type, MethodInfo methodInfo)
  23. {
  24. try
  25. {
  26. this.infos.Add(type, methodInfo);
  27. }
  28. catch (Exception e)
  29. {
  30. throw new Exception($"Add DisposerEventType MethodInfo Error: {type}", e);
  31. }
  32. }
  33. public MethodInfo Get(EntityEventType type)
  34. {
  35. MethodInfo methodInfo;
  36. this.infos.TryGetValue(type, out methodInfo);
  37. return methodInfo;
  38. }
  39. public EntityEventType[] GetDisposerEvent2Types()
  40. {
  41. return this.infos.Keys.ToArray();
  42. }
  43. public override string ToString()
  44. {
  45. StringBuilder sb = new StringBuilder();
  46. foreach (EntityEventType disposerEventType in this.infos.Keys.ToArray())
  47. {
  48. sb.Append($"{disposerEventType} {this.infos[disposerEventType].Name} ");
  49. }
  50. return sb.ToString();
  51. }
  52. }
  53. public sealed class EntityEventManager
  54. {
  55. private readonly Dictionary<string, Assembly> assemblies = new Dictionary<string, Assembly>();
  56. private readonly Dictionary<EntityEventType, HashSet<Disposer>> disposers = new Dictionary<EntityEventType, HashSet<Disposer>>();
  57. private Dictionary<Type, EntityTypeInfo> eventInfo;
  58. public EntityEventManager()
  59. {
  60. foreach (EntityEventType t in Enum.GetValues(typeof(EntityEventType)))
  61. {
  62. this.disposers.Add(t, new HashSet<Disposer>());
  63. }
  64. }
  65. public void Register(string name, Assembly assembly)
  66. {
  67. this.eventInfo = new Dictionary<Type, EntityTypeInfo>();
  68. this.assemblies[name] = assembly;
  69. foreach (Assembly ass in this.assemblies.Values)
  70. {
  71. Type[] types = ass.GetTypes();
  72. foreach (Type type in types)
  73. {
  74. object[] attrs = type.GetCustomAttributes(typeof(EntityEventAttribute), true);
  75. if (attrs.Length == 0)
  76. {
  77. continue;
  78. }
  79. EntityEventAttribute entityEventAttribute = attrs[0] as EntityEventAttribute;
  80. Type type2 = entityEventAttribute.ClassType;
  81. if (!this.eventInfo.ContainsKey(type2))
  82. {
  83. this.eventInfo.Add(type2, new EntityTypeInfo());
  84. }
  85. foreach (MethodInfo methodInfo in type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly))
  86. {
  87. int n = methodInfo.GetParameters().Length;
  88. if (methodInfo.IsStatic)
  89. {
  90. --n;
  91. }
  92. string sn = n > 0? $"{methodInfo.Name}{n}" : methodInfo.Name;
  93. foreach (string s in Enum.GetNames(typeof(EntityEventType)))
  94. {
  95. if (s != sn)
  96. {
  97. continue;
  98. }
  99. EntityEventType t = EnumHelper.FromString<EntityEventType>(s);
  100. this.eventInfo[type2].Add(t, methodInfo);
  101. break;
  102. }
  103. }
  104. }
  105. }
  106. this.Load();
  107. }
  108. public void Add(Disposer disposer)
  109. {
  110. EntityTypeInfo entityTypeInfo;
  111. if (!this.eventInfo.TryGetValue(disposer.GetType(), out entityTypeInfo))
  112. {
  113. return;
  114. }
  115. foreach (EntityEventType disposerEvent2Type in entityTypeInfo.GetDisposerEvent2Types())
  116. {
  117. this.disposers[disposerEvent2Type].Add(disposer);
  118. }
  119. }
  120. public void Remove(Disposer disposer)
  121. {
  122. EntityTypeInfo entityTypeInfo;
  123. if (!this.eventInfo.TryGetValue(disposer.GetType(), out entityTypeInfo))
  124. {
  125. return;
  126. }
  127. foreach (EntityEventType disposerEvent2Type in entityTypeInfo.GetDisposerEvent2Types())
  128. {
  129. this.disposers[disposerEvent2Type].Remove(disposer);
  130. }
  131. }
  132. public Assembly GetAssembly(string name)
  133. {
  134. return this.assemblies[name];
  135. }
  136. public Assembly[] GetAssemblies()
  137. {
  138. return this.assemblies.Values.ToArray();
  139. }
  140. private void Load()
  141. {
  142. HashSet<Disposer> list;
  143. if (!this.disposers.TryGetValue(EntityEventType.Update, out list))
  144. {
  145. return;
  146. }
  147. foreach (Disposer disposer in list)
  148. {
  149. EntityTypeInfo entityTypeInfo = this.eventInfo[disposer.GetType()];
  150. entityTypeInfo.Get(EntityEventType.Load).Run(disposer);
  151. }
  152. }
  153. public void Awake(Disposer disposer)
  154. {
  155. EntityTypeInfo entityTypeInfo = this.eventInfo[disposer.GetType()];
  156. entityTypeInfo.Get(EntityEventType.Awake)?.Run(disposer);
  157. }
  158. public void Awake(Disposer disposer, object p1)
  159. {
  160. EntityTypeInfo entityTypeInfo = this.eventInfo[disposer.GetType()];
  161. entityTypeInfo.Get(EntityEventType.Awake1)?.Run(disposer, p1);
  162. }
  163. public void Awake(Disposer disposer, object p1, object p2)
  164. {
  165. EntityTypeInfo entityTypeInfo = this.eventInfo[disposer.GetType()];
  166. entityTypeInfo.Get(EntityEventType.Awake2)?.Run(disposer, p1, p2 );
  167. }
  168. public void Awake(Disposer disposer, object p1, object p2, object p3)
  169. {
  170. EntityTypeInfo entityTypeInfo = this.eventInfo[disposer.GetType()];
  171. entityTypeInfo.Get(EntityEventType.Awake3)?.Run(disposer, p1, p2, p3 );
  172. }
  173. public void Update()
  174. {
  175. HashSet<Disposer> list;
  176. if (!this.disposers.TryGetValue(EntityEventType.Update, out list))
  177. {
  178. return;
  179. }
  180. foreach (Disposer disposer in list)
  181. {
  182. EntityTypeInfo entityTypeInfo = this.eventInfo[disposer.GetType()];
  183. entityTypeInfo.Get(EntityEventType.Update).Run(disposer);
  184. }
  185. }
  186. public string MethodInfo()
  187. {
  188. StringBuilder sb = new StringBuilder();
  189. foreach (Type type in this.eventInfo.Keys.ToArray())
  190. {
  191. sb.Append($"{type.Name} {this.eventInfo[type]}\n");
  192. }
  193. return sb.ToString();
  194. }
  195. }
  196. }