EventSystem.cs 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. namespace Model
  6. {
  7. public enum DLLType
  8. {
  9. Model,
  10. Hotfix,
  11. Editor,
  12. }
  13. public interface IObjectSystem
  14. {
  15. Type Type();
  16. void Set(object value);
  17. }
  18. public abstract class ObjectSystem<T> : IObjectSystem
  19. {
  20. private T value;
  21. protected T Get()
  22. {
  23. return value;
  24. }
  25. public void Set(object v)
  26. {
  27. this.value = (T)v;
  28. }
  29. public Type Type()
  30. {
  31. return typeof(T);
  32. }
  33. }
  34. public sealed class EventSystem
  35. {
  36. private Assembly hotfixAssembly;
  37. public Assembly HotfixAssembly
  38. {
  39. get
  40. {
  41. return this.hotfixAssembly;
  42. }
  43. set
  44. {
  45. this.hotfixAssembly = value;
  46. }
  47. }
  48. private readonly Dictionary<DLLType, Assembly> assemblies = new Dictionary<DLLType, Assembly>();
  49. private readonly Dictionary<EventIdType, List<IEventMethod>> allEvents = new Dictionary<EventIdType, List<IEventMethod>>();
  50. private readonly Dictionary<Type, IObjectSystem> disposerEvents = new Dictionary<Type, IObjectSystem>();
  51. private Queue<Disposer> updates = new Queue<Disposer>();
  52. private Queue<Disposer> updates2 = new Queue<Disposer>();
  53. private readonly Queue<Disposer> starts = new Queue<Disposer>();
  54. private Queue<Disposer> loaders = new Queue<Disposer>();
  55. private Queue<Disposer> loaders2 = new Queue<Disposer>();
  56. private Queue<Disposer> lateUpdates = new Queue<Disposer>();
  57. private Queue<Disposer> lateUpdates2 = new Queue<Disposer>();
  58. private readonly HashSet<Disposer> unique = new HashSet<Disposer>();
  59. public void LoadHotfixDll()
  60. {
  61. #if ILRuntime
  62. DllHelper.LoadHotfixAssembly();
  63. #else
  64. this.HotfixAssembly = DllHelper.LoadHotfixAssembly();
  65. #endif
  66. this.Register();
  67. this.Load();
  68. }
  69. public void Add(DLLType dllType, Assembly assembly)
  70. {
  71. this.assemblies[dllType] = assembly;
  72. this.Register();
  73. }
  74. private void Register()
  75. {
  76. Type[] types = DllHelper.GetMonoTypes();
  77. foreach (Type type in types)
  78. {
  79. object[] attrs = type.GetCustomAttributes(typeof(ObjectSystemAttribute), false);
  80. if (attrs.Length == 0)
  81. {
  82. continue;
  83. }
  84. object obj = Activator.CreateInstance(type);
  85. IObjectSystem objectSystem = obj as IObjectSystem;
  86. if (objectSystem == null)
  87. {
  88. Log.Error($"组件事件没有继承IObjectEvent: {type.Name}");
  89. continue;
  90. }
  91. this.disposerEvents[objectSystem.Type()] = objectSystem;
  92. }
  93. this.allEvents.Clear();
  94. foreach (Type type in types)
  95. {
  96. object[] attrs = type.GetCustomAttributes(typeof(EventAttribute), false);
  97. foreach (object attr in attrs)
  98. {
  99. EventAttribute aEventAttribute = (EventAttribute)attr;
  100. object obj = Activator.CreateInstance(type);
  101. if (!this.allEvents.ContainsKey((EventIdType)aEventAttribute.Type))
  102. {
  103. this.allEvents.Add((EventIdType)aEventAttribute.Type, new List<IEventMethod>());
  104. }
  105. this.allEvents[(EventIdType)aEventAttribute.Type].Add(new IEventMonoMethod(obj));
  106. }
  107. }
  108. // hotfix dll
  109. Type[] hotfixTypes = DllHelper.GetHotfixTypes();
  110. foreach (Type type in hotfixTypes)
  111. {
  112. object[] attrs = type.GetCustomAttributes(typeof(EventAttribute), false);
  113. foreach (object attr in attrs)
  114. {
  115. EventAttribute aEventAttribute = (EventAttribute)attr;
  116. #if ILRuntime
  117. IEventMethod method = new IEventILMethod(type, "Run");
  118. #else
  119. object obj = Activator.CreateInstance(type);
  120. IEventMethod method = new IEventMonoMethod(obj);
  121. #endif
  122. if (!allEvents.ContainsKey((EventIdType)aEventAttribute.Type))
  123. {
  124. allEvents.Add((EventIdType)aEventAttribute.Type, new List<IEventMethod>());
  125. }
  126. allEvents[(EventIdType)aEventAttribute.Type].Add(method);
  127. }
  128. }
  129. }
  130. public Assembly Get(DLLType dllType)
  131. {
  132. return this.assemblies[dllType];
  133. }
  134. public Assembly[] GetAll()
  135. {
  136. return this.assemblies.Values.ToArray();
  137. }
  138. public void Add(Disposer disposer)
  139. {
  140. IObjectSystem objectSystem;
  141. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out objectSystem))
  142. {
  143. return;
  144. }
  145. if (objectSystem is ILoad)
  146. {
  147. this.loaders.Enqueue(disposer);
  148. }
  149. if (objectSystem is IUpdate)
  150. {
  151. this.updates.Enqueue(disposer);
  152. }
  153. if (objectSystem is IStart)
  154. {
  155. this.starts.Enqueue(disposer);
  156. }
  157. if (objectSystem is ILateUpdate)
  158. {
  159. this.lateUpdates.Enqueue(disposer);
  160. }
  161. }
  162. public void Awake(Disposer disposer)
  163. {
  164. this.Add(disposer);
  165. IObjectSystem objectSystem;
  166. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out objectSystem))
  167. {
  168. return;
  169. }
  170. IAwake iAwake = objectSystem as IAwake;
  171. if (iAwake == null)
  172. {
  173. return;
  174. }
  175. objectSystem.Set(disposer);
  176. iAwake.Awake();
  177. }
  178. public void Awake<P1>(Disposer disposer, P1 p1)
  179. {
  180. this.Add(disposer);
  181. IObjectSystem objectSystem;
  182. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out objectSystem))
  183. {
  184. return;
  185. }
  186. IAwake<P1> iAwake = objectSystem as IAwake<P1>;
  187. if (iAwake == null)
  188. {
  189. return;
  190. }
  191. objectSystem.Set(disposer);
  192. iAwake.Awake(p1);
  193. }
  194. public void Awake<P1, P2>(Disposer disposer, P1 p1, P2 p2)
  195. {
  196. this.Add(disposer);
  197. IObjectSystem objectSystem;
  198. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out objectSystem))
  199. {
  200. return;
  201. }
  202. IAwake<P1, P2> iAwake = objectSystem as IAwake<P1, P2>;
  203. if (iAwake == null)
  204. {
  205. return;
  206. }
  207. objectSystem.Set(disposer);
  208. iAwake.Awake(p1, p2);
  209. }
  210. public void Awake<P1, P2, P3>(Disposer disposer, P1 p1, P2 p2, P3 p3)
  211. {
  212. this.Add(disposer);
  213. IObjectSystem objectSystem;
  214. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out objectSystem))
  215. {
  216. return;
  217. }
  218. IAwake<P1, P2, P3> iAwake = objectSystem as IAwake<P1, P2, P3>;
  219. if (iAwake == null)
  220. {
  221. return;
  222. }
  223. objectSystem.Set(disposer);
  224. iAwake.Awake(p1, p2, p3);
  225. }
  226. public void Load()
  227. {
  228. unique.Clear();
  229. while (this.loaders.Count > 0)
  230. {
  231. Disposer disposer = this.loaders.Dequeue();
  232. if (disposer.Id == 0)
  233. {
  234. continue;
  235. }
  236. if (!this.unique.Add(disposer))
  237. {
  238. continue;
  239. }
  240. IObjectSystem objectSystem;
  241. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out objectSystem))
  242. {
  243. continue;
  244. }
  245. this.loaders2.Enqueue(disposer);
  246. ILoad iLoad = objectSystem as ILoad;
  247. if (iLoad == null)
  248. {
  249. continue;
  250. }
  251. objectSystem.Set(disposer);
  252. try
  253. {
  254. iLoad.Load();
  255. }
  256. catch (Exception e)
  257. {
  258. Log.Error(e.ToString());
  259. }
  260. }
  261. ObjectHelper.Swap(ref this.loaders, ref this.loaders2);
  262. }
  263. private void Start()
  264. {
  265. unique.Clear();
  266. while (this.starts.Count > 0)
  267. {
  268. Disposer disposer = this.starts.Dequeue();
  269. if (!this.unique.Add(disposer))
  270. {
  271. continue;
  272. }
  273. IObjectSystem objectSystem;
  274. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out objectSystem))
  275. {
  276. continue;
  277. }
  278. IStart iStart = objectSystem as IStart;
  279. if (iStart == null)
  280. {
  281. continue;
  282. }
  283. objectSystem.Set(disposer);
  284. iStart.Start();
  285. }
  286. }
  287. public void Update()
  288. {
  289. this.Start();
  290. this.unique.Clear();
  291. while (this.updates.Count > 0)
  292. {
  293. Disposer disposer = this.updates.Dequeue();
  294. if (disposer.Id == 0)
  295. {
  296. continue;
  297. }
  298. if (!this.unique.Add(disposer))
  299. {
  300. continue;
  301. }
  302. IObjectSystem objectSystem;
  303. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out objectSystem))
  304. {
  305. continue;
  306. }
  307. this.updates2.Enqueue(disposer);
  308. IUpdate iUpdate = objectSystem as IUpdate;
  309. if (iUpdate == null)
  310. {
  311. continue;
  312. }
  313. objectSystem.Set(disposer);
  314. try
  315. {
  316. iUpdate.Update();
  317. }
  318. catch (Exception e)
  319. {
  320. Log.Error(e.ToString());
  321. }
  322. }
  323. ObjectHelper.Swap(ref this.updates, ref this.updates2);
  324. }
  325. public void LateUpdate()
  326. {
  327. this.unique.Clear();
  328. while (this.lateUpdates.Count > 0)
  329. {
  330. Disposer disposer = this.lateUpdates.Dequeue();
  331. if (disposer.Id == 0)
  332. {
  333. continue;
  334. }
  335. if (!this.unique.Add(disposer))
  336. {
  337. continue;
  338. }
  339. IObjectSystem objectSystem;
  340. if (!this.disposerEvents.TryGetValue(disposer.GetType(), out objectSystem))
  341. {
  342. continue;
  343. }
  344. this.lateUpdates2.Enqueue(disposer);
  345. ILateUpdate iLateUpdate = objectSystem as ILateUpdate;
  346. if (iLateUpdate == null)
  347. {
  348. continue;
  349. }
  350. objectSystem.Set(disposer);
  351. try
  352. {
  353. iLateUpdate.LateUpdate();
  354. }
  355. catch (Exception e)
  356. {
  357. Log.Error(e.ToString());
  358. }
  359. }
  360. ObjectHelper.Swap(ref this.lateUpdates, ref this.lateUpdates2);
  361. }
  362. public void Run(EventIdType type)
  363. {
  364. List<IEventMethod> iEvents;
  365. if (!this.allEvents.TryGetValue(type, out iEvents))
  366. {
  367. return;
  368. }
  369. foreach (IEventMethod iEvent in iEvents)
  370. {
  371. try
  372. {
  373. iEvent.Run();
  374. }
  375. catch (Exception e)
  376. {
  377. Log.Error(e.ToString());
  378. }
  379. }
  380. }
  381. public void Run<A>(EventIdType type, A a)
  382. {
  383. List<IEventMethod> iEvents;
  384. if (!this.allEvents.TryGetValue(type, out iEvents))
  385. {
  386. return;
  387. }
  388. foreach (IEventMethod iEvent in iEvents)
  389. {
  390. try
  391. {
  392. iEvent.Run(a);
  393. }
  394. catch (Exception e)
  395. {
  396. Log.Error(e.ToString());
  397. }
  398. }
  399. }
  400. public void Run<A, B>(EventIdType type, A a, B b)
  401. {
  402. List<IEventMethod> iEvents;
  403. if (!this.allEvents.TryGetValue(type, out iEvents))
  404. {
  405. return;
  406. }
  407. foreach (IEventMethod iEvent in iEvents)
  408. {
  409. try
  410. {
  411. iEvent.Run(a, b);
  412. }
  413. catch (Exception e)
  414. {
  415. Log.Error(e.ToString());
  416. }
  417. }
  418. }
  419. public void Run<A, B, C>(EventIdType type, A a, B b, C c)
  420. {
  421. List<IEventMethod> iEvents;
  422. if (!this.allEvents.TryGetValue(type, out iEvents))
  423. {
  424. return;
  425. }
  426. foreach (IEventMethod iEvent in iEvents)
  427. {
  428. try
  429. {
  430. iEvent.Run(a, b, c);
  431. }
  432. catch (Exception e)
  433. {
  434. Log.Error(e.ToString());
  435. }
  436. }
  437. }
  438. }
  439. }