EventSystem.cs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. using System;
  2. using System.Collections.Generic;
  3. using Model;
  4. namespace Hotfix
  5. {
  6. public interface IObjectSystem
  7. {
  8. Type Type();
  9. void Set(object value);
  10. }
  11. public abstract class ObjectSystem<T> : IObjectSystem
  12. {
  13. private T value;
  14. protected T Get()
  15. {
  16. return value;
  17. }
  18. public void Set(object v)
  19. {
  20. this.value = (T)v;
  21. }
  22. public Type Type()
  23. {
  24. return typeof(T);
  25. }
  26. }
  27. public sealed class EventSystem
  28. {
  29. private readonly Dictionary<Type, IObjectSystem> disposerEvents = new Dictionary<Type, IObjectSystem>();
  30. private readonly Dictionary<EventIdType, List<object>> allEvents = new Dictionary<EventIdType, List<object>>();
  31. private Queue<Disposer> updates = new Queue<Disposer>();
  32. private Queue<Disposer> updates2 = new Queue<Disposer>();
  33. private readonly Queue<Disposer> starts = new Queue<Disposer>();
  34. private Queue<Disposer> loaders = new Queue<Disposer>();
  35. private Queue<Disposer> loaders2 = new Queue<Disposer>();
  36. private Queue<Disposer> lateUpdates = new Queue<Disposer>();
  37. private Queue<Disposer> lateUpdates2 = new Queue<Disposer>();
  38. private readonly HashSet<Disposer> unique = new HashSet<Disposer>();
  39. public EventSystem()
  40. {
  41. this.disposerEvents.Clear();
  42. Type[] types = DllHelper.GetHotfixTypes();
  43. foreach (Type type in types)
  44. {
  45. object[] attrs = type.GetCustomAttributes(typeof(ObjectSystemAttribute), false);
  46. if (attrs.Length == 0)
  47. {
  48. continue;
  49. }
  50. object obj = Activator.CreateInstance(type);
  51. IObjectSystem objectSystem = obj as IObjectSystem;
  52. if (objectSystem == null)
  53. {
  54. Log.Error($"组件事件没有继承IObjectEvent: {type.Name}");
  55. continue;
  56. }
  57. this.disposerEvents[objectSystem.Type()] = objectSystem;
  58. }
  59. allEvents.Clear();
  60. foreach (Type type in types)
  61. {
  62. object[] attrs = type.GetCustomAttributes(typeof(EventAttribute), false);
  63. foreach (object attr in attrs)
  64. {
  65. EventAttribute aEventAttribute = (EventAttribute)attr;
  66. object obj = Activator.CreateInstance(type);
  67. if (!this.allEvents.ContainsKey((EventIdType)aEventAttribute.Type))
  68. {
  69. this.allEvents.Add((EventIdType)aEventAttribute.Type, new List<object>());
  70. }
  71. this.allEvents[(EventIdType)aEventAttribute.Type].Add(obj);
  72. }
  73. }
  74. this.Load();
  75. }
  76. public void Add(Disposer disposer)
  77. {
  78. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out IObjectSystem objectSystem))
  79. {
  80. return;
  81. }
  82. if (objectSystem is ILoad)
  83. {
  84. this.loaders.Enqueue(disposer);
  85. }
  86. if (objectSystem is IUpdate)
  87. {
  88. this.updates.Enqueue(disposer);
  89. }
  90. if (objectSystem is IStart)
  91. {
  92. this.starts.Enqueue(disposer);
  93. }
  94. if (objectSystem is ILateUpdate)
  95. {
  96. this.lateUpdates.Enqueue(disposer);
  97. }
  98. }
  99. public void Awake(Disposer disposer)
  100. {
  101. this.Add(disposer);
  102. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out IObjectSystem objectEvent))
  103. {
  104. return;
  105. }
  106. IAwake iAwake = objectEvent as IAwake;
  107. if (iAwake == null)
  108. {
  109. return;
  110. }
  111. objectEvent.Set(disposer);
  112. iAwake.Awake();
  113. }
  114. public void Awake<P1>(Disposer disposer, P1 p1)
  115. {
  116. this.Add(disposer);
  117. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out IObjectSystem objectEvent))
  118. {
  119. throw new Exception($"{disposer.GetType().Name} not found awake1");
  120. }
  121. IAwake<P1> iAwake = objectEvent as IAwake<P1>;
  122. if (iAwake == null)
  123. {
  124. throw new Exception($"{disposer.GetType().Name} not found awake1");
  125. }
  126. objectEvent.Set(disposer);
  127. iAwake.Awake(p1);
  128. }
  129. public void Awake<P1, P2>(Disposer disposer, P1 p1, P2 p2)
  130. {
  131. this.Add(disposer);
  132. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out IObjectSystem objectEvent))
  133. {
  134. throw new Exception($"{disposer.GetType().Name} not found awake2");
  135. }
  136. IAwake<P1, P2> iAwake = objectEvent as IAwake<P1, P2>;
  137. if (iAwake == null)
  138. {
  139. throw new Exception($"{disposer.GetType().Name} not found awake2");
  140. }
  141. objectEvent.Set(disposer);
  142. iAwake.Awake(p1, p2);
  143. }
  144. public void Awake<P1, P2, P3>(Disposer disposer, P1 p1, P2 p2, P3 p3)
  145. {
  146. this.Add(disposer);
  147. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out IObjectSystem objectEvent))
  148. {
  149. throw new Exception($"{disposer.GetType().Name} not found awake3");
  150. }
  151. IAwake<P1, P2, P3> iAwake = objectEvent as IAwake<P1, P2, P3>;
  152. if (iAwake == null)
  153. {
  154. throw new Exception($"{disposer.GetType().Name} not found awake3");
  155. }
  156. objectEvent.Set(disposer);
  157. iAwake.Awake(p1, p2, p3);
  158. }
  159. public void Load()
  160. {
  161. unique.Clear();
  162. while (this.loaders.Count > 0)
  163. {
  164. Disposer disposer = this.loaders.Dequeue();
  165. if (disposer.Id == 0)
  166. {
  167. continue;
  168. }
  169. if (!this.unique.Add(disposer))
  170. {
  171. continue;
  172. }
  173. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out IObjectSystem objectEvent))
  174. {
  175. continue;
  176. }
  177. this.loaders2.Enqueue(disposer);
  178. ILoad iLoad = objectEvent as ILoad;
  179. if (iLoad == null)
  180. {
  181. continue;
  182. }
  183. objectEvent.Set(disposer);
  184. try
  185. {
  186. iLoad.Load();
  187. }
  188. catch (Exception e)
  189. {
  190. Log.Error(e.ToString());
  191. }
  192. }
  193. ObjectHelper.Swap(ref this.loaders, ref this.loaders2);
  194. }
  195. private void Start()
  196. {
  197. unique.Clear();
  198. while (this.starts.Count > 0)
  199. {
  200. Disposer disposer = this.starts.Dequeue();
  201. if (!this.unique.Add(disposer))
  202. {
  203. continue;
  204. }
  205. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out IObjectSystem objectEvent))
  206. {
  207. continue;
  208. }
  209. IStart iStart = objectEvent as IStart;
  210. if (iStart == null)
  211. {
  212. continue;
  213. }
  214. objectEvent.Set(disposer);
  215. iStart.Start();
  216. }
  217. }
  218. public void Update()
  219. {
  220. this.Start();
  221. unique.Clear();
  222. while (this.updates.Count > 0)
  223. {
  224. Disposer disposer = this.updates.Dequeue();
  225. if (disposer.Id == 0)
  226. {
  227. continue;
  228. }
  229. if (!this.unique.Add(disposer))
  230. {
  231. continue;
  232. }
  233. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out IObjectSystem objectEvent))
  234. {
  235. continue;
  236. }
  237. this.updates2.Enqueue(disposer);
  238. IUpdate iUpdate = objectEvent as IUpdate;
  239. if (iUpdate == null)
  240. {
  241. continue;
  242. }
  243. objectEvent.Set(disposer);
  244. try
  245. {
  246. iUpdate.Update();
  247. }
  248. catch (Exception e)
  249. {
  250. Log.Error(e.ToString());
  251. }
  252. }
  253. ObjectHelper.Swap(ref this.updates, ref this.updates2);
  254. }
  255. public void LateUpdate()
  256. {
  257. unique.Clear();
  258. while (this.lateUpdates.Count > 0)
  259. {
  260. Disposer disposer = this.lateUpdates.Dequeue();
  261. if (disposer.Id == 0)
  262. {
  263. continue;
  264. }
  265. if (!this.unique.Add(disposer))
  266. {
  267. continue;
  268. }
  269. IObjectSystem objectSystem;
  270. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out objectSystem))
  271. {
  272. continue;
  273. }
  274. this.lateUpdates2.Enqueue(disposer);
  275. ILateUpdate iLateUpdate = objectSystem as ILateUpdate;
  276. if (iLateUpdate == null)
  277. {
  278. continue;
  279. }
  280. objectSystem.Set(disposer);
  281. try
  282. {
  283. iLateUpdate.LateUpdate();
  284. }
  285. catch (Exception e)
  286. {
  287. Log.Error(e.ToString());
  288. }
  289. }
  290. ObjectHelper.Swap(ref this.lateUpdates, ref this.lateUpdates2);
  291. }
  292. public void Run(EventIdType type)
  293. {
  294. List<object> iEvents;
  295. if (!this.allEvents.TryGetValue(type, out iEvents))
  296. {
  297. return;
  298. }
  299. foreach (object obj in iEvents)
  300. {
  301. try
  302. {
  303. IEvent iEvent = (IEvent)obj;
  304. iEvent.Run();
  305. }
  306. catch (Exception e)
  307. {
  308. Log.Error(e.ToString());
  309. }
  310. }
  311. }
  312. public void Run<A>(EventIdType type, A a)
  313. {
  314. List<object> iEvents;
  315. if (!this.allEvents.TryGetValue(type, out iEvents))
  316. {
  317. return;
  318. }
  319. foreach (object obj in iEvents)
  320. {
  321. try
  322. {
  323. IEvent<A> iEvent = (IEvent<A>)obj;
  324. iEvent.Run(a);
  325. }
  326. catch (Exception err)
  327. {
  328. Log.Error(err.ToString());
  329. }
  330. }
  331. }
  332. public void Run<A, B>(EventIdType type, A a, B b)
  333. {
  334. List<object> iEvents;
  335. if (!this.allEvents.TryGetValue(type, out iEvents))
  336. {
  337. return;
  338. }
  339. foreach (object obj in iEvents)
  340. {
  341. try
  342. {
  343. IEvent<A, B> iEvent = (IEvent<A, B>)obj;
  344. iEvent.Run(a, b);
  345. }
  346. catch (Exception err)
  347. {
  348. Log.Error(err.ToString());
  349. }
  350. }
  351. }
  352. public void Run<A, B, C>(EventIdType type, A a, B b, C c)
  353. {
  354. List<object> iEvents;
  355. if (!this.allEvents.TryGetValue(type, out iEvents))
  356. {
  357. return;
  358. }
  359. foreach (object obj in iEvents)
  360. {
  361. try
  362. {
  363. IEvent<A, B, C> iEvent = (IEvent<A, B, C>)obj;
  364. iEvent.Run(a, b, c);
  365. }
  366. catch (Exception err)
  367. {
  368. Log.Error(err.ToString());
  369. }
  370. }
  371. }
  372. }
  373. }