// Copyright (c) 2015 - 2023 Doozy Entertainment. All Rights Reserved.
// This code can only be used under the standard Unity Asset Store End User License Agreement
// A Copy of the EULA APPENDIX 1 is available at http://unity3d.com/company/legal/as_terms
using System.Collections;
using Doozy.Runtime.Common;
using UnityEngine;
using UnityEngine.Events;
// ReSharper disable IdentifierTypo
// ReSharper disable UnusedMember.Global
// ReSharper disable Unity.IncorrectMethodSignature
// ReSharper disable UnusedMethodReturnValue.Global
// ReSharper disable MemberCanBePrivate.Global
namespace Doozy.Runtime.Global
{
///
/// Special class used to run Coroutines on. When using any of its public static methods, it will instantiate itself and run any number of coroutines
public class Coroutiner : SingletonBehaviour
{
///
/// Start a Coroutine.
/// Coroutine will run on the Coroutiner GameObject
///
/// The enumerator
public Coroutine StartLocalCoroutine(IEnumerator enumerator) =>
StartCoroutine(enumerator);
/// Stop the first Coroutine named methodName, or the Coroutine stored in routine running on this behaviour
/// The coroutine
public void StopLocalCoroutine(Coroutine coroutine) =>
StopCoroutine(coroutine);
/// Stop the first Coroutine named methodName, or the Coroutine stored in routine running on this behaviour
/// The enumerator
public void StopLocalCoroutine(IEnumerator enumerator) =>
StopCoroutine(enumerator);
/// Stop all Coroutines running on this behaviour
public void StopAllLocalCoroutines() =>
StopAllCoroutines();
///
/// Start a Coroutine.
/// Coroutine will run on the Coroutiner GameObject
///
/// Target enumerator
public static Coroutine Start(IEnumerator enumerator) =>
instance != null && enumerator != null
? instance.StartLocalCoroutine(enumerator)
: null;
/// Stop the first Coroutine named methodName, or the Coroutine stored in routine running on Coroutiner
/// Target enumerator
public static void Stop(IEnumerator enumerator)
{
if (instance == null || enumerator == null) return;
instance.StopLocalCoroutine(enumerator);
}
/// Stop the first Coroutine named methodName, or the Coroutine stored in routine running on Coroutiner
/// The coroutine
public static void Stop(Coroutine coroutine)
{
if (instance == null || coroutine == null) return;
instance.StopLocalCoroutine(coroutine);
}
/// Stop all Coroutines running on Coroutiner
public static void StopAll()
{
if (instance == null) return;
instance.StopAllLocalCoroutines();
}
///
/// Execute the given callback after the set time delay (in seconds).
/// Coroutine will run on the Coroutiner GameObject
///
/// Callback
/// Time delay in seconds
public static Coroutine ExecuteLater(UnityAction callback, float delay) =>
Start(DelayExecution(callback, delay));
///
/// Execute the given callback after the set number of frames has passed.
/// Coroutine will run on the Coroutiner GameObject
///
/// Callback
/// Number of frames to wait until the callback is executed
public static Coroutine ExecuteLater(UnityAction callback, int numberOfFrames) =>
Start(DelayExecution(callback, numberOfFrames));
///
/// Execute the given callback at the end of the current frame.
/// Coroutine will run on the Coroutiner GameObject
///
/// Callback
public static Coroutine ExecuteAtEndOfFrame(UnityAction callback) =>
Start(DelayExecutionToTheEndOfFrame(callback));
///
/// Execute the given callback in the next frame.
/// Coroutine will run on the Coroutiner GameObject
///
/// Callback
public static Coroutine ExecuteNextFrame(UnityAction callback) =>
Start(DelayExecutionToTheNextFrame(callback));
/// Delay callback execution with for set time duration (in seconds)
/// Callback
/// Time delay in seconds
public static IEnumerator DelayExecution(UnityAction callback, float delay)
{
delay = delay < 0 ? 0 : delay; //sanity check
yield return new WaitForSecondsRealtime(delay); //wait
callback?.Invoke(); //execute
}
/// Delay callback execution with for set number of frames
/// Callback
/// Number of frames to wait until the callback is executed
public static IEnumerator DelayExecution(UnityAction callback, int numberOfFrames)
{
numberOfFrames = numberOfFrames < 0 ? 0 : numberOfFrames; //sanity check
while (numberOfFrames > 0) //wait
{
yield return null;
numberOfFrames--;
}
callback?.Invoke(); //execute
}
/// Delay callback execution till the end of the current frame.
/// Callback
public static IEnumerator DelayExecutionToTheEndOfFrame(UnityAction callback)
{
yield return new WaitForEndOfFrame(); //wait
callback?.Invoke(); //execute
}
/// Delay callback execution till the next frame.
/// Callback
public static IEnumerator DelayExecutionToTheNextFrame(UnityAction callback)
{
yield return null;
callback?.Invoke();
}
}
}