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