375 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			375 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using System; | ||
|  | using System.Collections.Generic; | ||
|  | using UnityEngine.Pool; | ||
|  | 
 | ||
|  | namespace UnityEngine.EventSystems | ||
|  | { | ||
|  |     public static class ExecuteEvents | ||
|  |     { | ||
|  |         public delegate void EventFunction<T1>(T1 handler, BaseEventData eventData); | ||
|  | 
 | ||
|  |         public static T ValidateEventData<T>(BaseEventData data) where T : class | ||
|  |         { | ||
|  |             if ((data as T) == null) | ||
|  |                 throw new ArgumentException(String.Format("Invalid type: {0} passed to event expecting {1}", data.GetType(), typeof(T))); | ||
|  |             return data as T; | ||
|  |         } | ||
|  | 
 | ||
|  |         private static readonly EventFunction<IPointerMoveHandler> s_PointerMoveHandler = Execute; | ||
|  | 
 | ||
|  |         private static void Execute(IPointerMoveHandler handler, BaseEventData eventData) | ||
|  |         { | ||
|  |             handler.OnPointerMove(ValidateEventData<PointerEventData>(eventData)); | ||
|  |         } | ||
|  | 
 | ||
|  |         private static readonly EventFunction<IPointerEnterHandler> s_PointerEnterHandler = Execute; | ||
|  | 
 | ||
|  |         private static void Execute(IPointerEnterHandler handler, BaseEventData eventData) | ||
|  |         { | ||
|  |             handler.OnPointerEnter(ValidateEventData<PointerEventData>(eventData)); | ||
|  |         } | ||
|  | 
 | ||
|  |         private static readonly EventFunction<IPointerExitHandler> s_PointerExitHandler = Execute; | ||
|  | 
 | ||
|  |         private static void Execute(IPointerExitHandler handler, BaseEventData eventData) | ||
|  |         { | ||
|  |             handler.OnPointerExit(ValidateEventData<PointerEventData>(eventData)); | ||
|  |         } | ||
|  | 
 | ||
|  |         private static readonly EventFunction<IPointerDownHandler> s_PointerDownHandler = Execute; | ||
|  | 
 | ||
|  |         private static void Execute(IPointerDownHandler handler, BaseEventData eventData) | ||
|  |         { | ||
|  |             handler.OnPointerDown(ValidateEventData<PointerEventData>(eventData)); | ||
|  |         } | ||
|  | 
 | ||
|  |         private static readonly EventFunction<IPointerUpHandler> s_PointerUpHandler = Execute; | ||
|  | 
 | ||
|  |         private static void Execute(IPointerUpHandler handler, BaseEventData eventData) | ||
|  |         { | ||
|  |             handler.OnPointerUp(ValidateEventData<PointerEventData>(eventData)); | ||
|  |         } | ||
|  | 
 | ||
|  |         private static readonly EventFunction<IPointerClickHandler> s_PointerClickHandler = Execute; | ||
|  | 
 | ||
|  |         private static void Execute(IPointerClickHandler handler, BaseEventData eventData) | ||
|  |         { | ||
|  |             handler.OnPointerClick(ValidateEventData<PointerEventData>(eventData)); | ||
|  |         } | ||
|  | 
 | ||
|  |         private static readonly EventFunction<IInitializePotentialDragHandler> s_InitializePotentialDragHandler = Execute; | ||
|  | 
 | ||
|  |         private static void Execute(IInitializePotentialDragHandler handler, BaseEventData eventData) | ||
|  |         { | ||
|  |             handler.OnInitializePotentialDrag(ValidateEventData<PointerEventData>(eventData)); | ||
|  |         } | ||
|  | 
 | ||
|  |         private static readonly EventFunction<IBeginDragHandler> s_BeginDragHandler = Execute; | ||
|  | 
 | ||
|  |         private static void Execute(IBeginDragHandler handler, BaseEventData eventData) | ||
|  |         { | ||
|  |             handler.OnBeginDrag(ValidateEventData<PointerEventData>(eventData)); | ||
|  |         } | ||
|  | 
 | ||
|  |         private static readonly EventFunction<IDragHandler> s_DragHandler = Execute; | ||
|  | 
 | ||
|  |         private static void Execute(IDragHandler handler, BaseEventData eventData) | ||
|  |         { | ||
|  |             handler.OnDrag(ValidateEventData<PointerEventData>(eventData)); | ||
|  |         } | ||
|  | 
 | ||
|  |         private static readonly EventFunction<IEndDragHandler> s_EndDragHandler = Execute; | ||
|  | 
 | ||
|  |         private static void Execute(IEndDragHandler handler, BaseEventData eventData) | ||
|  |         { | ||
|  |             handler.OnEndDrag(ValidateEventData<PointerEventData>(eventData)); | ||
|  |         } | ||
|  | 
 | ||
|  |         private static readonly EventFunction<IDropHandler> s_DropHandler = Execute; | ||
|  | 
 | ||
|  |         private static void Execute(IDropHandler handler, BaseEventData eventData) | ||
|  |         { | ||
|  |             handler.OnDrop(ValidateEventData<PointerEventData>(eventData)); | ||
|  |         } | ||
|  | 
 | ||
|  |         private static readonly EventFunction<IScrollHandler> s_ScrollHandler = Execute; | ||
|  | 
 | ||
|  |         private static void Execute(IScrollHandler handler, BaseEventData eventData) | ||
|  |         { | ||
|  |             handler.OnScroll(ValidateEventData<PointerEventData>(eventData)); | ||
|  |         } | ||
|  | 
 | ||
|  |         private static readonly EventFunction<IUpdateSelectedHandler> s_UpdateSelectedHandler = Execute; | ||
|  | 
 | ||
|  |         private static void Execute(IUpdateSelectedHandler handler, BaseEventData eventData) | ||
|  |         { | ||
|  |             handler.OnUpdateSelected(eventData); | ||
|  |         } | ||
|  | 
 | ||
|  |         private static readonly EventFunction<ISelectHandler> s_SelectHandler = Execute; | ||
|  | 
 | ||
|  |         private static void Execute(ISelectHandler handler, BaseEventData eventData) | ||
|  |         { | ||
|  |             handler.OnSelect(eventData); | ||
|  |         } | ||
|  | 
 | ||
|  |         private static readonly EventFunction<IDeselectHandler> s_DeselectHandler = Execute; | ||
|  | 
 | ||
|  |         private static void Execute(IDeselectHandler handler, BaseEventData eventData) | ||
|  |         { | ||
|  |             handler.OnDeselect(eventData); | ||
|  |         } | ||
|  | 
 | ||
|  |         private static readonly EventFunction<IMoveHandler> s_MoveHandler = Execute; | ||
|  | 
 | ||
|  |         private static void Execute(IMoveHandler handler, BaseEventData eventData) | ||
|  |         { | ||
|  |             handler.OnMove(ValidateEventData<AxisEventData>(eventData)); | ||
|  |         } | ||
|  | 
 | ||
|  |         private static readonly EventFunction<ISubmitHandler> s_SubmitHandler = Execute; | ||
|  | 
 | ||
|  |         private static void Execute(ISubmitHandler handler, BaseEventData eventData) | ||
|  |         { | ||
|  |             handler.OnSubmit(eventData); | ||
|  |         } | ||
|  | 
 | ||
|  |         private static readonly EventFunction<ICancelHandler> s_CancelHandler = Execute; | ||
|  | 
 | ||
|  |         private static void Execute(ICancelHandler handler, BaseEventData eventData) | ||
|  |         { | ||
|  |             handler.OnCancel(eventData); | ||
|  |         } | ||
|  | 
 | ||
|  |         public static EventFunction<IPointerMoveHandler> pointerMoveHandler | ||
|  |         { | ||
|  |             get { return s_PointerMoveHandler; } | ||
|  |         } | ||
|  | 
 | ||
|  |         public static EventFunction<IPointerEnterHandler> pointerEnterHandler | ||
|  |         { | ||
|  |             get { return s_PointerEnterHandler; } | ||
|  |         } | ||
|  | 
 | ||
|  |         public static EventFunction<IPointerExitHandler> pointerExitHandler | ||
|  |         { | ||
|  |             get { return s_PointerExitHandler; } | ||
|  |         } | ||
|  | 
 | ||
|  |         public static EventFunction<IPointerDownHandler> pointerDownHandler | ||
|  |         { | ||
|  |             get { return s_PointerDownHandler; } | ||
|  |         } | ||
|  | 
 | ||
|  |         public static EventFunction<IPointerUpHandler> pointerUpHandler | ||
|  |         { | ||
|  |             get { return s_PointerUpHandler; } | ||
|  |         } | ||
|  | 
 | ||
|  |         public static EventFunction<IPointerClickHandler> pointerClickHandler | ||
|  |         { | ||
|  |             get { return s_PointerClickHandler; } | ||
|  |         } | ||
|  | 
 | ||
|  |         public static EventFunction<IInitializePotentialDragHandler> initializePotentialDrag | ||
|  |         { | ||
|  |             get { return s_InitializePotentialDragHandler; } | ||
|  |         } | ||
|  | 
 | ||
|  |         public static EventFunction<IBeginDragHandler> beginDragHandler | ||
|  |         { | ||
|  |             get { return s_BeginDragHandler; } | ||
|  |         } | ||
|  | 
 | ||
|  |         public static EventFunction<IDragHandler> dragHandler | ||
|  |         { | ||
|  |             get { return s_DragHandler; } | ||
|  |         } | ||
|  | 
 | ||
|  |         public static EventFunction<IEndDragHandler> endDragHandler | ||
|  |         { | ||
|  |             get { return s_EndDragHandler; } | ||
|  |         } | ||
|  | 
 | ||
|  |         public static EventFunction<IDropHandler> dropHandler | ||
|  |         { | ||
|  |             get { return s_DropHandler; } | ||
|  |         } | ||
|  | 
 | ||
|  |         public static EventFunction<IScrollHandler> scrollHandler | ||
|  |         { | ||
|  |             get { return s_ScrollHandler; } | ||
|  |         } | ||
|  | 
 | ||
|  |         public static EventFunction<IUpdateSelectedHandler> updateSelectedHandler | ||
|  |         { | ||
|  |             get { return s_UpdateSelectedHandler; } | ||
|  |         } | ||
|  | 
 | ||
|  |         public static EventFunction<ISelectHandler> selectHandler | ||
|  |         { | ||
|  |             get { return s_SelectHandler; } | ||
|  |         } | ||
|  | 
 | ||
|  |         public static EventFunction<IDeselectHandler> deselectHandler | ||
|  |         { | ||
|  |             get { return s_DeselectHandler; } | ||
|  |         } | ||
|  | 
 | ||
|  |         public static EventFunction<IMoveHandler> moveHandler | ||
|  |         { | ||
|  |             get { return s_MoveHandler; } | ||
|  |         } | ||
|  | 
 | ||
|  |         public static EventFunction<ISubmitHandler> submitHandler | ||
|  |         { | ||
|  |             get { return s_SubmitHandler; } | ||
|  |         } | ||
|  | 
 | ||
|  |         public static EventFunction<ICancelHandler> cancelHandler | ||
|  |         { | ||
|  |             get { return s_CancelHandler; } | ||
|  |         } | ||
|  | 
 | ||
|  |         private static void GetEventChain(GameObject root, IList<Transform> eventChain) | ||
|  |         { | ||
|  |             eventChain.Clear(); | ||
|  |             if (root == null) | ||
|  |                 return; | ||
|  | 
 | ||
|  |             var t = root.transform; | ||
|  |             while (t != null) | ||
|  |             { | ||
|  |                 eventChain.Add(t); | ||
|  |                 t = t.parent; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         public static bool Execute<T>(GameObject target, BaseEventData eventData, EventFunction<T> functor) where T : IEventSystemHandler | ||
|  |         { | ||
|  |             var internalHandlers = ListPool<IEventSystemHandler>.Get(); | ||
|  |             GetEventList<T>(target, internalHandlers); | ||
|  |             //  if (s_InternalHandlers.Count > 0) | ||
|  |             //      Debug.Log("Executinng " + typeof (T) + " on " + target); | ||
|  | 
 | ||
|  |             var internalHandlersCount = internalHandlers.Count; | ||
|  |             for (var i = 0; i < internalHandlersCount; i++) | ||
|  |             { | ||
|  |                 T arg; | ||
|  |                 try | ||
|  |                 { | ||
|  |                     arg = (T)internalHandlers[i]; | ||
|  |                 } | ||
|  |                 catch (Exception e) | ||
|  |                 { | ||
|  |                     var temp = internalHandlers[i]; | ||
|  |                     Debug.LogException(new Exception(string.Format("Type {0} expected {1} received.", typeof(T).Name, temp.GetType().Name), e)); | ||
|  |                     continue; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 try | ||
|  |                 { | ||
|  |                     functor(arg, eventData); | ||
|  |                 } | ||
|  |                 catch (Exception e) | ||
|  |                 { | ||
|  |                     Debug.LogException(e); | ||
|  |                 } | ||
|  |             } | ||
|  | 
 | ||
|  |             var handlerCount = internalHandlers.Count; | ||
|  |             ListPool<IEventSystemHandler>.Release(internalHandlers); | ||
|  |             return handlerCount > 0; | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Execute the specified event on the first game object underneath the current touch. | ||
|  |         /// </summary> | ||
|  |         private static readonly List<Transform> s_InternalTransformList = new List<Transform>(30); | ||
|  | 
 | ||
|  |         public static GameObject ExecuteHierarchy<T>(GameObject root, BaseEventData eventData, EventFunction<T> callbackFunction) where T : IEventSystemHandler | ||
|  |         { | ||
|  |             GetEventChain(root, s_InternalTransformList); | ||
|  | 
 | ||
|  |             var internalTransformListCount = s_InternalTransformList.Count; | ||
|  |             for (var i = 0; i < internalTransformListCount; i++) | ||
|  |             { | ||
|  |                 var transform = s_InternalTransformList[i]; | ||
|  |                 if (Execute(transform.gameObject, eventData, callbackFunction)) | ||
|  |                     return transform.gameObject; | ||
|  |             } | ||
|  |             return null; | ||
|  |         } | ||
|  | 
 | ||
|  |         private static bool ShouldSendToComponent<T>(Component component) where T : IEventSystemHandler | ||
|  |         { | ||
|  |             var valid = component is T; | ||
|  |             if (!valid) | ||
|  |                 return false; | ||
|  | 
 | ||
|  |             var behaviour = component as Behaviour; | ||
|  |             if (behaviour != null) | ||
|  |                 return behaviour.isActiveAndEnabled; | ||
|  |             return true; | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Get the specified object's event event. | ||
|  |         /// </summary> | ||
|  |         private static void GetEventList<T>(GameObject go, IList<IEventSystemHandler> results) where T : IEventSystemHandler | ||
|  |         { | ||
|  |             // Debug.LogWarning("GetEventList<" + typeof(T).Name + ">"); | ||
|  |             if (results == null) | ||
|  |                 throw new ArgumentException("Results array is null", "results"); | ||
|  | 
 | ||
|  |             if (go == null || !go.activeInHierarchy) | ||
|  |                 return; | ||
|  | 
 | ||
|  |             var components = ListPool<Component>.Get(); | ||
|  |             go.GetComponents(components); | ||
|  | 
 | ||
|  |             var componentsCount = components.Count; | ||
|  |             for (var i = 0; i < componentsCount; i++) | ||
|  |             { | ||
|  |                 if (!ShouldSendToComponent<T>(components[i])) | ||
|  |                     continue; | ||
|  | 
 | ||
|  |                 // Debug.Log(string.Format("{2} found! On {0}.{1}", go, s_GetComponentsScratch[i].GetType(), typeof(T))); | ||
|  |                 results.Add(components[i] as IEventSystemHandler); | ||
|  |             } | ||
|  |             ListPool<Component>.Release(components); | ||
|  |             // Debug.LogWarning("end GetEventList<" + typeof(T).Name + ">"); | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Whether the specified game object will be able to handle the specified event. | ||
|  |         /// </summary> | ||
|  |         public static bool CanHandleEvent<T>(GameObject go) where T : IEventSystemHandler | ||
|  |         { | ||
|  |             var internalHandlers = ListPool<IEventSystemHandler>.Get(); | ||
|  |             GetEventList<T>(go, internalHandlers); | ||
|  |             var handlerCount = internalHandlers.Count; | ||
|  |             ListPool<IEventSystemHandler>.Release(internalHandlers); | ||
|  |             return handlerCount != 0; | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Bubble the specified event on the game object, figuring out which object will actually receive the event. | ||
|  |         /// </summary> | ||
|  |         public static GameObject GetEventHandler<T>(GameObject root) where T : IEventSystemHandler | ||
|  |         { | ||
|  |             if (root == null) | ||
|  |                 return null; | ||
|  | 
 | ||
|  |             Transform t = root.transform; | ||
|  |             while (t != null) | ||
|  |             { | ||
|  |                 if (CanHandleEvent<T>(t.gameObject)) | ||
|  |                     return t.gameObject; | ||
|  |                 t = t.parent; | ||
|  |             } | ||
|  |             return null; | ||
|  |         } | ||
|  |     } | ||
|  | } |