using System; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace CIG.Extensions { public static class ActionInvoker { public static void Invoke(this MonoBehaviour monoBehaviour, Action action, float time, bool realtime = false) { IEnumerator enumerator = ActionInvoker.InvokeCoroutine(action, time, realtime); if (ActionInvoker._invokeMethods.ContainsKey(action)) { UnityEngine.Debug.LogWarningFormat("[ActionInvoker] Overriding enumerator for action '{0}'.", new object[] { ActionInvoker.GetMethodName(action) }); ActionInvoker._invokeMethods[action] = enumerator; } else { ActionInvoker._invokeMethods.Add(action, enumerator); } monoBehaviour.StartCoroutine(enumerator); } public static void InvokeNextFrame(this MonoBehaviour monoBehaviour, Action action) { IEnumerator enumerator = ActionInvoker.InvokeCoroutine(action); if (ActionInvoker._invokeMethods.ContainsKey(action)) { UnityEngine.Debug.LogWarningFormat("[ActionInvoker] Overriding enumerator for action '{0}'.", new object[] { ActionInvoker.GetMethodName(action) }); ActionInvoker._invokeMethods[action] = enumerator; } else { ActionInvoker._invokeMethods.Add(action, enumerator); } monoBehaviour.StartCoroutine(enumerator); } public static void InvokeRepeating(this MonoBehaviour monoBehaviour, Action action, float time, float repeatRate, bool realtime = false) { IEnumerator enumerator = ActionInvoker.InvokeRepeatingCoroutine(action, time, repeatRate, realtime); if (ActionInvoker._invokeMethods.ContainsKey(action)) { UnityEngine.Debug.LogWarningFormat("[ActionInvoker] Overriding enumerator for action '{0}'.", new object[] { ActionInvoker.GetMethodName(action) }); ActionInvoker._invokeMethods[action] = enumerator; } else { ActionInvoker._invokeMethods.Add(action, enumerator); } monoBehaviour.StartCoroutine(enumerator); } public static bool IsInvoking(this MonoBehaviour monoBehaviour, Action action) { return ActionInvoker._invokeMethods.ContainsKey(action); } public static void CancelInvoke(this MonoBehaviour monoBehaviour, Action action) { if (ActionInvoker._invokeMethods.ContainsKey(action)) { monoBehaviour.StopCoroutine(ActionInvoker._invokeMethods[action]); ActionInvoker._invokeMethods.Remove(action); } } private static string GetMethodName(Action action) { return action.Method.ToString(); } private static IEnumerator InvokeCoroutine(Action action, float time, bool realtime) { if (realtime) { yield return new WaitForSecondsRealtime(time); } else { yield return new WaitForSeconds(time); } if (!ActionInvoker._invokeMethods.ContainsKey(action)) { yield break; } ActionInvoker._invokeMethods.Remove(action); action(); yield break; } private static IEnumerator InvokeCoroutine(Action action) { yield return null; if (!ActionInvoker._invokeMethods.ContainsKey(action)) { yield break; } ActionInvoker._invokeMethods.Remove(action); action(); yield break; } private static IEnumerator InvokeRepeatingCoroutine(Action action, float time, float repeatRate, bool realtime) { if (realtime) { yield return new WaitForSecondsRealtime(time); } else { yield return new WaitForSeconds(time); } if (!ActionInvoker._invokeMethods.ContainsKey(action)) { yield break; } while (ActionInvoker._invokeMethods.ContainsKey(action)) { action(); if (realtime) { yield return new WaitForSecondsRealtime(time); } else { yield return new WaitForSeconds(repeatRate); } } yield break; yield break; } private static Dictionary _invokeMethods = new Dictionary(); } }