ExecuteEvents.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine.UI;
  4. namespace UnityEngine.EventSystems
  5. {
  6. public static class ExecuteEvents
  7. {
  8. public delegate void EventFunction<T1>(T1 handler, BaseEventData eventData);
  9. public static T ValidateEventData<T>(BaseEventData data) where T : class
  10. {
  11. if ((data as T) == null)
  12. throw new ArgumentException(String.Format("Invalid type: {0} passed to event expecting {1}", data.GetType(), typeof(T)));
  13. return data as T;
  14. }
  15. private static readonly EventFunction<IPointerEnterHandler> s_PointerEnterHandler = Execute;
  16. private static void Execute(IPointerEnterHandler handler, BaseEventData eventData)
  17. {
  18. handler.OnPointerEnter(ValidateEventData<PointerEventData>(eventData));
  19. }
  20. private static readonly EventFunction<IPointerExitHandler> s_PointerExitHandler = Execute;
  21. private static void Execute(IPointerExitHandler handler, BaseEventData eventData)
  22. {
  23. handler.OnPointerExit(ValidateEventData<PointerEventData>(eventData));
  24. }
  25. private static readonly EventFunction<IPointerDownHandler> s_PointerDownHandler = Execute;
  26. private static void Execute(IPointerDownHandler handler, BaseEventData eventData)
  27. {
  28. handler.OnPointerDown(ValidateEventData<PointerEventData>(eventData));
  29. }
  30. private static readonly EventFunction<IPointerUpHandler> s_PointerUpHandler = Execute;
  31. private static void Execute(IPointerUpHandler handler, BaseEventData eventData)
  32. {
  33. handler.OnPointerUp(ValidateEventData<PointerEventData>(eventData));
  34. }
  35. private static readonly EventFunction<IPointerClickHandler> s_PointerClickHandler = Execute;
  36. private static void Execute(IPointerClickHandler handler, BaseEventData eventData)
  37. {
  38. handler.OnPointerClick(ValidateEventData<PointerEventData>(eventData));
  39. }
  40. private static readonly EventFunction<IInitializePotentialDragHandler> s_InitializePotentialDragHandler = Execute;
  41. private static void Execute(IInitializePotentialDragHandler handler, BaseEventData eventData)
  42. {
  43. handler.OnInitializePotentialDrag(ValidateEventData<PointerEventData>(eventData));
  44. }
  45. private static readonly EventFunction<IBeginDragHandler> s_BeginDragHandler = Execute;
  46. private static void Execute(IBeginDragHandler handler, BaseEventData eventData)
  47. {
  48. handler.OnBeginDrag(ValidateEventData<PointerEventData>(eventData));
  49. }
  50. private static readonly EventFunction<IDragHandler> s_DragHandler = Execute;
  51. private static void Execute(IDragHandler handler, BaseEventData eventData)
  52. {
  53. handler.OnDrag(ValidateEventData<PointerEventData>(eventData));
  54. }
  55. private static readonly EventFunction<IEndDragHandler> s_EndDragHandler = Execute;
  56. private static void Execute(IEndDragHandler handler, BaseEventData eventData)
  57. {
  58. handler.OnEndDrag(ValidateEventData<PointerEventData>(eventData));
  59. }
  60. private static readonly EventFunction<IDropHandler> s_DropHandler = Execute;
  61. private static void Execute(IDropHandler handler, BaseEventData eventData)
  62. {
  63. handler.OnDrop(ValidateEventData<PointerEventData>(eventData));
  64. }
  65. private static readonly EventFunction<IScrollHandler> s_ScrollHandler = Execute;
  66. private static void Execute(IScrollHandler handler, BaseEventData eventData)
  67. {
  68. handler.OnScroll(ValidateEventData<PointerEventData>(eventData));
  69. }
  70. private static readonly EventFunction<IUpdateSelectedHandler> s_UpdateSelectedHandler = Execute;
  71. private static void Execute(IUpdateSelectedHandler handler, BaseEventData eventData)
  72. {
  73. handler.OnUpdateSelected(eventData);
  74. }
  75. private static readonly EventFunction<ISelectHandler> s_SelectHandler = Execute;
  76. private static void Execute(ISelectHandler handler, BaseEventData eventData)
  77. {
  78. handler.OnSelect(eventData);
  79. }
  80. private static readonly EventFunction<IDeselectHandler> s_DeselectHandler = Execute;
  81. private static void Execute(IDeselectHandler handler, BaseEventData eventData)
  82. {
  83. handler.OnDeselect(eventData);
  84. }
  85. private static readonly EventFunction<IMoveHandler> s_MoveHandler = Execute;
  86. private static void Execute(IMoveHandler handler, BaseEventData eventData)
  87. {
  88. handler.OnMove(ValidateEventData<AxisEventData>(eventData));
  89. }
  90. private static readonly EventFunction<ISubmitHandler> s_SubmitHandler = Execute;
  91. private static void Execute(ISubmitHandler handler, BaseEventData eventData)
  92. {
  93. handler.OnSubmit(eventData);
  94. }
  95. private static readonly EventFunction<ICancelHandler> s_CancelHandler = Execute;
  96. private static void Execute(ICancelHandler handler, BaseEventData eventData)
  97. {
  98. handler.OnCancel(eventData);
  99. }
  100. public static EventFunction<IPointerEnterHandler> pointerEnterHandler
  101. {
  102. get { return s_PointerEnterHandler; }
  103. }
  104. public static EventFunction<IPointerExitHandler> pointerExitHandler
  105. {
  106. get { return s_PointerExitHandler; }
  107. }
  108. public static EventFunction<IPointerDownHandler> pointerDownHandler
  109. {
  110. get { return s_PointerDownHandler; }
  111. }
  112. public static EventFunction<IPointerUpHandler> pointerUpHandler
  113. {
  114. get { return s_PointerUpHandler; }
  115. }
  116. public static EventFunction<IPointerClickHandler> pointerClickHandler
  117. {
  118. get { return s_PointerClickHandler; }
  119. }
  120. public static EventFunction<IInitializePotentialDragHandler> initializePotentialDrag
  121. {
  122. get { return s_InitializePotentialDragHandler; }
  123. }
  124. public static EventFunction<IBeginDragHandler> beginDragHandler
  125. {
  126. get { return s_BeginDragHandler; }
  127. }
  128. public static EventFunction<IDragHandler> dragHandler
  129. {
  130. get { return s_DragHandler; }
  131. }
  132. public static EventFunction<IEndDragHandler> endDragHandler
  133. {
  134. get { return s_EndDragHandler; }
  135. }
  136. public static EventFunction<IDropHandler> dropHandler
  137. {
  138. get { return s_DropHandler; }
  139. }
  140. public static EventFunction<IScrollHandler> scrollHandler
  141. {
  142. get { return s_ScrollHandler; }
  143. }
  144. public static EventFunction<IUpdateSelectedHandler> updateSelectedHandler
  145. {
  146. get { return s_UpdateSelectedHandler; }
  147. }
  148. public static EventFunction<ISelectHandler> selectHandler
  149. {
  150. get { return s_SelectHandler; }
  151. }
  152. public static EventFunction<IDeselectHandler> deselectHandler
  153. {
  154. get { return s_DeselectHandler; }
  155. }
  156. public static EventFunction<IMoveHandler> moveHandler
  157. {
  158. get { return s_MoveHandler; }
  159. }
  160. public static EventFunction<ISubmitHandler> submitHandler
  161. {
  162. get { return s_SubmitHandler; }
  163. }
  164. public static EventFunction<ICancelHandler> cancelHandler
  165. {
  166. get { return s_CancelHandler; }
  167. }
  168. private static void GetEventChain(GameObject root, IList<Transform> eventChain)
  169. {
  170. eventChain.Clear();
  171. if (root == null)
  172. return;
  173. var t = root.transform;
  174. while (t != null)
  175. {
  176. eventChain.Add(t);
  177. t = t.parent;
  178. }
  179. }
  180. private static readonly ObjectPool<List<IEventSystemHandler>> s_HandlerListPool = new ObjectPool<List<IEventSystemHandler>>(null, l => l.Clear());
  181. public static bool Execute<T>(GameObject target, BaseEventData eventData, EventFunction<T> functor) where T : IEventSystemHandler
  182. {
  183. var internalHandlers = s_HandlerListPool.Get();
  184. GetEventList<T>(target, internalHandlers);
  185. // if (s_InternalHandlers.Count > 0)
  186. // Debug.Log("Executinng " + typeof (T) + " on " + target);
  187. var internalHandlersCount = internalHandlers.Count;
  188. for (var i = 0; i < internalHandlersCount; i++)
  189. {
  190. T arg;
  191. try
  192. {
  193. arg = (T)internalHandlers[i];
  194. }
  195. catch (Exception e)
  196. {
  197. var temp = internalHandlers[i];
  198. Debug.LogException(new Exception(string.Format("Type {0} expected {1} received.", typeof(T).Name, temp.GetType().Name), e));
  199. continue;
  200. }
  201. try
  202. {
  203. functor(arg, eventData);
  204. }
  205. catch (Exception e)
  206. {
  207. Debug.LogException(e);
  208. }
  209. }
  210. var handlerCount = internalHandlers.Count;
  211. s_HandlerListPool.Release(internalHandlers);
  212. return handlerCount > 0;
  213. }
  214. /// <summary>
  215. /// Execute the specified event on the first game object underneath the current touch.
  216. /// </summary>
  217. private static readonly List<Transform> s_InternalTransformList = new List<Transform>(30);
  218. public static GameObject ExecuteHierarchy<T>(GameObject root, BaseEventData eventData, EventFunction<T> callbackFunction) where T : IEventSystemHandler
  219. {
  220. GetEventChain(root, s_InternalTransformList);
  221. var internalTransformListCount = s_InternalTransformList.Count;
  222. for (var i = 0; i < internalTransformListCount; i++)
  223. {
  224. var transform = s_InternalTransformList[i];
  225. if (Execute(transform.gameObject, eventData, callbackFunction))
  226. return transform.gameObject;
  227. }
  228. return null;
  229. }
  230. private static bool ShouldSendToComponent<T>(Component component) where T : IEventSystemHandler
  231. {
  232. var valid = component is T;
  233. if (!valid)
  234. return false;
  235. var behaviour = component as Behaviour;
  236. if (behaviour != null)
  237. return behaviour.isActiveAndEnabled;
  238. return true;
  239. }
  240. /// <summary>
  241. /// Get the specified object's event event.
  242. /// </summary>
  243. private static void GetEventList<T>(GameObject go, IList<IEventSystemHandler> results) where T : IEventSystemHandler
  244. {
  245. // Debug.LogWarning("GetEventList<" + typeof(T).Name + ">");
  246. if (results == null)
  247. throw new ArgumentException("Results array is null", "results");
  248. if (go == null || !go.activeInHierarchy)
  249. return;
  250. var components = ListPool<Component>.Get();
  251. go.GetComponents(components);
  252. var componentsCount = components.Count;
  253. for (var i = 0; i < componentsCount; i++)
  254. {
  255. if (!ShouldSendToComponent<T>(components[i]))
  256. continue;
  257. // Debug.Log(string.Format("{2} found! On {0}.{1}", go, s_GetComponentsScratch[i].GetType(), typeof(T)));
  258. results.Add(components[i] as IEventSystemHandler);
  259. }
  260. ListPool<Component>.Release(components);
  261. // Debug.LogWarning("end GetEventList<" + typeof(T).Name + ">");
  262. }
  263. /// <summary>
  264. /// Whether the specified game object will be able to handle the specified event.
  265. /// </summary>
  266. public static bool CanHandleEvent<T>(GameObject go) where T : IEventSystemHandler
  267. {
  268. var internalHandlers = s_HandlerListPool.Get();
  269. GetEventList<T>(go, internalHandlers);
  270. var handlerCount = internalHandlers.Count;
  271. s_HandlerListPool.Release(internalHandlers);
  272. return handlerCount != 0;
  273. }
  274. /// <summary>
  275. /// Bubble the specified event on the game object, figuring out which object will actually receive the event.
  276. /// </summary>
  277. public static GameObject GetEventHandler<T>(GameObject root) where T : IEventSystemHandler
  278. {
  279. if (root == null)
  280. return null;
  281. Transform t = root.transform;
  282. while (t != null)
  283. {
  284. if (CanHandleEvent<T>(t.gameObject))
  285. return t.gameObject;
  286. t = t.parent;
  287. }
  288. return null;
  289. }
  290. }
  291. }