EventSystem.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Text;
  6. namespace ETModel
  7. {
  8. public enum DLLType
  9. {
  10. Model,
  11. Hotfix,
  12. Editor,
  13. }
  14. public sealed class EventSystem
  15. {
  16. private readonly Dictionary<long, Entity> allComponents = new Dictionary<long, Entity>();
  17. private readonly Dictionary<DLLType, Assembly> assemblies = new Dictionary<DLLType, Assembly>();
  18. private readonly UnOrderMultiMapSet<Type, Type> types = new UnOrderMultiMapSet<Type, Type>();
  19. private readonly Dictionary<string, List<object>> allEvents = new Dictionary<string, List<object>>();
  20. private readonly UnOrderMultiMap<Type, IAwakeSystem> awakeSystems = new UnOrderMultiMap<Type, IAwakeSystem>();
  21. private readonly UnOrderMultiMap<Type, IStartSystem> startSystems = new UnOrderMultiMap<Type, IStartSystem>();
  22. private readonly UnOrderMultiMap<Type, IDestroySystem> destroySystems = new UnOrderMultiMap<Type, IDestroySystem>();
  23. private readonly UnOrderMultiMap<Type, ILoadSystem> loadSystems = new UnOrderMultiMap<Type, ILoadSystem>();
  24. private readonly UnOrderMultiMap<Type, IUpdateSystem> updateSystems = new UnOrderMultiMap<Type, IUpdateSystem>();
  25. private readonly UnOrderMultiMap<Type, ILateUpdateSystem> lateUpdateSystems = new UnOrderMultiMap<Type, ILateUpdateSystem>();
  26. private readonly UnOrderMultiMap<Type, IChangeSystem> changeSystems = new UnOrderMultiMap<Type, IChangeSystem>();
  27. private readonly UnOrderMultiMap<Type, IDeserializeSystem> deserializeSystems = new UnOrderMultiMap<Type, IDeserializeSystem>();
  28. private Queue<long> updates = new Queue<long>();
  29. private Queue<long> updates2 = new Queue<long>();
  30. private readonly Queue<long> starts = new Queue<long>();
  31. private Queue<long> loaders = new Queue<long>();
  32. private Queue<long> loaders2 = new Queue<long>();
  33. private Queue<long> lateUpdates = new Queue<long>();
  34. private Queue<long> lateUpdates2 = new Queue<long>();
  35. public void Add(DLLType dllType, Assembly assembly)
  36. {
  37. this.assemblies[dllType] = assembly;
  38. this.types.Clear();
  39. foreach (Assembly value in this.assemblies.Values)
  40. {
  41. foreach (Type type in value.GetTypes())
  42. {
  43. if (type.IsAbstract)
  44. {
  45. continue;
  46. }
  47. object[] objects = type.GetCustomAttributes(typeof(BaseAttribute), true);
  48. if (objects.Length == 0)
  49. {
  50. continue;
  51. }
  52. BaseAttribute baseAttribute = (BaseAttribute) objects[0];
  53. this.types.Add(baseAttribute.AttributeType, type);
  54. }
  55. }
  56. this.awakeSystems.Clear();
  57. this.lateUpdateSystems.Clear();
  58. this.updateSystems.Clear();
  59. this.startSystems.Clear();
  60. this.loadSystems.Clear();
  61. this.changeSystems.Clear();
  62. this.destroySystems.Clear();
  63. this.deserializeSystems.Clear();
  64. foreach (Type type in this.GetTypes(typeof(ObjectSystemAttribute)))
  65. {
  66. object obj = Activator.CreateInstance(type);
  67. switch (obj)
  68. {
  69. case IAwakeSystem objectSystem:
  70. this.awakeSystems.Add(objectSystem.Type(), objectSystem);
  71. break;
  72. case IUpdateSystem updateSystem:
  73. this.updateSystems.Add(updateSystem.Type(), updateSystem);
  74. break;
  75. case ILateUpdateSystem lateUpdateSystem:
  76. this.lateUpdateSystems.Add(lateUpdateSystem.Type(), lateUpdateSystem);
  77. break;
  78. case IStartSystem startSystem:
  79. this.startSystems.Add(startSystem.Type(), startSystem);
  80. break;
  81. case IDestroySystem destroySystem:
  82. this.destroySystems.Add(destroySystem.Type(), destroySystem);
  83. break;
  84. case ILoadSystem loadSystem:
  85. this.loadSystems.Add(loadSystem.Type(), loadSystem);
  86. break;
  87. case IChangeSystem changeSystem:
  88. this.changeSystems.Add(changeSystem.Type(), changeSystem);
  89. break;
  90. case IDeserializeSystem deserializeSystem:
  91. this.deserializeSystems.Add(deserializeSystem.Type(), deserializeSystem);
  92. break;
  93. }
  94. }
  95. this.allEvents.Clear();
  96. if (this.types.ContainsKey(typeof (EventAttribute)))
  97. {
  98. foreach (Type type in types[typeof(EventAttribute)])
  99. {
  100. object[] attrs = type.GetCustomAttributes(typeof(EventAttribute), false);
  101. foreach (object attr in attrs)
  102. {
  103. EventAttribute aEventAttribute = (EventAttribute)attr;
  104. object obj = Activator.CreateInstance(type);
  105. IEvent iEvent = obj as IEvent;
  106. if (iEvent == null)
  107. {
  108. Log.Error($"{obj.GetType().Name} 没有继承IEvent");
  109. }
  110. this.RegisterEvent(aEventAttribute.Type, iEvent);
  111. }
  112. }
  113. }
  114. this.Load();
  115. }
  116. public void RegisterEvent(string eventId, IEvent e)
  117. {
  118. if (!this.allEvents.ContainsKey(eventId))
  119. {
  120. this.allEvents.Add(eventId, new List<object>());
  121. }
  122. this.allEvents[eventId].Add(e);
  123. }
  124. public Assembly Get(DLLType dllType)
  125. {
  126. return this.assemblies[dllType];
  127. }
  128. public HashSet<Type> GetTypes(Type systemAttributeType)
  129. {
  130. if (!this.types.ContainsKey(systemAttributeType))
  131. {
  132. return new HashSet<Type>();
  133. }
  134. return this.types[systemAttributeType];
  135. }
  136. public List<Type> GetTypes()
  137. {
  138. List<Type> allTypes = new List<Type>();
  139. foreach (Assembly assembly in this.assemblies.Values)
  140. {
  141. allTypes.AddRange(assembly.GetTypes());
  142. }
  143. return allTypes;
  144. }
  145. public void RegisterSystem(Entity component, bool isRegister = true)
  146. {
  147. if (!isRegister)
  148. {
  149. this.Remove(component.InstanceId);
  150. return;
  151. }
  152. this.allComponents.Add(component.InstanceId, component);
  153. Type type = component.GetType();
  154. if (this.loadSystems.ContainsKey(type))
  155. {
  156. this.loaders.Enqueue(component.InstanceId);
  157. }
  158. if (this.updateSystems.ContainsKey(type))
  159. {
  160. this.updates.Enqueue(component.InstanceId);
  161. }
  162. if (this.startSystems.ContainsKey(type))
  163. {
  164. this.starts.Enqueue(component.InstanceId);
  165. }
  166. if (this.lateUpdateSystems.ContainsKey(type))
  167. {
  168. this.lateUpdates.Enqueue(component.InstanceId);
  169. }
  170. }
  171. public void Remove(long instanceId)
  172. {
  173. this.allComponents.Remove(instanceId);
  174. }
  175. public Entity Get(long instanceId)
  176. {
  177. Entity component = null;
  178. this.allComponents.TryGetValue(instanceId, out component);
  179. return component;
  180. }
  181. public bool IsRegister(long instanceId)
  182. {
  183. return this.allComponents.ContainsKey(instanceId);
  184. }
  185. public void Deserialize(Entity component)
  186. {
  187. List<IDeserializeSystem> iDeserializeSystems = this.deserializeSystems[component.GetType()];
  188. if (iDeserializeSystems == null)
  189. {
  190. return;
  191. }
  192. foreach (IDeserializeSystem deserializeSystem in iDeserializeSystems)
  193. {
  194. if (deserializeSystem == null)
  195. {
  196. continue;
  197. }
  198. try
  199. {
  200. deserializeSystem.Run(component);
  201. }
  202. catch (Exception e)
  203. {
  204. Log.Error(e);
  205. }
  206. }
  207. }
  208. public void Awake(Entity component)
  209. {
  210. List<IAwakeSystem> iAwakeSystems = this.awakeSystems[component.GetType()];
  211. if (iAwakeSystems == null)
  212. {
  213. return;
  214. }
  215. foreach (IAwakeSystem aAwakeSystem in iAwakeSystems)
  216. {
  217. if (aAwakeSystem == null)
  218. {
  219. continue;
  220. }
  221. IAwake iAwake = aAwakeSystem as IAwake;
  222. if (iAwake == null)
  223. {
  224. continue;
  225. }
  226. try
  227. {
  228. iAwake.Run(component);
  229. }
  230. catch (Exception e)
  231. {
  232. Log.Error(e);
  233. }
  234. }
  235. }
  236. public void Awake<P1>(Entity component, P1 p1)
  237. {
  238. List<IAwakeSystem> iAwakeSystems = this.awakeSystems[component.GetType()];
  239. if (iAwakeSystems == null)
  240. {
  241. return;
  242. }
  243. foreach (IAwakeSystem aAwakeSystem in iAwakeSystems)
  244. {
  245. if (aAwakeSystem == null)
  246. {
  247. continue;
  248. }
  249. IAwake<P1> iAwake = aAwakeSystem as IAwake<P1>;
  250. if (iAwake == null)
  251. {
  252. continue;
  253. }
  254. try
  255. {
  256. iAwake.Run(component, p1);
  257. }
  258. catch (Exception e)
  259. {
  260. Log.Error(e);
  261. }
  262. }
  263. }
  264. public void Awake<P1, P2>(Entity component, P1 p1, P2 p2)
  265. {
  266. List<IAwakeSystem> iAwakeSystems = this.awakeSystems[component.GetType()];
  267. if (iAwakeSystems == null)
  268. {
  269. return;
  270. }
  271. foreach (IAwakeSystem aAwakeSystem in iAwakeSystems)
  272. {
  273. if (aAwakeSystem == null)
  274. {
  275. continue;
  276. }
  277. IAwake<P1, P2> iAwake = aAwakeSystem as IAwake<P1, P2>;
  278. if (iAwake == null)
  279. {
  280. continue;
  281. }
  282. try
  283. {
  284. iAwake.Run(component, p1, p2);
  285. }
  286. catch (Exception e)
  287. {
  288. Log.Error(e);
  289. }
  290. }
  291. }
  292. public void Awake<P1, P2, P3>(Entity component, P1 p1, P2 p2, P3 p3)
  293. {
  294. List<IAwakeSystem> iAwakeSystems = this.awakeSystems[component.GetType()];
  295. if (iAwakeSystems == null)
  296. {
  297. return;
  298. }
  299. foreach (IAwakeSystem aAwakeSystem in iAwakeSystems)
  300. {
  301. if (aAwakeSystem == null)
  302. {
  303. continue;
  304. }
  305. IAwake<P1, P2, P3> iAwake = aAwakeSystem as IAwake<P1, P2, P3>;
  306. if (iAwake == null)
  307. {
  308. continue;
  309. }
  310. try
  311. {
  312. iAwake.Run(component, p1, p2, p3);
  313. }
  314. catch (Exception e)
  315. {
  316. Log.Error(e);
  317. }
  318. }
  319. }
  320. public void Awake<P1, P2, P3, P4>(Entity component, P1 p1, P2 p2, P3 p3, P4 p4)
  321. {
  322. List<IAwakeSystem> iAwakeSystems = this.awakeSystems[component.GetType()];
  323. if (iAwakeSystems == null)
  324. {
  325. return;
  326. }
  327. foreach (IAwakeSystem aAwakeSystem in iAwakeSystems)
  328. {
  329. if (aAwakeSystem == null)
  330. {
  331. continue;
  332. }
  333. IAwake<P1, P2, P3, P4> iAwake = aAwakeSystem as IAwake<P1, P2, P3, P4>;
  334. if (iAwake == null)
  335. {
  336. continue;
  337. }
  338. try
  339. {
  340. iAwake.Run(component, p1, p2, p3, p4);
  341. }
  342. catch (Exception e)
  343. {
  344. Log.Error(e);
  345. }
  346. }
  347. }
  348. public void Change(Entity component)
  349. {
  350. List<IChangeSystem> iChangeSystems = this.changeSystems[component.GetType()];
  351. if (iChangeSystems == null)
  352. {
  353. return;
  354. }
  355. foreach (IChangeSystem iChangeSystem in iChangeSystems)
  356. {
  357. if (iChangeSystem == null)
  358. {
  359. continue;
  360. }
  361. try
  362. {
  363. iChangeSystem.Run(component);
  364. }
  365. catch (Exception e)
  366. {
  367. Log.Error(e);
  368. }
  369. }
  370. }
  371. public void Load()
  372. {
  373. while (this.loaders.Count > 0)
  374. {
  375. long instanceId = this.loaders.Dequeue();
  376. Entity component;
  377. if (!this.allComponents.TryGetValue(instanceId, out component))
  378. {
  379. continue;
  380. }
  381. if (component.IsDisposed)
  382. {
  383. continue;
  384. }
  385. List<ILoadSystem> iLoadSystems = this.loadSystems[component.GetType()];
  386. if (iLoadSystems == null)
  387. {
  388. continue;
  389. }
  390. this.loaders2.Enqueue(instanceId);
  391. foreach (ILoadSystem iLoadSystem in iLoadSystems)
  392. {
  393. try
  394. {
  395. iLoadSystem.Run(component);
  396. }
  397. catch (Exception e)
  398. {
  399. Log.Error(e);
  400. }
  401. }
  402. }
  403. ObjectHelper.Swap(ref this.loaders, ref this.loaders2);
  404. }
  405. private void Start()
  406. {
  407. while (this.starts.Count > 0)
  408. {
  409. long instanceId = this.starts.Dequeue();
  410. Entity component;
  411. if (!this.allComponents.TryGetValue(instanceId, out component))
  412. {
  413. continue;
  414. }
  415. List<IStartSystem> iStartSystems = this.startSystems[component.GetType()];
  416. if (iStartSystems == null)
  417. {
  418. continue;
  419. }
  420. foreach (IStartSystem iStartSystem in iStartSystems)
  421. {
  422. try
  423. {
  424. iStartSystem.Run(component);
  425. }
  426. catch (Exception e)
  427. {
  428. Log.Error(e);
  429. }
  430. }
  431. }
  432. }
  433. public void Destroy(Entity component)
  434. {
  435. List<IDestroySystem> iDestroySystems = this.destroySystems[component.GetType()];
  436. if (iDestroySystems == null)
  437. {
  438. return;
  439. }
  440. foreach (IDestroySystem iDestroySystem in iDestroySystems)
  441. {
  442. if (iDestroySystem == null)
  443. {
  444. continue;
  445. }
  446. try
  447. {
  448. iDestroySystem.Run(component);
  449. }
  450. catch (Exception e)
  451. {
  452. Log.Error(e);
  453. }
  454. }
  455. }
  456. public void Update()
  457. {
  458. this.Start();
  459. while (this.updates.Count > 0)
  460. {
  461. long instanceId = this.updates.Dequeue();
  462. Entity component;
  463. if (!this.allComponents.TryGetValue(instanceId, out component))
  464. {
  465. continue;
  466. }
  467. if (component.IsDisposed)
  468. {
  469. continue;
  470. }
  471. List<IUpdateSystem> iUpdateSystems = this.updateSystems[component.GetType()];
  472. if (iUpdateSystems == null)
  473. {
  474. continue;
  475. }
  476. this.updates2.Enqueue(instanceId);
  477. foreach (IUpdateSystem iUpdateSystem in iUpdateSystems)
  478. {
  479. try
  480. {
  481. iUpdateSystem.Run(component);
  482. }
  483. catch (Exception e)
  484. {
  485. Log.Error(e);
  486. }
  487. }
  488. }
  489. ObjectHelper.Swap(ref this.updates, ref this.updates2);
  490. }
  491. public void LateUpdate()
  492. {
  493. while (this.lateUpdates.Count > 0)
  494. {
  495. long instanceId = this.lateUpdates.Dequeue();
  496. Entity component;
  497. if (!this.allComponents.TryGetValue(instanceId, out component))
  498. {
  499. continue;
  500. }
  501. if (component.IsDisposed)
  502. {
  503. continue;
  504. }
  505. List<ILateUpdateSystem> iLateUpdateSystems = this.lateUpdateSystems[component.GetType()];
  506. if (iLateUpdateSystems == null)
  507. {
  508. continue;
  509. }
  510. this.lateUpdates2.Enqueue(instanceId);
  511. foreach (ILateUpdateSystem iLateUpdateSystem in iLateUpdateSystems)
  512. {
  513. try
  514. {
  515. iLateUpdateSystem.Run(component);
  516. }
  517. catch (Exception e)
  518. {
  519. Log.Error(e);
  520. }
  521. }
  522. }
  523. ObjectHelper.Swap(ref this.lateUpdates, ref this.lateUpdates2);
  524. }
  525. public void Run(string type)
  526. {
  527. List<object> iEvents;
  528. if (!this.allEvents.TryGetValue(type, out iEvents))
  529. {
  530. return;
  531. }
  532. foreach (AEvent aEvent in iEvents)
  533. {
  534. try
  535. {
  536. aEvent.Run();
  537. }
  538. catch (Exception e)
  539. {
  540. Log.Error(e);
  541. }
  542. }
  543. }
  544. public void Run<A>(string type, A a)
  545. {
  546. List<object> iEvents;
  547. if (!this.allEvents.TryGetValue(type, out iEvents))
  548. {
  549. return;
  550. }
  551. foreach (object obj in iEvents)
  552. {
  553. try
  554. {
  555. if (obj is AEvent<A> aEvent)
  556. {
  557. aEvent.Run(a);
  558. }
  559. else if (obj is EventProxy eventProxy)
  560. {
  561. eventProxy.Handle(a);
  562. }
  563. }
  564. catch (Exception e)
  565. {
  566. Log.Error(e);
  567. }
  568. }
  569. }
  570. public void Run<A, B>(string type, A a, B b)
  571. {
  572. List<object> iEvents;
  573. if (!this.allEvents.TryGetValue(type, out iEvents))
  574. {
  575. return;
  576. }
  577. foreach (object obj in iEvents)
  578. {
  579. try
  580. {
  581. if (obj is AEvent<A, B> aEvent)
  582. {
  583. aEvent.Run(a, b);
  584. }
  585. else if (obj is EventProxy eventProxy)
  586. {
  587. eventProxy.Handle(a, b);
  588. }
  589. }
  590. catch (Exception e)
  591. {
  592. Log.Error(e);
  593. }
  594. }
  595. }
  596. public void Run<A, B, C>(string type, A a, B b, C c)
  597. {
  598. List<object> iEvents;
  599. if (!this.allEvents.TryGetValue(type, out iEvents))
  600. {
  601. return;
  602. }
  603. foreach (object obj in iEvents)
  604. {
  605. try
  606. {
  607. if (obj is AEvent<A, B, C> aEvent)
  608. {
  609. aEvent.Run(a, b, c);
  610. }
  611. else if (obj is EventProxy eventProxy)
  612. {
  613. eventProxy.Handle(a, b, c);
  614. }
  615. }
  616. catch (Exception e)
  617. {
  618. Log.Error(e);
  619. }
  620. }
  621. }
  622. public override string ToString()
  623. {
  624. StringBuilder sb = new StringBuilder();
  625. HashSet<Type> noParent = new HashSet<Type>();
  626. Dictionary<Type, int> typeCount = new Dictionary<Type, int>();
  627. HashSet<Type> noDomain = new HashSet<Type>();
  628. foreach (var kv in this.allComponents)
  629. {
  630. Type type = kv.Value.GetType();
  631. if (kv.Value.Parent == null)
  632. {
  633. noParent.Add(type);
  634. }
  635. if (kv.Value.Domain == null)
  636. {
  637. noDomain.Add(type);
  638. }
  639. if (typeCount.ContainsKey(type))
  640. {
  641. typeCount[type]++;
  642. }
  643. else
  644. {
  645. typeCount[type] = 1;
  646. }
  647. }
  648. sb.AppendLine("not set parent type: ");
  649. foreach (Type type in noParent)
  650. {
  651. sb.AppendLine($"\t{type.Name}");
  652. }
  653. sb.AppendLine("not set domain type: ");
  654. foreach (Type type in noDomain)
  655. {
  656. sb.AppendLine($"\t{type.Name}");
  657. }
  658. IOrderedEnumerable<KeyValuePair<Type, int>> orderByDescending = typeCount.OrderByDescending(s => s.Value);
  659. sb.AppendLine("Entity Count: ");
  660. foreach (var kv in orderByDescending)
  661. {
  662. if (kv.Value == 1)
  663. {
  664. continue;
  665. }
  666. sb.AppendLine($"\t{kv.Key.Name}: {kv.Value}");
  667. }
  668. return sb.ToString();
  669. }
  670. }
  671. }