EventDispatcher.cs 16 KB

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