123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458 |
- #pragma warning disable CS0649 // Field is never assigned to, and will always have its default value.
- #if ANIMANCER_ULT_EVENTS
- using SerializableCallback = UltEvents.UltEvent;
- #else
- using SerializableCallback = UnityEngine.Events.UnityEvent;
- #endif
- using UnityEngine;
- using System;
- namespace Animancer
- {
-
- partial struct AnimancerEvent
- {
-
- partial class Sequence
- {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [Serializable]
- public class Serializable : ICopyable<Serializable>
- #if UNITY_EDITOR
- , ISerializationCallbackReceiver
- #endif
- {
-
- [SerializeField]
- private float[] _NormalizedTimes;
-
- public ref float[] NormalizedTimes => ref _NormalizedTimes;
-
- [SerializeField]
- private SerializableCallback[] _Callbacks;
-
-
-
-
-
- public ref SerializableCallback[] Callbacks => ref _Callbacks;
-
- [SerializeField]
- private string[] _Names;
-
- public ref string[] Names => ref _Names;
-
- #if UNITY_EDITOR
-
-
- internal const string NormalizedTimesField = nameof(_NormalizedTimes);
-
- internal const string CallbacksField = nameof(_Callbacks);
-
- internal const string NamesField = nameof(_Names);
-
- #endif
-
- private Sequence _Events;
-
-
-
-
-
-
-
-
- public Sequence Events
- {
- get
- {
- if (_Events == null)
- {
- GetEventsOptional();
- if (_Events == null)
- _Events = new Sequence();
- }
- return _Events;
- }
- set => _Events = value;
- }
-
-
-
-
-
-
-
-
-
- public Sequence GetEventsOptional()
- {
- if (_Events != null ||
- _NormalizedTimes == null)
- return _Events;
- var timeCount = _NormalizedTimes.Length;
- if (timeCount == 0)
- return null;
- var callbackCount = _Callbacks != null ? _Callbacks.Length : 0;
- var callback = callbackCount >= timeCount-- ?
- GetInvoker(_Callbacks[timeCount]) :
- null;
- var endEvent = new AnimancerEvent(_NormalizedTimes[timeCount], callback);
- _Events = new Sequence(timeCount)
- {
- EndEvent = endEvent,
- Count = timeCount,
- _Names = _Names,
- };
- for (int i = 0; i < timeCount; i++)
- {
- callback = i < callbackCount ? GetInvoker(_Callbacks[i]) : DummyCallback;
- _Events._Events[i] = new AnimancerEvent(_NormalizedTimes[i], callback);
- }
- return _Events;
- }
-
- public static implicit operator Sequence(Serializable serializable) => serializable?.GetEventsOptional();
-
-
- internal Sequence InitializedEvents => _Events;
-
-
-
-
-
-
- public static Action GetInvoker(SerializableCallback callback)
- => HasPersistentCalls(callback) ? callback.Invoke : DummyCallback;
- #if UNITY_EDITOR
-
-
-
- public static Action GetInvoker(object callback)
- => GetInvoker((SerializableCallback)callback);
- #endif
-
-
-
-
-
-
- public static bool HasPersistentCalls(SerializableCallback callback)
- {
- if (callback == null)
- return false;
-
-
-
- #if ANIMANCER_ULT_EVENTS
- var calls = callback.PersistentCallsList;
- return calls != null && calls.Count > 0;
- #else
- return callback.GetPersistentEventCount() > 0;
- #endif
- }
- #if UNITY_EDITOR
-
-
-
- public static bool HasPersistentCalls(object callback) => HasPersistentCalls((SerializableCallback)callback);
- #endif
-
-
-
- public float GetNormalizedEndTime(float speed = 1)
- {
- if (_NormalizedTimes.IsNullOrEmpty())
- return GetDefaultNormalizedEndTime(speed);
- else
- return _NormalizedTimes[_NormalizedTimes.Length - 1];
- }
-
-
- public void SetNormalizedEndTime(float normalizedTime)
- {
- if (_NormalizedTimes.IsNullOrEmpty())
- _NormalizedTimes = new float[] { normalizedTime };
- else
- _NormalizedTimes[_NormalizedTimes.Length - 1] = normalizedTime;
- }
-
-
- public void CopyFrom(Serializable copyFrom)
- {
- if (copyFrom == null)
- {
- _NormalizedTimes = default;
- _Callbacks = default;
- _Names = default;
- return;
- }
- AnimancerUtilities.CopyExactArray(copyFrom._NormalizedTimes, ref _NormalizedTimes);
- AnimancerUtilities.CopyExactArray(copyFrom._Callbacks, ref _Callbacks);
- AnimancerUtilities.CopyExactArray(copyFrom._Names, ref _Names);
- }
-
- #if UNITY_EDITOR
-
-
-
-
-
-
- void ISerializationCallbackReceiver.OnAfterDeserialize() { }
-
-
- void ISerializationCallbackReceiver.OnBeforeSerialize()
- {
- if (_NormalizedTimes == null ||
- _NormalizedTimes.Length <= 2)
- {
- CompactArrays();
- return;
- }
- var eventContext = Editor.SerializableEventSequenceDrawer.Context.Current;
- var selectedEvent = eventContext?.Property != null ? eventContext.SelectedEvent : -1;
- var timeCount = _NormalizedTimes.Length - 1;
- var previousTime = _NormalizedTimes[0];
-
- for (int i = 1; i < timeCount; i++)
- {
- var time = _NormalizedTimes[i];
- if (time >= previousTime)
- {
- previousTime = time;
- continue;
- }
- _NormalizedTimes.Swap(i, i - 1);
- DynamicSwap(ref _Callbacks, i);
- DynamicSwap(ref _Names, i);
- if (selectedEvent == i)
- selectedEvent = i - 1;
- else if (selectedEvent == i - 1)
- selectedEvent = i;
- if (i == 1)
- {
- i = 0;
- previousTime = float.NegativeInfinity;
- }
- else
- {
- i -= 2;
- previousTime = _NormalizedTimes[i];
- }
- }
-
- var transitionContext = Editor.TransitionDrawer.Context;
- if (transitionContext != null &&
- transitionContext.Transition != null &&
- transitionContext.Transition.IsLooping)
- {
- for (int i = _NormalizedTimes.Length - 1; i >= 0; i--)
- {
- var time = _NormalizedTimes[i];
- if (time < 0)
- _NormalizedTimes[i] = 0;
- else if (time > AlmostOne)
- _NormalizedTimes[i] = AlmostOne;
- }
- }
-
- if (eventContext?.Property != null && eventContext.SelectedEvent != selectedEvent)
- {
- eventContext.SelectedEvent = selectedEvent;
- Editor.TransitionPreviewWindow.PreviewNormalizedTime = _NormalizedTimes[selectedEvent];
- }
- CompactArrays();
- }
-
-
-
-
-
- private static void DynamicSwap<T>(ref T[] array, int index)
- {
- var count = array != null ? array.Length : 0;
- if (index == count)
- Array.Resize(ref array, ++count);
- if (index < count)
- array.Swap(index, index - 1);
- }
-
-
-
-
- internal static bool DisableCompactArrays { get; set; }
-
-
-
- private void CompactArrays()
- {
- if (DisableCompactArrays)
- return;
-
- if (_NormalizedTimes == null ||
- (_NormalizedTimes.Length == 1 &&
- (_Callbacks == null || _Callbacks.Length == 0) &&
- (_Names == null || _Names.Length == 0) &&
- float.IsNaN(_NormalizedTimes[0])))
- {
- _NormalizedTimes = Array.Empty<float>();
- _Callbacks = Array.Empty<SerializableCallback>();
- _Names = Array.Empty<string>();
- return;
- }
- Trim(ref _Callbacks, _NormalizedTimes.Length, (callback) => HasPersistentCalls(callback));
- Trim(ref _Names, _NormalizedTimes.Length, (name) => !string.IsNullOrEmpty(name));
- }
-
-
- private static void Trim<T>(ref T[] array, int maxLength, Func<T, bool> isImportant)
- {
- if (array == null)
- return;
- var count = Math.Min(array.Length, maxLength);
- while (count >= 1)
- {
- var item = array[count - 1];
- if (isImportant(item))
- break;
- else
- count--;
- }
- Array.Resize(ref array, count);
- }
-
- #endif
-
- }
- }
- }
- }
- #if UNITY_EDITOR
- namespace Animancer.Editor
- {
-
-
-
-
-
-
-
-
- [Serializable]
- internal sealed class SerializableCallbackHolder
- {
- #pragma warning disable CS0169 // Field is never used.
- [SerializeField]
- private SerializableCallback _Callback;
- #pragma warning restore CS0169 // Field is never used.
-
- internal const string CallbackField = nameof(_Callback);
- }
- }
- #endif
|