EventSystem.cs 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  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<int, List<IEvent>> allEvents = new Dictionary<int, List<IEvent>>();
  31. private Queue<Component> updates = new Queue<Component>();
  32. private Queue<Component> updates2 = new Queue<Component>();
  33. private readonly Queue<Component> starts = new Queue<Component>();
  34. private Queue<Component> loaders = new Queue<Component>();
  35. private Queue<Component> loaders2 = new Queue<Component>();
  36. private Queue<Component> lateUpdates = new Queue<Component>();
  37. private Queue<Component> lateUpdates2 = new Queue<Component>();
  38. private readonly HashSet<Component> unique = new HashSet<Component>();
  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. this.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. IEvent iEvent = obj as IEvent;
  68. if (iEvent == null)
  69. {
  70. Log.Error($"{obj.GetType().Name} 没有继承IEvent");
  71. }
  72. this.RegisterEvent(aEventAttribute.Type, iEvent);
  73. // hotfix的事件也要注册到mono层,hotfix可以订阅mono层的事件
  74. Action<List<object>> action = list => { Handle(aEventAttribute.Type, list); };
  75. Game.EventSystem.RegisterEvent(aEventAttribute.Type, new EventProxy(action));
  76. }
  77. }
  78. this.Load();
  79. }
  80. public void RegisterEvent(int eventId, IEvent e)
  81. {
  82. if (!this.allEvents.ContainsKey(eventId))
  83. {
  84. this.allEvents.Add(eventId, new List<IEvent>());
  85. }
  86. this.allEvents[eventId].Add(e);
  87. }
  88. public static void Handle(int type, List<object> param)
  89. {
  90. switch (param.Count)
  91. {
  92. case 0:
  93. Hotfix.EventSystem.Run(type);
  94. break;
  95. case 1:
  96. Hotfix.EventSystem.Run(type, param[0]);
  97. break;
  98. case 2:
  99. Hotfix.EventSystem.Run(type, param[0], param[1]);
  100. break;
  101. case 3:
  102. Hotfix.EventSystem.Run(type, param[0], param[1], param[2]);
  103. break;
  104. }
  105. }
  106. public void Add(Component disposer)
  107. {
  108. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out IObjectSystem objectSystem))
  109. {
  110. return;
  111. }
  112. if (objectSystem is ILoad)
  113. {
  114. this.loaders.Enqueue(disposer);
  115. }
  116. if (objectSystem is IUpdate)
  117. {
  118. this.updates.Enqueue(disposer);
  119. }
  120. if (objectSystem is IStart)
  121. {
  122. this.starts.Enqueue(disposer);
  123. }
  124. if (objectSystem is ILateUpdate)
  125. {
  126. this.lateUpdates.Enqueue(disposer);
  127. }
  128. }
  129. public void Awake(Component disposer)
  130. {
  131. this.Add(disposer);
  132. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out IObjectSystem objectEvent))
  133. {
  134. return;
  135. }
  136. IAwake iAwake = objectEvent as IAwake;
  137. if (iAwake == null)
  138. {
  139. return;
  140. }
  141. objectEvent.Set(disposer);
  142. iAwake.Awake();
  143. }
  144. public void Awake<P1>(Component disposer, P1 p1)
  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 awake1");
  150. }
  151. IAwake<P1> iAwake = objectEvent as IAwake<P1>;
  152. if (iAwake == null)
  153. {
  154. throw new Exception($"{disposer.GetType().Name} not found awake1");
  155. }
  156. objectEvent.Set(disposer);
  157. iAwake.Awake(p1);
  158. }
  159. public void Awake<P1, P2>(Component disposer, P1 p1, P2 p2)
  160. {
  161. this.Add(disposer);
  162. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out IObjectSystem objectEvent))
  163. {
  164. throw new Exception($"{disposer.GetType().Name} not found awake2");
  165. }
  166. IAwake<P1, P2> iAwake = objectEvent as IAwake<P1, P2>;
  167. if (iAwake == null)
  168. {
  169. throw new Exception($"{disposer.GetType().Name} not found awake2");
  170. }
  171. objectEvent.Set(disposer);
  172. iAwake.Awake(p1, p2);
  173. }
  174. public void Awake<P1, P2, P3>(Component disposer, P1 p1, P2 p2, P3 p3)
  175. {
  176. this.Add(disposer);
  177. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out IObjectSystem objectEvent))
  178. {
  179. throw new Exception($"{disposer.GetType().Name} not found awake3");
  180. }
  181. IAwake<P1, P2, P3> iAwake = objectEvent as IAwake<P1, P2, P3>;
  182. if (iAwake == null)
  183. {
  184. throw new Exception($"{disposer.GetType().Name} not found awake3");
  185. }
  186. objectEvent.Set(disposer);
  187. iAwake.Awake(p1, p2, p3);
  188. }
  189. public void Load()
  190. {
  191. unique.Clear();
  192. while (this.loaders.Count > 0)
  193. {
  194. Component disposer = this.loaders.Dequeue();
  195. if (disposer.IsDisposed)
  196. {
  197. continue;
  198. }
  199. if (!this.unique.Add(disposer))
  200. {
  201. continue;
  202. }
  203. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out IObjectSystem objectEvent))
  204. {
  205. continue;
  206. }
  207. this.loaders2.Enqueue(disposer);
  208. ILoad iLoad = objectEvent as ILoad;
  209. if (iLoad == null)
  210. {
  211. continue;
  212. }
  213. objectEvent.Set(disposer);
  214. try
  215. {
  216. iLoad.Load();
  217. }
  218. catch (Exception e)
  219. {
  220. Log.Error(e.ToString());
  221. }
  222. }
  223. ObjectHelper.Swap(ref this.loaders, ref this.loaders2);
  224. }
  225. private void Start()
  226. {
  227. unique.Clear();
  228. while (this.starts.Count > 0)
  229. {
  230. Component disposer = this.starts.Dequeue();
  231. if (!this.unique.Add(disposer))
  232. {
  233. continue;
  234. }
  235. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out IObjectSystem objectEvent))
  236. {
  237. continue;
  238. }
  239. IStart iStart = objectEvent as IStart;
  240. if (iStart == null)
  241. {
  242. continue;
  243. }
  244. objectEvent.Set(disposer);
  245. iStart.Start();
  246. }
  247. }
  248. public void Update()
  249. {
  250. this.Start();
  251. unique.Clear();
  252. while (this.updates.Count > 0)
  253. {
  254. Component disposer = this.updates.Dequeue();
  255. if (disposer.IsDisposed)
  256. {
  257. continue;
  258. }
  259. if (!this.unique.Add(disposer))
  260. {
  261. continue;
  262. }
  263. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out IObjectSystem objectEvent))
  264. {
  265. continue;
  266. }
  267. this.updates2.Enqueue(disposer);
  268. IUpdate iUpdate = objectEvent as IUpdate;
  269. if (iUpdate == null)
  270. {
  271. continue;
  272. }
  273. objectEvent.Set(disposer);
  274. try
  275. {
  276. iUpdate.Update();
  277. }
  278. catch (Exception e)
  279. {
  280. Log.Error(e.ToString());
  281. }
  282. }
  283. ObjectHelper.Swap(ref this.updates, ref this.updates2);
  284. }
  285. public void LateUpdate()
  286. {
  287. unique.Clear();
  288. while (this.lateUpdates.Count > 0)
  289. {
  290. Component disposer = this.lateUpdates.Dequeue();
  291. if (disposer.IsDisposed)
  292. {
  293. continue;
  294. }
  295. if (!this.unique.Add(disposer))
  296. {
  297. continue;
  298. }
  299. IObjectSystem objectSystem;
  300. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out objectSystem))
  301. {
  302. continue;
  303. }
  304. this.lateUpdates2.Enqueue(disposer);
  305. ILateUpdate iLateUpdate = objectSystem as ILateUpdate;
  306. if (iLateUpdate == null)
  307. {
  308. continue;
  309. }
  310. objectSystem.Set(disposer);
  311. try
  312. {
  313. iLateUpdate.LateUpdate();
  314. }
  315. catch (Exception e)
  316. {
  317. Log.Error(e.ToString());
  318. }
  319. }
  320. ObjectHelper.Swap(ref this.lateUpdates, ref this.lateUpdates2);
  321. }
  322. public void Run(int type)
  323. {
  324. List<IEvent> iEvents;
  325. if (!this.allEvents.TryGetValue((int)type, out iEvents))
  326. {
  327. return;
  328. }
  329. foreach (IEvent iEvent in iEvents)
  330. {
  331. try
  332. {
  333. iEvent?.Handle();
  334. }
  335. catch (Exception e)
  336. {
  337. Log.Error(e.ToString());
  338. }
  339. }
  340. }
  341. public void Run<A>(int type, A a)
  342. {
  343. List<IEvent> iEvents;
  344. if (!this.allEvents.TryGetValue((int)type, out iEvents))
  345. {
  346. return;
  347. }
  348. foreach (IEvent iEvent in iEvents)
  349. {
  350. try
  351. {
  352. iEvent?.Handle(a);
  353. }
  354. catch (Exception e)
  355. {
  356. Log.Error(e.ToString());
  357. }
  358. }
  359. }
  360. public void Run<A, B>(int type, A a, B b)
  361. {
  362. List<IEvent> iEvents;
  363. if (!this.allEvents.TryGetValue((int)type, out iEvents))
  364. {
  365. return;
  366. }
  367. foreach (IEvent iEvent in iEvents)
  368. {
  369. try
  370. {
  371. iEvent?.Handle(a, b);
  372. }
  373. catch (Exception e)
  374. {
  375. Log.Error(e.ToString());
  376. }
  377. }
  378. }
  379. public void Run<A, B, C>(int type, A a, B b, C c)
  380. {
  381. List<IEvent> iEvents;
  382. if (!this.allEvents.TryGetValue((int)type, out iEvents))
  383. {
  384. return;
  385. }
  386. foreach (IEvent iEvent in iEvents)
  387. {
  388. try
  389. {
  390. iEvent?.Handle(a, b, c);
  391. }
  392. catch (Exception e)
  393. {
  394. Log.Error(e.ToString());
  395. }
  396. }
  397. }
  398. }
  399. }