EventSystem.cs 13 KB

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