EventDispatcher.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  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. if (bridge == null)
  181. bridge = TryGetEventBridge(strType);
  182. EventBridge gBridge = null;
  183. if ((this is DisplayObject) && ((DisplayObject)this).gOwner != null)
  184. gBridge = ((DisplayObject)this).gOwner.TryGetEventBridge(strType);
  185. bool b1 = bridge != null && !bridge.isEmpty;
  186. bool b2 = gBridge != null && !gBridge.isEmpty;
  187. if (b1 || b2)
  188. {
  189. EventContext context = EventContext.Get();
  190. context.initiator = initiator != null ? initiator : this;
  191. context.type = strType;
  192. context.data = data;
  193. if (data is InputEvent)
  194. sCurrentInputEvent = (InputEvent)data;
  195. context.inputEvent = sCurrentInputEvent;
  196. if (b1)
  197. {
  198. bridge.CallCaptureInternal(context);
  199. bridge.CallInternal(context);
  200. }
  201. if (b2)
  202. {
  203. gBridge.CallCaptureInternal(context);
  204. gBridge.CallInternal(context);
  205. }
  206. EventContext.Return(context);
  207. context.initiator = null;
  208. context.sender = null;
  209. context.data = null;
  210. return context._defaultPrevented;
  211. }
  212. else
  213. return false;
  214. }
  215. /// <summary>
  216. ///
  217. /// </summary>
  218. /// <param name="context"></param>
  219. /// <returns></returns>
  220. public bool DispatchEvent(EventContext context)
  221. {
  222. EventBridge bridge = TryGetEventBridge(context.type);
  223. EventBridge gBridge = null;
  224. if ((this is DisplayObject) && ((DisplayObject)this).gOwner != null)
  225. gBridge = ((DisplayObject)this).gOwner.TryGetEventBridge(context.type);
  226. EventDispatcher savedSender = context.sender;
  227. if (bridge != null && !bridge.isEmpty)
  228. {
  229. bridge.CallCaptureInternal(context);
  230. bridge.CallInternal(context);
  231. }
  232. if (gBridge != null && !gBridge.isEmpty)
  233. {
  234. gBridge.CallCaptureInternal(context);
  235. gBridge.CallInternal(context);
  236. }
  237. context.sender = savedSender;
  238. return context._defaultPrevented;
  239. }
  240. /// <summary>
  241. ///
  242. /// </summary>
  243. /// <param name="strType"></param>
  244. /// <param name="data"></param>
  245. /// <param name="addChain"></param>
  246. /// <returns></returns>
  247. internal bool BubbleEvent(string strType, object data, List<EventBridge> addChain)
  248. {
  249. EventContext context = EventContext.Get();
  250. context.initiator = this;
  251. context.type = strType;
  252. context.data = data;
  253. if (data is InputEvent)
  254. sCurrentInputEvent = (InputEvent)data;
  255. context.inputEvent = sCurrentInputEvent;
  256. List<EventBridge> bubbleChain = context.callChain;
  257. bubbleChain.Clear();
  258. GetChainBridges(strType, bubbleChain, true);
  259. int length = bubbleChain.Count;
  260. for (int i = length - 1; i >= 0; i--)
  261. {
  262. bubbleChain[i].CallCaptureInternal(context);
  263. if (context._touchCapture)
  264. {
  265. context._touchCapture = false;
  266. if (strType == "onTouchBegin")
  267. Stage.inst.AddTouchMonitor(context.inputEvent.touchId, bubbleChain[i].owner);
  268. }
  269. }
  270. if (!context._stopsPropagation)
  271. {
  272. for (int i = 0; i < length; ++i)
  273. {
  274. bubbleChain[i].CallInternal(context);
  275. if (context._touchCapture)
  276. {
  277. context._touchCapture = false;
  278. if (strType == "onTouchBegin")
  279. Stage.inst.AddTouchMonitor(context.inputEvent.touchId, bubbleChain[i].owner);
  280. }
  281. if (context._stopsPropagation)
  282. break;
  283. }
  284. if (addChain != null)
  285. {
  286. length = addChain.Count;
  287. for (int i = 0; i < length; ++i)
  288. {
  289. EventBridge bridge = addChain[i];
  290. if (bubbleChain.IndexOf(bridge) == -1)
  291. {
  292. bridge.CallCaptureInternal(context);
  293. bridge.CallInternal(context);
  294. }
  295. }
  296. }
  297. }
  298. EventContext.Return(context);
  299. context.initiator = null;
  300. context.sender = null;
  301. context.data = null;
  302. return context._defaultPrevented;
  303. }
  304. /// <summary>
  305. ///
  306. /// </summary>
  307. /// <param name="strType"></param>
  308. /// <param name="data"></param>
  309. /// <returns></returns>
  310. public bool BubbleEvent(string strType, object data)
  311. {
  312. return BubbleEvent(strType, data, null);
  313. }
  314. /// <summary>
  315. ///
  316. /// </summary>
  317. /// <param name="strType"></param>
  318. /// <param name="data"></param>
  319. /// <returns></returns>
  320. public bool BroadcastEvent(string strType, object data)
  321. {
  322. EventContext context = EventContext.Get();
  323. context.initiator = this;
  324. context.type = strType;
  325. context.data = data;
  326. if (data is InputEvent)
  327. sCurrentInputEvent = (InputEvent)data;
  328. context.inputEvent = sCurrentInputEvent;
  329. List<EventBridge> bubbleChain = context.callChain;
  330. bubbleChain.Clear();
  331. if (this is Container)
  332. GetChildEventBridges(strType, (Container)this, bubbleChain);
  333. else if (this is GComponent)
  334. GetChildEventBridges(strType, (GComponent)this, bubbleChain);
  335. int length = bubbleChain.Count;
  336. for (int i = 0; i < length; ++i)
  337. bubbleChain[i].CallInternal(context);
  338. EventContext.Return(context);
  339. context.initiator = null;
  340. context.sender = null;
  341. context.data = null;
  342. return context._defaultPrevented;
  343. }
  344. EventBridge GetBridge(string strType)
  345. {
  346. if (strType == null)
  347. throw new Exception("event type cant be null");
  348. if (_dic == null)
  349. _dic = new Dictionary<string, EventBridge>();
  350. EventBridge bridge = null;
  351. if (!_dic.TryGetValue(strType, out bridge))
  352. {
  353. bridge = new EventBridge(this);
  354. _dic[strType] = bridge;
  355. }
  356. return bridge;
  357. }
  358. static void GetChildEventBridges(string strType, Container container, List<EventBridge> bridges)
  359. {
  360. EventBridge bridge = container.TryGetEventBridge(strType);
  361. if (bridge != null)
  362. bridges.Add(bridge);
  363. if (container.gOwner != null)
  364. {
  365. bridge = container.gOwner.TryGetEventBridge(strType);
  366. if (bridge != null && !bridge.isEmpty)
  367. bridges.Add(bridge);
  368. }
  369. int count = container.numChildren;
  370. for (int i = 0; i < count; ++i)
  371. {
  372. DisplayObject obj = container.GetChildAt(i);
  373. if (obj is Container)
  374. GetChildEventBridges(strType, (Container)obj, bridges);
  375. else
  376. {
  377. bridge = obj.TryGetEventBridge(strType);
  378. if (bridge != null && !bridge.isEmpty)
  379. bridges.Add(bridge);
  380. if (obj.gOwner != null)
  381. {
  382. bridge = obj.gOwner.TryGetEventBridge(strType);
  383. if (bridge != null && !bridge.isEmpty)
  384. bridges.Add(bridge);
  385. }
  386. }
  387. }
  388. }
  389. static void GetChildEventBridges(string strType, GComponent container, List<EventBridge> bridges)
  390. {
  391. EventBridge bridge = container.TryGetEventBridge(strType);
  392. if (bridge != null)
  393. bridges.Add(bridge);
  394. int count = container.numChildren;
  395. for (int i = 0; i < count; ++i)
  396. {
  397. GObject obj = container.GetChildAt(i);
  398. if (obj is GComponent)
  399. GetChildEventBridges(strType, (GComponent)obj, bridges);
  400. else
  401. {
  402. bridge = obj.TryGetEventBridge(strType);
  403. if (bridge != null)
  404. bridges.Add(bridge);
  405. }
  406. }
  407. }
  408. internal void GetChainBridges(string strType, List<EventBridge> chain, bool bubble)
  409. {
  410. EventBridge bridge = TryGetEventBridge(strType);
  411. if (bridge != null && !bridge.isEmpty)
  412. chain.Add(bridge);
  413. if ((this is DisplayObject) && ((DisplayObject)this).gOwner != null)
  414. {
  415. bridge = ((DisplayObject)this).gOwner.TryGetEventBridge(strType);
  416. if (bridge != null && !bridge.isEmpty)
  417. chain.Add(bridge);
  418. }
  419. if (!bubble)
  420. return;
  421. if (this is DisplayObject)
  422. {
  423. DisplayObject element = (DisplayObject)this;
  424. while ((element = element.parent) != null)
  425. {
  426. bridge = element.TryGetEventBridge(strType);
  427. if (bridge != null && !bridge.isEmpty)
  428. chain.Add(bridge);
  429. if (element.gOwner != null)
  430. {
  431. bridge = element.gOwner.TryGetEventBridge(strType);
  432. if (bridge != null && !bridge.isEmpty)
  433. chain.Add(bridge);
  434. }
  435. }
  436. }
  437. else if (this is GObject)
  438. {
  439. GObject element = (GObject)this;
  440. while ((element = element.parent) != null)
  441. {
  442. bridge = element.TryGetEventBridge(strType);
  443. if (bridge != null && !bridge.isEmpty)
  444. chain.Add(bridge);
  445. }
  446. }
  447. }
  448. }
  449. }