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;
}
}
}