EventDispatcher.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace FairyGUI
  5. {
  6. public delegate void EventCallback0();
  7. public delegate void EventCallback1(EventContext context);
  8. /// <summary>
  9. ///
  10. /// </summary>
  11. public class EventDispatcher : IEventDispatcher
  12. {
  13. Dictionary<string, EventBridge> _dic;
  14. public EventDispatcher()
  15. {
  16. }
  17. /// <summary>
  18. ///
  19. /// </summary>
  20. /// <param name="strType"></param>
  21. /// <param name="callback"></param>
  22. public void AddEventListener(string strType, EventCallback1 callback)
  23. {
  24. GetBridge(strType).Add(callback);
  25. }
  26. /// <summary>
  27. ///
  28. /// </summary>
  29. /// <param name="strType"></param>
  30. /// <param name="callback"></param>
  31. public void AddEventListener(string strType, EventCallback0 callback)
  32. {
  33. GetBridge(strType).Add(callback);
  34. }
  35. /// <summary>
  36. ///
  37. /// </summary>
  38. /// <param name="strType"></param>
  39. /// <param name="callback"></param>
  40. public void RemoveEventListener(string strType, EventCallback1 callback)
  41. {
  42. if (_dic == null)
  43. return;
  44. EventBridge bridge = null;
  45. if (_dic.TryGetValue(strType, out bridge))
  46. bridge.Remove(callback);
  47. }
  48. /// <summary>
  49. ///
  50. /// </summary>
  51. /// <param name="strType"></param>
  52. /// <param name="callback"></param>
  53. public void RemoveEventListener(string strType, EventCallback0 callback)
  54. {
  55. if (_dic == null)
  56. return;
  57. EventBridge bridge = null;
  58. if (_dic.TryGetValue(strType, out bridge))
  59. bridge.Remove(callback);
  60. }
  61. /// <summary>
  62. ///
  63. /// </summary>
  64. /// <param name="strType"></param>
  65. /// <param name="callback"></param>
  66. public void AddCapture(string strType, EventCallback1 callback)
  67. {
  68. GetBridge(strType).AddCapture(callback);
  69. }
  70. /// <summary>
  71. ///
  72. /// </summary>
  73. /// <param name="strType"></param>
  74. /// <param name="callback"></param>
  75. public void RemoveCapture(string strType, EventCallback1 callback)
  76. {
  77. if (_dic == null)
  78. return;
  79. EventBridge bridge = null;
  80. if (_dic.TryGetValue(strType, out bridge))
  81. bridge.RemoveCapture(callback);
  82. }
  83. /// <summary>
  84. ///
  85. /// </summary>
  86. public void RemoveEventListeners()
  87. {
  88. RemoveEventListeners(null);
  89. }
  90. /// <summary>
  91. ///
  92. /// </summary>
  93. /// <param name="strType"></param>
  94. public void RemoveEventListeners(string strType)
  95. {
  96. if (_dic == null)
  97. return;
  98. if (strType != null)
  99. {
  100. EventBridge bridge;
  101. if (_dic.TryGetValue(strType, out bridge))
  102. bridge.Clear();
  103. }
  104. else
  105. {
  106. foreach (KeyValuePair<string, EventBridge> kv in _dic)
  107. kv.Value.Clear();
  108. }
  109. }
  110. /// <summary>
  111. ///
  112. /// </summary>
  113. /// <param name="strType"></param>
  114. /// <returns></returns>
  115. public bool hasEventListeners(string strType)
  116. {
  117. EventBridge bridge = TryGetEventBridge(strType);
  118. if (bridge == null)
  119. return false;
  120. return !bridge.isEmpty;
  121. }
  122. /// <summary>
  123. ///
  124. /// </summary>
  125. /// <param name="strType"></param>
  126. /// <returns></returns>
  127. public bool isDispatching(string strType)
  128. {
  129. EventBridge bridge = TryGetEventBridge(strType);
  130. if (bridge == null)
  131. return false;
  132. return bridge._dispatching;
  133. }
  134. internal EventBridge TryGetEventBridge(string strType)
  135. {
  136. if (_dic == null)
  137. return null;
  138. EventBridge bridge = null;
  139. _dic.TryGetValue(strType, out bridge);
  140. return bridge;
  141. }
  142. internal EventBridge GetEventBridge(string strType)
  143. {
  144. if (_dic == null)
  145. _dic = new Dictionary<string, EventBridge>();
  146. EventBridge bridge = null;
  147. if (!_dic.TryGetValue(strType, out bridge))
  148. {
  149. bridge = new EventBridge(this);
  150. _dic[strType] = bridge;
  151. }
  152. return bridge;
  153. }
  154. /// <summary>
  155. ///
  156. /// </summary>
  157. /// <param name="strType"></param>
  158. /// <returns></returns>
  159. public bool DispatchEvent(string strType)
  160. {
  161. return DispatchEvent(strType, null);
  162. }
  163. /// <summary>
  164. ///
  165. /// </summary>
  166. /// <param name="strType"></param>
  167. /// <param name="data"></param>
  168. /// <returns></returns>
  169. public bool DispatchEvent(string strType, object data)
  170. {
  171. return InternalDispatchEvent(strType, null, data, null);
  172. }
  173. public bool DispatchEvent(string strType, object data, object initiator)
  174. {
  175. return InternalDispatchEvent(strType, null, data, initiator);
  176. }
  177. static InputEvent sCurrentInputEvent = new InputEvent();
  178. internal bool InternalDispatchEvent(string strType, EventBridge bridge, object data, object initiator)
  179. {
  180. Debug.Log($"正在初始化 InternalDispatchEvent 1");
  181. if (bridge == null)
  182. bridge = TryGetEventBridge(strType);
  183. Debug.Log($"正在初始化 InternalDispatchEvent 2");
  184. EventBridge gBridge = null;
  185. if ((this is DisplayObject) && ((DisplayObject)this).gOwner != null)
  186. gBridge = ((DisplayObject)this).gOwner.TryGetEventBridge(strType);
  187. Debug.Log($"正在初始化 InternalDispatchEvent 3");
  188. bool b1 = bridge != null && !bridge.isEmpty;
  189. bool b2 = gBridge != null && !gBridge.isEmpty;
  190. if (b1 || b2)
  191. {
  192. Debug.Log($"正在初始化 InternalDispatchEvent 44");
  193. EventContext context = EventContext.Get();
  194. context.initiator = initiator != null ? initiator : this;
  195. context.type = strType;
  196. context.data = data;
  197. Debug.Log($"正在初始化 InternalDispatchEvent 4");
  198. if (data is InputEvent)
  199. sCurrentInputEvent = (InputEvent)data;
  200. context.inputEvent = sCurrentInputEvent;
  201. if (b1)
  202. {
  203. bridge.CallCaptureInternal(context);
  204. bridge.CallInternal(context);
  205. }
  206. if (b2)
  207. {
  208. gBridge.CallCaptureInternal(context);
  209. gBridge.CallInternal(context);
  210. }
  211. Debug.Log($"正在初始化 InternalDispatchEvent 5");
  212. EventContext.Return(context);
  213. context.initiator = null;
  214. context.sender = null;
  215. context.data = null;
  216. Debug.Log($"正在初始化 InternalDispatchEvent 6");
  217. return context._defaultPrevented;
  218. }
  219. else
  220. return false;
  221. }
  222. /// <summary>
  223. ///
  224. /// </summary>
  225. /// <param name="context"></param>
  226. /// <returns></returns>
  227. public bool DispatchEvent(EventContext context)
  228. {
  229. EventBridge bridge = TryGetEventBridge(context.type);
  230. EventBridge gBridge = null;
  231. if ((this is DisplayObject) && ((DisplayObject)this).gOwner != null)
  232. gBridge = ((DisplayObject)this).gOwner.TryGetEventBridge(context.type);
  233. EventDispatcher savedSender = context.sender;
  234. if (bridge != null && !bridge.isEmpty)
  235. {
  236. bridge.CallCaptureInternal(context);
  237. bridge.CallInternal(context);
  238. }
  239. if (gBridge != null && !gBridge.isEmpty)
  240. {
  241. gBridge.CallCaptureInternal(context);
  242. gBridge.CallInternal(context);
  243. }
  244. context.sender = savedSender;
  245. return context._defaultPrevented;
  246. }
  247. /// <summary>
  248. ///
  249. /// </summary>
  250. /// <param name="strType"></param>
  251. /// <param name="data"></param>
  252. /// <param name="addChain"></param>
  253. /// <returns></returns>
  254. internal bool BubbleEvent(string strType, object data, List<EventBridge> addChain)
  255. {
  256. EventContext context = EventContext.Get();
  257. context.initiator = this;
  258. context.type = strType;
  259. context.data = data;
  260. if (data is InputEvent)
  261. sCurrentInputEvent = (InputEvent)data;
  262. context.inputEvent = sCurrentInputEvent;
  263. List<EventBridge> bubbleChain = context.callChain;
  264. bubbleChain.Clear();
  265. GetChainBridges(strType, bubbleChain, true);
  266. int length = bubbleChain.Count;
  267. for (int i = length - 1; i >= 0; i--)
  268. {
  269. bubbleChain[i].CallCaptureInternal(context);
  270. if (context._touchCapture)
  271. {
  272. context._touchCapture = false;
  273. if (strType == "onTouchBegin")
  274. Stage.inst.AddTouchMonitor(context.inputEvent.touchId, bubbleChain[i].owner);
  275. }
  276. }
  277. if (!context._stopsPropagation)
  278. {
  279. for (int i = 0; i < length; ++i)
  280. {
  281. bubbleChain[i].CallInternal(context);
  282. if (context._touchCapture)
  283. {
  284. context._touchCapture = false;
  285. if (strType == "onTouchBegin")
  286. Stage.inst.AddTouchMonitor(context.inputEvent.touchId, bubbleChain[i].owner);
  287. }
  288. if (context._stopsPropagation)
  289. break;
  290. }
  291. if (addChain != null)
  292. {
  293. length = addChain.Count;
  294. for (int i = 0; i < length; ++i)
  295. {
  296. EventBridge bridge = addChain[i];
  297. if (bubbleChain.IndexOf(bridge) == -1)
  298. {
  299. bridge.CallCaptureInternal(context);
  300. bridge.CallInternal(context);
  301. }
  302. }
  303. }
  304. }
  305. EventContext.Return(context);
  306. context.initiator = null;
  307. context.sender = null;
  308. context.data = null;
  309. return context._defaultPrevented;
  310. }
  311. /// <summary>
  312. ///
  313. /// </summary>
  314. /// <param name="strType"></param>
  315. /// <param name="data"></param>
  316. /// <returns></returns>
  317. public bool BubbleEvent(string strType, object data)
  318. {
  319. return BubbleEvent(strType, data, null);
  320. }
  321. /// <summary>
  322. ///
  323. /// </summary>
  324. /// <param name="strType"></param>
  325. /// <param name="data"></param>
  326. /// <returns></returns>
  327. public bool BroadcastEvent(string strType, object data)
  328. {
  329. EventContext context = EventContext.Get();
  330. context.initiator = this;
  331. context.type = strType;
  332. context.data = data;
  333. if (data is InputEvent)
  334. sCurrentInputEvent = (InputEvent)data;
  335. context.inputEvent = sCurrentInputEvent;
  336. List<EventBridge> bubbleChain = context.callChain;
  337. bubbleChain.Clear();
  338. if (this is Container)
  339. GetChildEventBridges(strType, (Container)this, bubbleChain);
  340. else if (this is GComponent)
  341. GetChildEventBridges(strType, (GComponent)this, bubbleChain);
  342. int length = bubbleChain.Count;
  343. for (int i = 0; i < length; ++i)
  344. bubbleChain[i].CallInternal(context);
  345. EventContext.Return(context);
  346. context.initiator = null;
  347. context.sender = null;
  348. context.data = null;
  349. return context._defaultPrevented;
  350. }
  351. EventBridge GetBridge(string strType)
  352. {
  353. if (strType == null)
  354. throw new Exception("event type cant be null");
  355. if (_dic == null)
  356. _dic = new Dictionary<string, EventBridge>();
  357. EventBridge bridge = null;
  358. if (!_dic.TryGetValue(strType, out bridge))
  359. {
  360. bridge = new EventBridge(this);
  361. _dic[strType] = bridge;
  362. }
  363. return bridge;
  364. }
  365. static void GetChildEventBridges(string strType, Container container, List<EventBridge> bridges)
  366. {
  367. EventBridge bridge = container.TryGetEventBridge(strType);
  368. if (bridge != null)
  369. bridges.Add(bridge);
  370. if (container.gOwner != null)
  371. {
  372. bridge = container.gOwner.TryGetEventBridge(strType);
  373. if (bridge != null && !bridge.isEmpty)
  374. bridges.Add(bridge);
  375. }
  376. int count = container.numChildren;
  377. for (int i = 0; i < count; ++i)
  378. {
  379. DisplayObject obj = container.GetChildAt(i);
  380. if (obj is Container)
  381. GetChildEventBridges(strType, (Container)obj, bridges);
  382. else
  383. {
  384. bridge = obj.TryGetEventBridge(strType);
  385. if (bridge != null && !bridge.isEmpty)
  386. bridges.Add(bridge);
  387. if (obj.gOwner != null)
  388. {
  389. bridge = obj.gOwner.TryGetEventBridge(strType);
  390. if (bridge != null && !bridge.isEmpty)
  391. bridges.Add(bridge);
  392. }
  393. }
  394. }
  395. }
  396. static void GetChildEventBridges(string strType, GComponent container, List<EventBridge> bridges)
  397. {
  398. EventBridge bridge = container.TryGetEventBridge(strType);
  399. if (bridge != null)
  400. bridges.Add(bridge);
  401. int count = container.numChildren;
  402. for (int i = 0; i < count; ++i)
  403. {
  404. GObject obj = container.GetChildAt(i);
  405. if (obj is GComponent)
  406. GetChildEventBridges(strType, (GComponent)obj, bridges);
  407. else
  408. {
  409. bridge = obj.TryGetEventBridge(strType);
  410. if (bridge != null)
  411. bridges.Add(bridge);
  412. }
  413. }
  414. }
  415. internal void GetChainBridges(string strType, List<EventBridge> chain, bool bubble)
  416. {
  417. EventBridge bridge = TryGetEventBridge(strType);
  418. if (bridge != null && !bridge.isEmpty)
  419. chain.Add(bridge);
  420. if ((this is DisplayObject) && ((DisplayObject)this).gOwner != null)
  421. {
  422. bridge = ((DisplayObject)this).gOwner.TryGetEventBridge(strType);
  423. if (bridge != null && !bridge.isEmpty)
  424. chain.Add(bridge);
  425. }
  426. if (!bubble)
  427. return;
  428. if (this is DisplayObject)
  429. {
  430. DisplayObject element = (DisplayObject)this;
  431. while ((element = element.parent) != null)
  432. {
  433. bridge = element.TryGetEventBridge(strType);
  434. if (bridge != null && !bridge.isEmpty)
  435. chain.Add(bridge);
  436. if (element.gOwner != null)
  437. {
  438. bridge = element.gOwner.TryGetEventBridge(strType);
  439. if (bridge != null && !bridge.isEmpty)
  440. chain.Add(bridge);
  441. }
  442. }
  443. }
  444. else if (this is GObject)
  445. {
  446. GObject element = (GObject)this;
  447. while ((element = element.parent) != null)
  448. {
  449. bridge = element.TryGetEventBridge(strType);
  450. if (bridge != null && !bridge.isEmpty)
  451. chain.Add(bridge);
  452. }
  453. }
  454. }
  455. }
  456. }