// 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(); } } }