EventSystem.cs 15 KB

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