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