Keine Beschreibung
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

DelegateHelpers.cs 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. using System;
  2. using UnityEngine.Profiling;
  3. namespace UnityEngine.InputSystem.Utilities
  4. {
  5. internal static class DelegateHelpers
  6. {
  7. // InvokeCallbacksSafe protects both against the callback getting removed while being called
  8. // and against exceptions being thrown by the callback.
  9. public static void InvokeCallbacksSafe(ref CallbackArray<Action> callbacks, string callbackName, object context = null)
  10. {
  11. if (callbacks.length == 0)
  12. return;
  13. Profiler.BeginSample(callbackName);
  14. callbacks.LockForChanges();
  15. for (var i = 0; i < callbacks.length; ++i)
  16. {
  17. try
  18. {
  19. callbacks[i]();
  20. }
  21. catch (Exception exception)
  22. {
  23. Debug.LogException(exception);
  24. if (context != null)
  25. Debug.LogError($"{exception.GetType().Name} while executing '{callbackName}' callbacks of '{context}'");
  26. else
  27. Debug.LogError($"{exception.GetType().Name} while executing '{callbackName}' callbacks");
  28. }
  29. }
  30. callbacks.UnlockForChanges();
  31. Profiler.EndSample();
  32. }
  33. public static void InvokeCallbacksSafe<TValue>(ref CallbackArray<Action<TValue>> callbacks, TValue argument, string callbackName, object context = null)
  34. {
  35. if (callbacks.length == 0)
  36. return;
  37. Profiler.BeginSample(callbackName);
  38. callbacks.LockForChanges();
  39. for (var i = 0; i < callbacks.length; ++i)
  40. {
  41. try
  42. {
  43. callbacks[i](argument);
  44. }
  45. catch (Exception exception)
  46. {
  47. Debug.LogException(exception);
  48. if (context != null)
  49. Debug.LogError($"{exception.GetType().Name} while executing '{callbackName}' callbacks of '{context}'");
  50. else
  51. Debug.LogError($"{exception.GetType().Name} while executing '{callbackName}' callbacks");
  52. }
  53. }
  54. callbacks.UnlockForChanges();
  55. Profiler.EndSample();
  56. }
  57. public static void InvokeCallbacksSafe<TValue1, TValue2>(ref CallbackArray<Action<TValue1, TValue2>> callbacks, TValue1 argument1, TValue2 argument2, string callbackName, object context = null)
  58. {
  59. if (callbacks.length == 0)
  60. return;
  61. Profiler.BeginSample(callbackName);
  62. callbacks.LockForChanges();
  63. for (var i = 0; i < callbacks.length; ++i)
  64. {
  65. try
  66. {
  67. callbacks[i](argument1, argument2);
  68. }
  69. catch (Exception exception)
  70. {
  71. Debug.LogException(exception);
  72. if (context != null)
  73. Debug.LogError($"{exception.GetType().Name} while executing '{callbackName}' callbacks of '{context}'");
  74. else
  75. Debug.LogError($"{exception.GetType().Name} while executing '{callbackName}' callbacks");
  76. }
  77. }
  78. callbacks.UnlockForChanges();
  79. Profiler.EndSample();
  80. }
  81. public static bool InvokeCallbacksSafe_AnyCallbackReturnsTrue<TValue1, TValue2>(ref CallbackArray<Func<TValue1, TValue2, bool>> callbacks,
  82. TValue1 argument1, TValue2 argument2, string callbackName, object context = null)
  83. {
  84. if (callbacks.length == 0)
  85. return true;
  86. Profiler.BeginSample(callbackName);
  87. callbacks.LockForChanges();
  88. for (var i = 0; i < callbacks.length; ++i)
  89. {
  90. try
  91. {
  92. if (callbacks[i](argument1, argument2))
  93. {
  94. callbacks.UnlockForChanges();
  95. Profiler.EndSample();
  96. return true;
  97. }
  98. }
  99. catch (Exception exception)
  100. {
  101. Debug.LogException(exception);
  102. if (context != null)
  103. Debug.LogError($"{exception.GetType().Name} while executing '{callbackName}' callbacks of '{context}'");
  104. else
  105. Debug.LogError($"{exception.GetType().Name} while executing '{callbackName}' callbacks");
  106. }
  107. }
  108. callbacks.UnlockForChanges();
  109. Profiler.EndSample();
  110. return false;
  111. }
  112. /// <summary>
  113. /// Invokes the given callbacks and also invokes any callback returned from the result of the first.
  114. /// </summary>
  115. /// <seealso cref="System.Action"/>
  116. /// <remarks>
  117. /// Allows an chaining up an additional, optional block of code to the original callback
  118. /// and allow the external code make the decision about whether this code should be executed.
  119. /// </remarks>
  120. public static void InvokeCallbacksSafe_AndInvokeReturnedActions<TValue>(
  121. ref CallbackArray<Func<TValue, Action>> callbacks, TValue argument,
  122. string callbackName, object context = null)
  123. {
  124. if (callbacks.length == 0)
  125. return;
  126. Profiler.BeginSample(callbackName);
  127. callbacks.LockForChanges();
  128. for (var i = 0; i < callbacks.length; ++i)
  129. {
  130. try
  131. {
  132. callbacks[i](argument)?.Invoke();
  133. }
  134. catch (Exception exception)
  135. {
  136. Debug.LogException(exception);
  137. if (context != null)
  138. Debug.LogError($"{exception.GetType().Name} while executing '{callbackName}' callbacks of '{context}'");
  139. else
  140. Debug.LogError($"{exception.GetType().Name} while executing '{callbackName}' callbacks");
  141. }
  142. }
  143. callbacks.UnlockForChanges();
  144. Profiler.EndSample();
  145. }
  146. /// <summary>
  147. /// Invokes the given callbacks and returns true if any of them returned a non-null result.
  148. /// </summary>
  149. /// <remarks>
  150. /// Returns false if every callback invocation returned null.
  151. /// </remarks>
  152. public static bool InvokeCallbacksSafe_AnyCallbackReturnsObject<TValue, TReturn>(
  153. ref CallbackArray<Func<TValue, TReturn>> callbacks, TValue argument,
  154. string callbackName, object context = null)
  155. {
  156. if (callbacks.length == 0)
  157. return false;
  158. Profiler.BeginSample(callbackName);
  159. callbacks.LockForChanges();
  160. for (var i = 0; i < callbacks.length; ++i)
  161. {
  162. try
  163. {
  164. var ret = callbacks[i](argument);
  165. if (ret != null)
  166. {
  167. callbacks.UnlockForChanges();
  168. Profiler.EndSample();
  169. return true;
  170. }
  171. }
  172. catch (Exception exception)
  173. {
  174. Debug.LogException(exception);
  175. if (context != null)
  176. Debug.LogError($"{exception.GetType().Name} while executing '{callbackName}' callbacks of '{context}'");
  177. else
  178. Debug.LogError($"{exception.GetType().Name} while executing '{callbackName}' callbacks");
  179. }
  180. }
  181. callbacks.UnlockForChanges();
  182. Profiler.EndSample();
  183. return false;
  184. }
  185. }
  186. }