ObjectManager.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Text;
  6. namespace Base
  7. {
  8. public interface IObjectEvent
  9. {
  10. Type ValueType();
  11. void SetValue(object value);
  12. }
  13. public abstract class ObjectEvent<T> : IObjectEvent
  14. {
  15. private T value;
  16. protected T GetValue()
  17. {
  18. return value;
  19. }
  20. public void SetValue(object v)
  21. {
  22. this.value = (T)v;
  23. }
  24. public Type ValueType()
  25. {
  26. return typeof(T);
  27. }
  28. }
  29. public class ObjectManager : IDisposable
  30. {
  31. private readonly Dictionary<string, Assembly> assemblies = new Dictionary<string, Assembly>();
  32. private Dictionary<Type, IObjectEvent> objectEvents;
  33. private readonly Dictionary<long, Object> objects = new Dictionary<long, Object>();
  34. private List<long> starts = new List<long>();
  35. private List<long> newStarts = new List<long>();
  36. private List<long> updates = new List<long>(3000);
  37. private List<long> newUpdates = new List<long>(3000);
  38. private readonly List<long> loaders = new List<long>();
  39. public void Dispose()
  40. {
  41. foreach (Object o in this.objects.Values.ToArray())
  42. {
  43. o.Dispose();
  44. }
  45. }
  46. public void Register(string name, Assembly assembly)
  47. {
  48. this.assemblies[name] = assembly;
  49. objectEvents = new Dictionary<Type, IObjectEvent>();
  50. foreach (Assembly ass in this.assemblies.Values)
  51. {
  52. Type[] types = ass.GetTypes();
  53. foreach (Type type in types)
  54. {
  55. object[] attrs = type.GetCustomAttributes(typeof(ObjectEventAttribute), false);
  56. if (attrs.Length == 0)
  57. {
  58. continue;
  59. }
  60. object obj = Activator.CreateInstance(type);
  61. IObjectEvent objectEvent = obj as IObjectEvent;
  62. if (objectEvent == null)
  63. {
  64. Log.Error($"组件事件没有继承IComponentEvent: {type.Name}");
  65. }
  66. objectEvents[objectEvent.ValueType()] = objectEvent;
  67. }
  68. }
  69. this.Load();
  70. }
  71. public Assembly GetAssembly(string name)
  72. {
  73. return this.assemblies[name];
  74. }
  75. public Assembly[] GetAssemblies()
  76. {
  77. return this.assemblies.Values.ToArray();
  78. }
  79. private void Load()
  80. {
  81. foreach (long id in this.loaders)
  82. {
  83. Object obj;
  84. if (!this.objects.TryGetValue(id, out obj))
  85. {
  86. continue;
  87. }
  88. IObjectEvent objectEvent;
  89. if (!objectEvents.TryGetValue(obj.GetType(), out objectEvent))
  90. {
  91. continue;
  92. }
  93. ILoader iLoader = objectEvent as ILoader;
  94. if (iLoader == null)
  95. {
  96. continue;
  97. }
  98. objectEvent.SetValue(obj);
  99. iLoader.Load();
  100. }
  101. }
  102. public void Add(Object obj)
  103. {
  104. if (objectEvents == null)
  105. {
  106. return;
  107. }
  108. this.objects.Add(obj.Id, obj);
  109. IObjectEvent objectEvent;
  110. if (!objectEvents.TryGetValue(obj.GetType(), out objectEvent))
  111. {
  112. return;
  113. }
  114. IStart iStart = objectEvent as IStart;
  115. if (iStart != null)
  116. {
  117. this.newStarts.Add(obj.Id);
  118. }
  119. IUpdate iUpdate = objectEvent as IUpdate;
  120. if (iUpdate != null)
  121. {
  122. this.newUpdates.Add(obj.Id);
  123. }
  124. ILoader iLoader = objectEvent as ILoader;
  125. if (iLoader != null)
  126. {
  127. this.loaders.Add(obj.Id);
  128. }
  129. }
  130. public void Remove(long id)
  131. {
  132. this.objects.Remove(id);
  133. }
  134. public void Open(long id)
  135. {
  136. Object obj;
  137. if (!objects.TryGetValue(id, out obj))
  138. {
  139. return;
  140. }
  141. IObjectEvent e;
  142. if (!objectEvents.TryGetValue(obj.GetType(), out e))
  143. {
  144. return;
  145. }
  146. IOpen open = e as IOpen;
  147. if (open == null)
  148. {
  149. return;
  150. }
  151. try
  152. {
  153. e.SetValue(obj);
  154. open.Open();
  155. }
  156. catch (Exception exc)
  157. {
  158. Log.Error(exc.ToString());
  159. }
  160. }
  161. public void Close(long id)
  162. {
  163. Object obj;
  164. if (!objects.TryGetValue(id, out obj))
  165. {
  166. return;
  167. }
  168. IObjectEvent e;
  169. if (!objectEvents.TryGetValue(obj.GetType(), out e))
  170. {
  171. return;
  172. }
  173. IClose close = e as IClose;
  174. if (close == null)
  175. {
  176. return;
  177. }
  178. try
  179. {
  180. e.SetValue(obj);
  181. close.Close();
  182. }
  183. catch (Exception exc)
  184. {
  185. Log.Error(exc.ToString());
  186. }
  187. }
  188. public void Awake(long id)
  189. {
  190. Object obj;
  191. if (!objects.TryGetValue(id, out obj))
  192. {
  193. return;
  194. }
  195. IObjectEvent objectEvent;
  196. if (!objectEvents.TryGetValue(obj.GetType(), out objectEvent))
  197. {
  198. return;
  199. }
  200. IAwake iAwake = objectEvent as IAwake;
  201. if (iAwake == null)
  202. {
  203. return;
  204. }
  205. objectEvent.SetValue(obj);
  206. iAwake.Awake();
  207. }
  208. public void Awake<P1>(long id, P1 p1)
  209. {
  210. Object obj;
  211. if (!objects.TryGetValue(id, out obj))
  212. {
  213. return;
  214. }
  215. IObjectEvent objectEvent;
  216. if (!objectEvents.TryGetValue(obj.GetType(), out objectEvent))
  217. {
  218. return;
  219. }
  220. IAwake<P1> iAwake = objectEvent as IAwake<P1>;
  221. if (iAwake == null)
  222. {
  223. return;
  224. }
  225. objectEvent.SetValue(obj);
  226. iAwake.Awake(p1);
  227. }
  228. public void Awake<P1, P2>(long id, P1 p1, P2 p2)
  229. {
  230. Object obj;
  231. if (!objects.TryGetValue(id, out obj))
  232. {
  233. return;
  234. }
  235. IObjectEvent objectEvent;
  236. if (!objectEvents.TryGetValue(obj.GetType(), out objectEvent))
  237. {
  238. return;
  239. }
  240. IAwake<P1, P2> iAwake = objectEvent as IAwake<P1, P2>;
  241. if (iAwake == null)
  242. {
  243. return;
  244. }
  245. objectEvent.SetValue(obj);
  246. iAwake.Awake(p1, p2);
  247. }
  248. public void Awake<P1, P2, P3>(long id, P1 p1, P2 p2, P3 p3)
  249. {
  250. Object obj;
  251. if (!objects.TryGetValue(id, out obj))
  252. {
  253. return;
  254. }
  255. IObjectEvent objectEvent;
  256. if (!objectEvents.TryGetValue(obj.GetType(), out objectEvent))
  257. {
  258. return;
  259. }
  260. IAwake<P1, P2, P3> iAwake = objectEvent as IAwake<P1, P2, P3>;
  261. if (iAwake == null)
  262. {
  263. return;
  264. }
  265. objectEvent.SetValue(obj);
  266. iAwake.Awake(p1, p2, p3);
  267. }
  268. private void Start()
  269. {
  270. starts = newStarts;
  271. newStarts = new List<long>();
  272. foreach (long id in starts)
  273. {
  274. Object obj;
  275. if (!this.objects.TryGetValue(id, out obj))
  276. {
  277. continue;
  278. }
  279. IObjectEvent objectEvent;
  280. if (!objectEvents.TryGetValue(obj.GetType(), out objectEvent))
  281. {
  282. continue;
  283. }
  284. IStart iStart = objectEvent as IStart;
  285. if (iStart == null)
  286. {
  287. continue;
  288. }
  289. objectEvent.SetValue(obj);
  290. iStart.Start();
  291. }
  292. }
  293. public void Update()
  294. {
  295. this.Start();
  296. // 交换update
  297. List<long> tmpUpdate = updates;
  298. updates = newUpdates;
  299. newUpdates = tmpUpdate;
  300. newUpdates.Clear();
  301. foreach (long id in updates)
  302. {
  303. Object obj;
  304. if (!objects.TryGetValue(id, out obj))
  305. {
  306. continue;
  307. }
  308. IObjectEvent objectEvent;
  309. if (!objectEvents.TryGetValue(obj.GetType(), out objectEvent))
  310. {
  311. continue;
  312. }
  313. IUpdate iUpdate = objectEvent as IUpdate;
  314. if (iUpdate == null)
  315. {
  316. continue;
  317. }
  318. newUpdates.Add(id);
  319. objectEvent.SetValue(obj);
  320. try
  321. {
  322. iUpdate.Update();
  323. }
  324. catch (Exception e)
  325. {
  326. Log.Error(e.ToString());
  327. }
  328. }
  329. }
  330. public override string ToString()
  331. {
  332. var info = new Dictionary<string, int>();
  333. foreach (Object obj in objects.Values)
  334. {
  335. if (info.ContainsKey(obj.GetType().Name))
  336. {
  337. info[obj.GetType().Name] += 1;
  338. }
  339. else
  340. {
  341. info[obj.GetType().Name] = 1;
  342. }
  343. }
  344. info = info.OrderByDescending(s => s.Value).ToDictionary(p => p.Key, p => p.Value);
  345. StringBuilder sb = new StringBuilder();
  346. sb.Append("\r\n");
  347. foreach (string key in info.Keys)
  348. {
  349. sb.Append($"{info[key],10} {key}\r\n");
  350. }
  351. sb.Append($"\r\n start: {newStarts.Count}, update: {newUpdates.Count} total: {this.objects.Count}");
  352. return sb.ToString();
  353. }
  354. }
  355. }