EventSystem.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. namespace ETModel
  6. {
  7. public enum DLLType
  8. {
  9. Model,
  10. Hotfix,
  11. Editor,
  12. }
  13. public sealed class EventSystem
  14. {
  15. private readonly Dictionary<long, Component> allComponents = new Dictionary<long, Component>();
  16. private readonly Dictionary<DLLType, Assembly> assemblies = new Dictionary<DLLType, Assembly>();
  17. private readonly List<Type> types = new List<Type>();
  18. private readonly Dictionary<string, List<IEvent>> allEvents = new Dictionary<string, List<IEvent>>();
  19. private readonly UnOrderMultiMap<Type, IAwakeSystem> awakeSystems = new UnOrderMultiMap<Type, IAwakeSystem>();
  20. private readonly UnOrderMultiMap<Type, IStartSystem> startSystems = new UnOrderMultiMap<Type, IStartSystem>();
  21. private readonly UnOrderMultiMap<Type, IDestroySystem> destroySystems = new UnOrderMultiMap<Type, IDestroySystem>();
  22. private readonly UnOrderMultiMap<Type, ILoadSystem> loadSystems = new UnOrderMultiMap<Type, ILoadSystem>();
  23. private readonly UnOrderMultiMap<Type, IUpdateSystem> updateSystems = new UnOrderMultiMap<Type, IUpdateSystem>();
  24. private readonly UnOrderMultiMap<Type, ILateUpdateSystem> lateUpdateSystems = new UnOrderMultiMap<Type, ILateUpdateSystem>();
  25. private readonly UnOrderMultiMap<Type, IChangeSystem> changeSystems = new UnOrderMultiMap<Type, IChangeSystem>();
  26. private Queue<long> updates = new Queue<long>();
  27. private Queue<long> updates2 = new Queue<long>();
  28. private readonly Queue<long> starts = new Queue<long>();
  29. private Queue<long> loaders = new Queue<long>();
  30. private Queue<long> loaders2 = new Queue<long>();
  31. private Queue<long> lateUpdates = new Queue<long>();
  32. private Queue<long> lateUpdates2 = new Queue<long>();
  33. public void Add(DLLType dllType, Assembly assembly)
  34. {
  35. this.assemblies[dllType] = assembly;
  36. this.types.Clear();
  37. foreach (Assembly value in this.assemblies.Values)
  38. {
  39. this.types.AddRange(value.GetTypes());
  40. }
  41. this.awakeSystems.Clear();
  42. this.lateUpdateSystems.Clear();
  43. this.updateSystems.Clear();
  44. this.startSystems.Clear();
  45. this.loadSystems.Clear();
  46. this.changeSystems.Clear();
  47. foreach (Type type in types)
  48. {
  49. object[] attrs = type.GetCustomAttributes(typeof(ObjectSystemAttribute), false);
  50. if (attrs.Length == 0)
  51. {
  52. continue;
  53. }
  54. object obj = Activator.CreateInstance(type);
  55. IAwakeSystem objectSystem = obj as IAwakeSystem;
  56. if (objectSystem != null)
  57. {
  58. this.awakeSystems.Add(objectSystem.Type(), objectSystem);
  59. }
  60. IUpdateSystem updateSystem = obj as IUpdateSystem;
  61. if (updateSystem != null)
  62. {
  63. this.updateSystems.Add(updateSystem.Type(), updateSystem);
  64. }
  65. ILateUpdateSystem lateUpdateSystem = obj as ILateUpdateSystem;
  66. if (lateUpdateSystem != null)
  67. {
  68. this.lateUpdateSystems.Add(lateUpdateSystem.Type(), lateUpdateSystem);
  69. }
  70. IStartSystem startSystem = obj as IStartSystem;
  71. if (startSystem != null)
  72. {
  73. this.startSystems.Add(startSystem.Type(), startSystem);
  74. }
  75. IDestroySystem destroySystem = obj as IDestroySystem;
  76. if (destroySystem != null)
  77. {
  78. this.destroySystems.Add(destroySystem.Type(), destroySystem);
  79. }
  80. ILoadSystem loadSystem = obj as ILoadSystem;
  81. if (loadSystem != null)
  82. {
  83. this.loadSystems.Add(loadSystem.Type(), loadSystem);
  84. }
  85. IChangeSystem changeSystem = obj as IChangeSystem;
  86. if (changeSystem != null)
  87. {
  88. this.changeSystems.Add(changeSystem.Type(), changeSystem);
  89. }
  90. }
  91. this.allEvents.Clear();
  92. foreach (Type type in types)
  93. {
  94. object[] attrs = type.GetCustomAttributes(typeof(EventAttribute), false);
  95. foreach (object attr in attrs)
  96. {
  97. EventAttribute aEventAttribute = (EventAttribute)attr;
  98. object obj = Activator.CreateInstance(type);
  99. IEvent iEvent = obj as IEvent;
  100. if (iEvent == null)
  101. {
  102. Log.Error($"{obj.GetType().Name} 没有继承IEvent");
  103. }
  104. this.RegisterEvent(aEventAttribute.Type, iEvent);
  105. }
  106. }
  107. this.Load();
  108. }
  109. public void RegisterEvent(string eventId, IEvent e)
  110. {
  111. if (!this.allEvents.ContainsKey(eventId))
  112. {
  113. this.allEvents.Add(eventId, new List<IEvent>());
  114. }
  115. this.allEvents[eventId].Add(e);
  116. }
  117. public Assembly Get(DLLType dllType)
  118. {
  119. return this.assemblies[dllType];
  120. }
  121. public List<Type> GetTypes()
  122. {
  123. return this.types;
  124. }
  125. public void Add(Component component)
  126. {
  127. this.allComponents.Add(component.InstanceId, component);
  128. Type type = component.GetType();
  129. if (this.loadSystems.ContainsKey(type))
  130. {
  131. this.loaders.Enqueue(component.InstanceId);
  132. }
  133. if (this.updateSystems.ContainsKey(type))
  134. {
  135. this.updates.Enqueue(component.InstanceId);
  136. }
  137. if (this.startSystems.ContainsKey(type))
  138. {
  139. this.starts.Enqueue(component.InstanceId);
  140. }
  141. if (this.lateUpdateSystems.ContainsKey(type))
  142. {
  143. this.lateUpdates.Enqueue(component.InstanceId);
  144. }
  145. }
  146. public void Remove(long id)
  147. {
  148. this.allComponents.Remove(id);
  149. }
  150. public Component Get(long id)
  151. {
  152. Component component = null;
  153. this.allComponents.TryGetValue(id, out component);
  154. return component;
  155. }
  156. public void Awake(Component component)
  157. {
  158. List<IAwakeSystem> iAwakeSystems = this.awakeSystems[component.GetType()];
  159. if (iAwakeSystems == null)
  160. {
  161. return;
  162. }
  163. foreach (IAwakeSystem aAwakeSystem in iAwakeSystems)
  164. {
  165. if (aAwakeSystem == null)
  166. {
  167. continue;
  168. }
  169. IAwake iAwake = aAwakeSystem as IAwake;
  170. if (iAwake == null)
  171. {
  172. continue;
  173. }
  174. try
  175. {
  176. iAwake.Run(component);
  177. }
  178. catch (Exception e)
  179. {
  180. Log.Error(e);
  181. }
  182. }
  183. }
  184. public void Awake<P1>(Component component, P1 p1)
  185. {
  186. List<IAwakeSystem> iAwakeSystems = this.awakeSystems[component.GetType()];
  187. if (iAwakeSystems == null)
  188. {
  189. return;
  190. }
  191. foreach (IAwakeSystem aAwakeSystem in iAwakeSystems)
  192. {
  193. if (aAwakeSystem == null)
  194. {
  195. continue;
  196. }
  197. IAwake<P1> iAwake = aAwakeSystem as IAwake<P1>;
  198. if (iAwake == null)
  199. {
  200. continue;
  201. }
  202. try
  203. {
  204. iAwake.Run(component, p1);
  205. }
  206. catch (Exception e)
  207. {
  208. Log.Error(e);
  209. }
  210. }
  211. }
  212. public void Awake<P1, P2>(Component component, P1 p1, P2 p2)
  213. {
  214. List<IAwakeSystem> iAwakeSystems = this.awakeSystems[component.GetType()];
  215. if (iAwakeSystems == null)
  216. {
  217. return;
  218. }
  219. foreach (IAwakeSystem aAwakeSystem in iAwakeSystems)
  220. {
  221. if (aAwakeSystem == null)
  222. {
  223. continue;
  224. }
  225. IAwake<P1, P2> iAwake = aAwakeSystem as IAwake<P1, P2>;
  226. if (iAwake == null)
  227. {
  228. continue;
  229. }
  230. try
  231. {
  232. iAwake.Run(component, p1, p2);
  233. }
  234. catch (Exception e)
  235. {
  236. Log.Error(e);
  237. }
  238. }
  239. }
  240. public void Awake<P1, P2, P3>(Component component, P1 p1, P2 p2, P3 p3)
  241. {
  242. List<IAwakeSystem> iAwakeSystems = this.awakeSystems[component.GetType()];
  243. if (iAwakeSystems == null)
  244. {
  245. return;
  246. }
  247. foreach (IAwakeSystem aAwakeSystem in iAwakeSystems)
  248. {
  249. if (aAwakeSystem == null)
  250. {
  251. continue;
  252. }
  253. IAwake<P1, P2, P3> iAwake = aAwakeSystem as IAwake<P1, P2, P3>;
  254. if (iAwake == null)
  255. {
  256. continue;
  257. }
  258. try
  259. {
  260. iAwake.Run(component, p1, p2, p3);
  261. }
  262. catch (Exception e)
  263. {
  264. Log.Error(e);
  265. }
  266. }
  267. }
  268. public void Change(Component component)
  269. {
  270. List<IChangeSystem> iChangeSystems = this.changeSystems[component.GetType()];
  271. if (iChangeSystems == null)
  272. {
  273. return;
  274. }
  275. foreach (IChangeSystem iChangeSystem in iChangeSystems)
  276. {
  277. if (iChangeSystem == null)
  278. {
  279. continue;
  280. }
  281. try
  282. {
  283. iChangeSystem.Run(component);
  284. }
  285. catch (Exception e)
  286. {
  287. Log.Error(e);
  288. }
  289. }
  290. }
  291. public void Load()
  292. {
  293. while (this.loaders.Count > 0)
  294. {
  295. long instanceId = this.loaders.Dequeue();
  296. Component component;
  297. if (!this.allComponents.TryGetValue(instanceId, out component))
  298. {
  299. continue;
  300. }
  301. if (component.IsDisposed)
  302. {
  303. continue;
  304. }
  305. List<ILoadSystem> iLoadSystems = this.loadSystems[component.GetType()];
  306. if (iLoadSystems == null)
  307. {
  308. continue;
  309. }
  310. this.loaders2.Enqueue(instanceId);
  311. foreach (ILoadSystem iLoadSystem in iLoadSystems)
  312. {
  313. try
  314. {
  315. iLoadSystem.Run(component);
  316. }
  317. catch (Exception e)
  318. {
  319. Log.Error(e);
  320. }
  321. }
  322. }
  323. ObjectHelper.Swap(ref this.loaders, ref this.loaders2);
  324. }
  325. private void Start()
  326. {
  327. while (this.starts.Count > 0)
  328. {
  329. long instanceId = this.starts.Dequeue();
  330. Component component;
  331. if (!this.allComponents.TryGetValue(instanceId, out component))
  332. {
  333. continue;
  334. }
  335. List<IStartSystem> iStartSystems = this.startSystems[component.GetType()];
  336. if (iStartSystems == null)
  337. {
  338. continue;
  339. }
  340. foreach (IStartSystem iStartSystem in iStartSystems)
  341. {
  342. try
  343. {
  344. iStartSystem.Run(component);
  345. }
  346. catch (Exception e)
  347. {
  348. Log.Error(e);
  349. }
  350. }
  351. }
  352. }
  353. public void Destroy(Component component)
  354. {
  355. List<IDestroySystem> iDestroySystems = this.destroySystems[component.GetType()];
  356. if (iDestroySystems == null)
  357. {
  358. return;
  359. }
  360. foreach (IDestroySystem iDestroySystem in iDestroySystems)
  361. {
  362. if (iDestroySystem == null)
  363. {
  364. continue;
  365. }
  366. try
  367. {
  368. iDestroySystem.Run(component);
  369. }
  370. catch (Exception e)
  371. {
  372. Log.Error(e);
  373. }
  374. }
  375. }
  376. public void Update()
  377. {
  378. this.Start();
  379. while (this.updates.Count > 0)
  380. {
  381. long instanceId = this.updates.Dequeue();
  382. Component component;
  383. if (!this.allComponents.TryGetValue(instanceId, out component))
  384. {
  385. continue;
  386. }
  387. if (component.IsDisposed)
  388. {
  389. continue;
  390. }
  391. List<IUpdateSystem> iUpdateSystems = this.updateSystems[component.GetType()];
  392. if (iUpdateSystems == null)
  393. {
  394. continue;
  395. }
  396. this.updates2.Enqueue(instanceId);
  397. foreach (IUpdateSystem iUpdateSystem in iUpdateSystems)
  398. {
  399. try
  400. {
  401. iUpdateSystem.Run(component);
  402. }
  403. catch (Exception e)
  404. {
  405. Log.Error(e);
  406. }
  407. }
  408. }
  409. ObjectHelper.Swap(ref this.updates, ref this.updates2);
  410. }
  411. public void LateUpdate()
  412. {
  413. while (this.lateUpdates.Count > 0)
  414. {
  415. long instanceId = this.lateUpdates.Dequeue();
  416. Component component;
  417. if (!this.allComponents.TryGetValue(instanceId, out component))
  418. {
  419. continue;
  420. }
  421. if (component.IsDisposed)
  422. {
  423. continue;
  424. }
  425. List<ILateUpdateSystem> iLateUpdateSystems = this.lateUpdateSystems[component.GetType()];
  426. if (iLateUpdateSystems == null)
  427. {
  428. continue;
  429. }
  430. this.lateUpdates2.Enqueue(instanceId);
  431. foreach (ILateUpdateSystem iLateUpdateSystem in iLateUpdateSystems)
  432. {
  433. try
  434. {
  435. iLateUpdateSystem.Run(component);
  436. }
  437. catch (Exception e)
  438. {
  439. Log.Error(e);
  440. }
  441. }
  442. }
  443. ObjectHelper.Swap(ref this.lateUpdates, ref this.lateUpdates2);
  444. }
  445. public void Run(string type)
  446. {
  447. List<IEvent> iEvents;
  448. if (!this.allEvents.TryGetValue(type, out iEvents))
  449. {
  450. return;
  451. }
  452. foreach (IEvent iEvent in iEvents)
  453. {
  454. try
  455. {
  456. iEvent?.Handle();
  457. }
  458. catch (Exception e)
  459. {
  460. Log.Error(e);
  461. }
  462. }
  463. }
  464. public void Run<A>(string type, A a)
  465. {
  466. List<IEvent> iEvents;
  467. if (!this.allEvents.TryGetValue(type, out iEvents))
  468. {
  469. return;
  470. }
  471. foreach (IEvent iEvent in iEvents)
  472. {
  473. try
  474. {
  475. iEvent?.Handle(a);
  476. }
  477. catch (Exception e)
  478. {
  479. Log.Error(e);
  480. }
  481. }
  482. }
  483. public void Run<A, B>(string type, A a, B b)
  484. {
  485. List<IEvent> iEvents;
  486. if (!this.allEvents.TryGetValue(type, out iEvents))
  487. {
  488. return;
  489. }
  490. foreach (IEvent iEvent in iEvents)
  491. {
  492. try
  493. {
  494. iEvent?.Handle(a, b);
  495. }
  496. catch (Exception e)
  497. {
  498. Log.Error(e);
  499. }
  500. }
  501. }
  502. public void Run<A, B, C>(string type, A a, B b, C c)
  503. {
  504. List<IEvent> iEvents;
  505. if (!this.allEvents.TryGetValue(type, out iEvents))
  506. {
  507. return;
  508. }
  509. foreach (IEvent iEvent in iEvents)
  510. {
  511. try
  512. {
  513. iEvent?.Handle(a, b, c);
  514. }
  515. catch (Exception e)
  516. {
  517. Log.Error(e);
  518. }
  519. }
  520. }
  521. }
  522. }