diff options
Diffstat (limited to 'Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalReceiver.cs')
| -rw-r--r-- | Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalReceiver.cs | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalReceiver.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalReceiver.cs new file mode 100644 index 0000000..4e7564a --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalReceiver.cs @@ -0,0 +1,248 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Events; +using UnityEngine.Playables; + +namespace UnityEngine.Timeline +{ + /// <summary> + /// Listens for emitted signals and reacts depending on its defined reactions. + /// </summary> + /// A SignalReceiver contains a list of reactions. Each reaction is bound to a SignalAsset. + /// When a SignalEmitter emits a signal, the SignalReceiver invokes the corresponding reaction. + /// <seealso cref="UnityEngine.Timeline.SignalEmitter"/> + /// <seealso cref="UnityEngine.Timeline.SignalAsset"/> + public class SignalReceiver : MonoBehaviour, INotificationReceiver + { + [SerializeField] + EventKeyValue m_Events = new EventKeyValue(); + + /// <summary> + /// Called when a notification is sent. + /// </summary> + public void OnNotify(Playable origin, INotification notification, object context) + { + var signal = notification as SignalEmitter; + if (signal != null && signal.asset != null) + { + UnityEvent evt; + if (m_Events.TryGetValue(signal.asset, out evt) && evt != null) + { + evt.Invoke(); + } + } + } + + /// <summary> + /// Defines a new reaction for a SignalAsset. + /// </summary> + /// <param name="asset">The SignalAsset for which the reaction is being defined.</param> + /// <param name="reaction">The UnityEvent that describes the reaction.</param> + /// <exception cref="ArgumentNullException">Thrown when the asset is null.</exception> + /// <exception cref="ArgumentException">Thrown when the SignalAsset is already registered with this receiver.</exception> + public void AddReaction(SignalAsset asset, UnityEvent reaction) + { + if (asset == null) + throw new ArgumentNullException("asset"); + + if (m_Events.signals.Contains(asset)) + throw new ArgumentException("SignalAsset already used."); + m_Events.Append(asset, reaction); + } + + /// <summary> + /// Appends a null SignalAsset with a reaction specified by the UnityEvent. + /// </summary> + /// <param name="reaction">The new reaction to be appended.</param> + /// <returns>The index of the appended reaction.</returns> + /// <remarks>Multiple null assets are valid.</remarks> + public int AddEmptyReaction(UnityEvent reaction) + { + m_Events.Append(null, reaction); + return m_Events.events.Count - 1; + } + + /// <summary> + /// Removes the first occurrence of a SignalAsset. + /// </summary> + /// <param name="asset">The SignalAsset to be removed.</param> + public void Remove(SignalAsset asset) + { + if (!m_Events.signals.Contains(asset)) + { + throw new ArgumentException("The SignalAsset is not registered with this receiver."); + } + + m_Events.Remove(asset); + } + + /// <summary> + /// Gets a list of all registered SignalAssets. + /// </summary> + /// <returns>Returns a list of SignalAssets.</returns> + public IEnumerable<SignalAsset> GetRegisteredSignals() + { + return m_Events.signals; + } + + /// <summary> + /// Gets the first UnityEvent associated with a SignalAsset. + /// </summary> + /// <param name="key">A SignalAsset defining the signal.</param> + /// <returns>Returns the reaction associated with a SignalAsset. Returns null if the signal asset does not exist.</returns> + public UnityEvent GetReaction(SignalAsset key) + { + UnityEvent ret; + if (m_Events.TryGetValue(key, out ret)) + { + return ret; + } + + return null; + } + + /// <summary> + /// Returns the count of registered SignalAssets. + /// </summary> + /// <returns></returns> + public int Count() + { + return m_Events.signals.Count; + } + + /// <summary> + /// Replaces the SignalAsset associated with a reaction at a specific index. + /// </summary> + /// <param name="idx">The index of the reaction.</param> + /// <param name="newKey">The replacement SignalAsset.</param> + /// <exception cref="ArgumentException">Thrown when the replacement SignalAsset is already registered to this SignalReceiver.</exception> + /// <remarks>The new SignalAsset can be null.</remarks> + public void ChangeSignalAtIndex(int idx, SignalAsset newKey) + { + if (idx < 0 || idx > m_Events.signals.Count - 1) + throw new IndexOutOfRangeException(); + + if (m_Events.signals[idx] == newKey) + return; + var alreadyUsed = m_Events.signals.Contains(newKey); + if (newKey == null || m_Events.signals[idx] == null || !alreadyUsed) + m_Events.signals[idx] = newKey; + + if (newKey != null && alreadyUsed) + throw new ArgumentException("SignalAsset already used."); + } + + /// <summary> + /// Removes the SignalAsset and reaction at a specific index. + /// </summary> + /// <param name="idx">The index of the SignalAsset to be removed.</param> + public void RemoveAtIndex(int idx) + { + if (idx < 0 || idx > m_Events.signals.Count - 1) + throw new IndexOutOfRangeException(); + m_Events.Remove(idx); + } + + /// <summary> + /// Replaces the reaction at a specific index with a new UnityEvent. + /// </summary> + /// <param name="idx">The index of the reaction to be replaced.</param> + /// <param name="reaction">The replacement reaction.</param> + /// <exception cref="ArgumentNullException">Thrown when the replacement reaction is null.</exception> + public void ChangeReactionAtIndex(int idx, UnityEvent reaction) + { + if (idx < 0 || idx > m_Events.events.Count - 1) + throw new IndexOutOfRangeException(); + + m_Events.events[idx] = reaction; + } + + /// <summary> + /// Gets the reaction at a specific index. + /// </summary> + /// <param name="idx">The index of the reaction.</param> + /// <returns>Returns a reaction.</returns> + public UnityEvent GetReactionAtIndex(int idx) + { + if (idx < 0 || idx > m_Events.events.Count - 1) + throw new IndexOutOfRangeException(); + return m_Events.events[idx]; + } + + /// <summary> + /// Gets the SignalAsset at a specific index + /// </summary> + /// <param name="idx">The index of the SignalAsset.</param> + /// <returns>Returns a SignalAsset.</returns> + public SignalAsset GetSignalAssetAtIndex(int idx) + { + if (idx < 0 || idx > m_Events.signals.Count - 1) + throw new IndexOutOfRangeException(); + return m_Events.signals[idx]; + } + + // Required by Unity for the MonoBehaviour to have an enabled state + private void OnEnable() + { + } + + [Serializable] + class EventKeyValue + { + [SerializeField] + List<SignalAsset> m_Signals = new List<SignalAsset>(); + + [SerializeField, CustomSignalEventDrawer] + List<UnityEvent> m_Events = new List<UnityEvent>(); + + public bool TryGetValue(SignalAsset key, out UnityEvent value) + { + var index = m_Signals.IndexOf(key); + if (index != -1) + { + value = m_Events[index]; + return true; + } + + value = null; + return false; + } + + public void Append(SignalAsset key, UnityEvent value) + { + m_Signals.Add(key); + m_Events.Add(value); + } + + public void Remove(int idx) + { + if (idx != -1) + { + m_Signals.RemoveAt(idx); + m_Events.RemoveAt(idx); + } + } + + public void Remove(SignalAsset key) + { + var idx = m_Signals.IndexOf(key); + if (idx != -1) + { + m_Signals.RemoveAt(idx); + m_Events.RemoveAt(idx); + } + } + + public List<SignalAsset> signals + { + get { return m_Signals; } + } + + public List<UnityEvent> events + { + get { return m_Events; } + } + } + } +} |
