// UltEvents // Copyright 2020 Kybernetik // using System; using UnityEngine; using UnityEngine.Events; using Object = UnityEngine.Object; namespace UltEvents { /// /// Allows you to expose the add and remove methods of an without exposing the rest of its /// members such as the ability to invoke it. /// public interface IUltEvent : IUltEventBase { /************************************************************************************************************************/ /// /// Delegates registered here are invoked by after all /// . /// event Action DynamicCalls; /************************************************************************************************************************/ } /// /// A serializable event with 4 parameters which can be viewed and configured in the inspector. /// /// This is a more versatile and user friendly implementation than . /// [Serializable] public class UltEvent : UltEventBase, IUltEvent { /************************************************************************************************************************/ #region Fields and Properties /************************************************************************************************************************/ public override int ParameterCount { get { return 4; } } /************************************************************************************************************************/ /// /// Delegates registered to this event are serialized as s and are invoked by /// before all . /// public event Action PersistentCalls { add { AddPersistentCall(value); } remove { RemovePersistentCall(value); } } /************************************************************************************************************************/ private Action _DynamicCalls; /// /// Delegates registered here are invoked by after all . /// public event Action DynamicCalls { add { _DynamicCalls += value; OnDynamicCallsChanged(); } remove { _DynamicCalls -= value; OnDynamicCallsChanged(); } } /// /// The non-serialized method and parameter details of this event. /// Delegates registered here are called by after all . /// protected override Delegate DynamicCallsBase { get { return _DynamicCalls; } set { _DynamicCalls = value as Action; } } /************************************************************************************************************************/ #endregion /************************************************************************************************************************/ #region Operators and Call Registration /************************************************************************************************************************/ /// /// Ensures that `e` isn't null and adds `method` to its (if in Edit Mode) or /// (in Play Mode and at runtime). /// public static UltEvent operator +(UltEvent e, Action method) { if (e == null) e = new UltEvent(); #if UNITY_EDITOR if (!UnityEditor.EditorApplication.isPlaying && method.Target is Object) { e.PersistentCalls += method; return e; } #endif e.DynamicCalls += method; return e; } /************************************************************************************************************************/ /// /// If `e` isn't null, this method removes `method` from its (if in Edit Mode) or /// (in Play Mode and at runtime). /// public static UltEvent operator -(UltEvent e, Action method) { if (e == null) return null; #if UNITY_EDITOR if (!UnityEditor.EditorApplication.isPlaying && method.Target is Object) { e.PersistentCalls -= method; return e; } #endif e.DynamicCalls -= method; return e; } /************************************************************************************************************************/ /// /// Creates a new and adds `method` to its (if in edit /// mode), or (in Play Mode and at runtime). /// public static implicit operator UltEvent(Action method) { if (method != null) { var e = new UltEvent(); e += method; return e; } else return null; } /************************************************************************************************************************/ /// Ensures that `e` isn't null and adds `method` to its . public static void AddDynamicCall(ref UltEvent e, Action method) { if (e == null) e = new UltEvent(); e.DynamicCalls += method; } /// If `e` isn't null, this method removes `method` from its . public static void RemoveDynamicCall(ref UltEvent e, Action method) { if (e != null) e.DynamicCalls -= method; } /************************************************************************************************************************/ #endregion /************************************************************************************************************************/ #if UNITY_EDITOR /// [Editor-Only] The types of each of this event's parameters. public override Type[] ParameterTypes { get { return _ParameterTypes; } } private static Type[] _ParameterTypes = new Type[] { typeof(T0), typeof(T1), typeof(T2), typeof(T3) }; #endif /************************************************************************************************************************/ /// /// Invokes all then all . /// /// See also: and . /// public virtual void Invoke(T0 parameter0, T1 parameter1, T2 parameter2, T3 parameter3) { CacheParameter(parameter0); CacheParameter(parameter1); CacheParameter(parameter2); CacheParameter(parameter3); InvokePersistentCalls(); if (_DynamicCalls != null) _DynamicCalls(parameter0, parameter1, parameter2, parameter3); } /************************************************************************************************************************/ /// /// Invokes all then all inside a try/catch block /// which logs any exceptions that are thrown. /// /// See also: and . /// public virtual void InvokeSafe(T0 parameter0, T1 parameter1, T2 parameter2, T3 parameter3) { try { Invoke(parameter0, parameter1, parameter2, parameter3); } catch (Exception ex) { Debug.LogException(ex); } } /************************************************************************************************************************/ } }