EventSystem.cs 15 KB

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