namespace Zinnia.Event.Yield { using System.Collections; using UnityEngine; using UnityEngine.Events; using Zinnia.Extension; /// /// Emits an event when a coroutine has complete after the yield. /// public abstract class YieldEmitter : MonoBehaviour { /// /// Emitted when the coroutine has yielded successfully. /// public UnityEvent Yielded = new UnityEvent(); /// /// Emitted when the coroutine is cancelled before the yield completes. /// public UnityEvent Cancelled = new UnityEvent(); /// /// Whether the routine is currently running. /// public virtual bool IsRunning => routine != null; /// /// The routine to process. /// protected Coroutine routine; /// /// Cancels any existing yield check before beginning a new one. /// public virtual void CancelThenBegin() { if (!this.IsValidState()) { return; } Cancel(); Begin(); } /// /// Starts a new yield check if one is not already running. /// public virtual void Begin() { if (!this.IsValidState()) { return; } if (routine == null) { routine = StartCoroutine(Routine()); } } /// /// Cancels any existing yield check. /// public virtual void Cancel() { if (routine != null) { StopCoroutine(routine); Cancelled?.Invoke(); routine = null; } } /// /// The instruction to yield on. /// /// The enumerator to yield on. protected abstract IEnumerator YieldOn(); protected virtual void OnDisable() { Cancel(); } /// /// The routine to perform the yield check with. /// /// An Enumerator to manage the running of the Coroutine. protected virtual IEnumerator Routine() { yield return YieldOn(); if (routine != null) { Yielded?.Invoke(); } routine = null; } } }