namespace UIWidgets { using System.Collections; using System.Collections.Generic; using UnityEngine; /// /// Notification order sequence. /// public enum NotifySequence { /// /// Display notification right now, without adding to sequence. /// None = 0, /// /// Add notification to start of sequence. /// First = 1, /// /// Add notification to end of sequence. /// Last = 2, } /// /// Notification sequence manager. /// public class NotifySequenceManager : MonoBehaviour, IUpdatable { static readonly List NotificationSequence = new List(); static NotificationBase currentNotification; #if UNITY_2019_3_OR_NEWER /// /// Reload support. /// [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] protected static void StaticInit() { currentNotification = null; NotificationSequence.Clear(); } #endif /// /// Clear notifications sequence. /// public void Clear() { if (currentNotification != null) { currentNotification.Return(); currentNotification = null; } foreach (var n in NotificationSequence) { ReturnNotification(n); } NotificationSequence.Clear(); } void ReturnNotification(NotificationBase notification) { notification.Return(); } /// /// Add the specified notification to sequence. /// /// Notification. /// Type. public virtual void Add(NotificationBase notification, NotifySequence type) { if (type == NotifySequence.Last) { NotificationSequence.Add(notification); } else { NotificationSequence.Insert(0, notification); } } /// /// Process the enable event. /// protected virtual void OnEnable() { Updater.Add(this); } /// /// Process the disable event. /// protected virtual void OnDisable() { Updater.Remove(this); } /// /// Display next notification in sequence if possible. /// public virtual void RunUpdate() { if (currentNotification != null) { return; } if (NotificationSequence.Count == 0) { return; } currentNotification = NotificationSequence[0]; NotificationSequence.RemoveAt(0); currentNotification.Display(NotificationDelay); } IEnumerator nextDelay; void NotificationDelay() { if (nextDelay != null) { StopCoroutine(nextDelay); } if ((NotificationSequence.Count > 0) && (NotificationSequence[0].SequenceDelay > 0)) { nextDelay = NextDelay(); StartCoroutine(nextDelay); } else { currentNotification = null; } } /// /// Wait the SequenceDelay seconds. /// /// IEnumerator. [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "HAA0401:Possible allocation of reference type enumerator", Justification = "Enumerator is reusable.")] protected virtual IEnumerator NextDelay() { var notify = NotificationSequence[0]; yield return UtilitiesTime.Wait(notify.SequenceDelay, notify.UnscaledTime); currentNotification = null; } } }