From 2afbb545027568fccc85853e18af02a7c6b2929e Mon Sep 17 00:00:00 2001 From: chai <215380520@qq.com> Date: Tue, 16 May 2023 16:03:51 +0800 Subject: *misc --- .../Assets/Plugins/Trinary Software/Timing.cs | 2738 -------------------- 1 file changed, 2738 deletions(-) delete mode 100644 WorldlineKeepers/Assets/Plugins/Trinary Software/Timing.cs (limited to 'WorldlineKeepers/Assets/Plugins/Trinary Software/Timing.cs') diff --git a/WorldlineKeepers/Assets/Plugins/Trinary Software/Timing.cs b/WorldlineKeepers/Assets/Plugins/Trinary Software/Timing.cs deleted file mode 100644 index c61b93e..0000000 --- a/WorldlineKeepers/Assets/Plugins/Trinary Software/Timing.cs +++ /dev/null @@ -1,2738 +0,0 @@ -using UnityEngine; -using System.Collections.Generic; -using UnityEngine.Assertions; -#if UNITY_5_5_OR_NEWER -using UnityEngine.Profiling; -#endif - -// ///////////////////////////////////////////////////////////////////////////////////////// -// More Effective Coroutines -// v3.10.2 -// -// This is an improved implementation of coroutines that boasts zero per-frame memory allocations, -// runs about twice as fast as Unity's built in coroutines and has a range of extra features. -// -// This is the free version. MEC also has a pro version, which can be found here: -// https://www.assetstore.unity3d.com/en/#!/content/68480 -// The pro version contains exactly the same core that the free version uses, but also -// contains many additional features. Every function that exists in MEC Free also exists in MEC Pro, -// so you can upgrade at any time without breaking existing code. -// -// For manual, support, or upgrade guide visit http://trinary.tech/ -// -// Created by Teal Rogers -// Trinary Software -// All rights preserved -// ///////////////////////////////////////////////////////////////////////////////////////// - -namespace MEC -{ - public class Timing : MonoBehaviour - { - /// - /// The time between calls to SlowUpdate. - /// - [Tooltip("How quickly the SlowUpdate segment ticks.")] - public float TimeBetweenSlowUpdateCalls = 1f / 7f; - /// - /// The amount that each coroutine should be seperated inside the Unity profiler. NOTE: When the profiler window - /// is not open this value is ignored and all coroutines behave as if "None" is selected. - /// - [Tooltip("How much data should be sent to the profiler window when it's open.")] - public DebugInfoType ProfilerDebugAmount; - /// - /// The number of coroutines that are being run in the Update segment. - /// - [Tooltip("A count of the number of Update coroutines that are currently running."), Space(12)] - public int UpdateCoroutines; - /// - /// The number of coroutines that are being run in the FixedUpdate segment. - /// - [Tooltip("A count of the number of FixedUpdate coroutines that are currently running.")] - public int FixedUpdateCoroutines; - /// - /// The number of coroutines that are being run in the LateUpdate segment. - /// - [Tooltip("A count of the number of LateUpdate coroutines that are currently running.")] - public int LateUpdateCoroutines; - /// - /// The number of coroutines that are being run in the SlowUpdate segment. - /// - [Tooltip("A count of the number of SlowUpdate coroutines that are currently running.")] - public int SlowUpdateCoroutines; - /// - /// The time in seconds that the current segment has been running. - /// - [System.NonSerialized] - public float localTime; - /// - /// The time in seconds that the current segment has been running. - /// - public static float LocalTime { get { return Instance.localTime; } } - /// - /// The amount of time in fractional seconds that elapsed between this frame and the last frame. - /// - [System.NonSerialized] - public float deltaTime; - /// - /// The amount of time in fractional seconds that elapsed between this frame and the last frame. - /// - public static float DeltaTime { get { return Instance.deltaTime; } } - /// - /// Used for advanced coroutine control. - /// - public static System.Func, CoroutineHandle, IEnumerator> ReplacementFunction; - /// - /// This event fires just before each segment is run. - /// - public static event System.Action OnPreExecute; - /// - /// You can use "yield return Timing.WaitForOneFrame;" inside a coroutine function to go to the next frame. - /// - public const float WaitForOneFrame = float.NegativeInfinity; - /// - /// The main thread that (almost) everything in unity runs in. - /// - public static System.Threading.Thread MainThread { get; private set; } - /// - /// The handle of the current coroutine that is running. - /// - public static CoroutineHandle CurrentCoroutine - { - get - { - for (int i = 0; i < ActiveInstances.Length; i++) - if (ActiveInstances[i] != null && ActiveInstances[i].currentCoroutine.IsValid) - return ActiveInstances[i].currentCoroutine; - return default(CoroutineHandle); - } - } - /// - /// The handle of the current coroutine that is running. - /// - public CoroutineHandle currentCoroutine { get; private set; } - - private static object _tmpRef; - private static bool _tmpBool; - private static CoroutineHandle _tmpHandle; - - private int _currentUpdateFrame; - private int _currentLateUpdateFrame; - private int _currentSlowUpdateFrame; - private int _nextUpdateProcessSlot; - private int _nextLateUpdateProcessSlot; - private int _nextFixedUpdateProcessSlot; - private int _nextSlowUpdateProcessSlot; - private int _lastUpdateProcessSlot; - private int _lastLateUpdateProcessSlot; - private int _lastFixedUpdateProcessSlot; - private int _lastSlowUpdateProcessSlot; - private float _lastUpdateTime; - private float _lastLateUpdateTime; - private float _lastFixedUpdateTime; - private float _lastSlowUpdateTime; - private float _lastSlowUpdateDeltaTime; - private ushort _framesSinceUpdate; - private ushort _expansions = 1; - [SerializeField, HideInInspector] - private byte _instanceID; - - private readonly Dictionary> _waitingTriggers = new Dictionary>(); - private readonly HashSet _allWaiting = new HashSet(); - private readonly Dictionary _handleToIndex = new Dictionary(); - private readonly Dictionary _indexToHandle = new Dictionary(); - private readonly Dictionary _processTags = new Dictionary(); - private readonly Dictionary> _taggedProcesses = new Dictionary>(); - - private IEnumerator[] UpdateProcesses = new IEnumerator[InitialBufferSizeLarge]; - private IEnumerator[] LateUpdateProcesses = new IEnumerator[InitialBufferSizeSmall]; - private IEnumerator[] FixedUpdateProcesses = new IEnumerator[InitialBufferSizeMedium]; - private IEnumerator[] SlowUpdateProcesses = new IEnumerator[InitialBufferSizeMedium]; - - private bool[] UpdatePaused = new bool[InitialBufferSizeLarge]; - private bool[] LateUpdatePaused = new bool[InitialBufferSizeSmall]; - private bool[] FixedUpdatePaused = new bool[InitialBufferSizeMedium]; - private bool[] SlowUpdatePaused = new bool[InitialBufferSizeMedium]; - private bool[] UpdateHeld = new bool[InitialBufferSizeLarge]; - private bool[] LateUpdateHeld = new bool[InitialBufferSizeSmall]; - private bool[] FixedUpdateHeld = new bool[InitialBufferSizeMedium]; - private bool[] SlowUpdateHeld = new bool[InitialBufferSizeMedium]; - - private const ushort FramesUntilMaintenance = 64; - private const int ProcessArrayChunkSize = 64; - private const int InitialBufferSizeLarge = 256; - private const int InitialBufferSizeMedium = 64; - private const int InitialBufferSizeSmall = 8; - - private static Timing[] ActiveInstances = new Timing[16]; - private static Timing _instance; - - public static Timing Instance - { - get - { - if (_instance == null || !_instance.gameObject) - { - GameObject instanceHome = GameObject.Find("Timing Controller"); - - if (instanceHome == null) - { - instanceHome = new GameObject { name = "Timing Controller" }; - - DontDestroyOnLoad(instanceHome); - } - - _instance = instanceHome.GetComponent() ?? instanceHome.AddComponent(); - - _instance.InitializeInstanceID(); - } - - return _instance; - } - set { _instance = value; } - } - - void OnDestroy() - { - if (_instance == this) - _instance = null; - } - - void OnEnable() - { - if (MainThread == null) - MainThread = System.Threading.Thread.CurrentThread; - - InitializeInstanceID(); - } - - void OnDisable() - { - if (_instanceID < ActiveInstances.Length) - ActiveInstances[_instanceID] = null; - } - - private void InitializeInstanceID() - { - if (ActiveInstances[_instanceID] == null) - { - if (_instanceID == 0x00) - _instanceID++; - - for (; _instanceID <= 0x10; _instanceID++) - { - if (_instanceID == 0x10) - { - GameObject.Destroy(gameObject); - throw new System.OverflowException("You are only allowed 15 different contexts for MEC to run inside at one time."); - } - - if (ActiveInstances[_instanceID] == null) - { - ActiveInstances[_instanceID] = this; - break; - } - } - } - } - - void Update() - { - if (OnPreExecute != null) - OnPreExecute(); - - if (_lastSlowUpdateTime + TimeBetweenSlowUpdateCalls < Time.realtimeSinceStartup && _nextSlowUpdateProcessSlot > 0) - { - ProcessIndex coindex = new ProcessIndex { seg = Segment.SlowUpdate }; - if (UpdateTimeValues(coindex.seg)) - _lastSlowUpdateProcessSlot = _nextSlowUpdateProcessSlot; - - for (coindex.i = 0; coindex.i < _lastSlowUpdateProcessSlot; coindex.i++) - { - try - { - if (!SlowUpdatePaused[coindex.i] && !SlowUpdateHeld[coindex.i] && SlowUpdateProcesses[coindex.i] != null && !(localTime < SlowUpdateProcesses[coindex.i].Current)) - { - currentCoroutine = _indexToHandle[coindex]; - - if (ProfilerDebugAmount != DebugInfoType.None && _indexToHandle.ContainsKey(coindex)) - { - Profiler.BeginSample(ProfilerDebugAmount == DebugInfoType.SeperateTags ? ("Processing Coroutine (Slow Update)" + - (_processTags.ContainsKey(_indexToHandle[coindex]) ? ", tag " + _processTags[_indexToHandle[coindex]] : ", no tag")) - : "Processing Coroutine (Slow Update)"); - } - - if (!SlowUpdateProcesses[coindex.i].MoveNext()) - { - if (_indexToHandle.ContainsKey(coindex)) - KillCoroutinesOnInstance(_indexToHandle[coindex]); - } - else if (SlowUpdateProcesses[coindex.i] != null && float.IsNaN(SlowUpdateProcesses[coindex.i].Current)) - { - if (ReplacementFunction != null) - { - SlowUpdateProcesses[coindex.i] = ReplacementFunction(SlowUpdateProcesses[coindex.i], _indexToHandle[coindex]); - ReplacementFunction = null; - } - coindex.i--; - } - - if (ProfilerDebugAmount != DebugInfoType.None) - Profiler.EndSample(); - } - } - catch (System.Exception ex) - { - Debug.LogException(ex); - - if (ex is MissingReferenceException) - Debug.LogError("This exception can probably be fixed by adding \"CancelWith(gameObject)\" when you run the coroutine.\n" - + "Example: Timing.RunCoroutine(_foo().CancelWith(gameObject), Segment.SlowUpdate);"); - } - } - } - - if (_nextUpdateProcessSlot > 0) - { - ProcessIndex coindex = new ProcessIndex { seg = Segment.Update }; - if (UpdateTimeValues(coindex.seg)) - _lastUpdateProcessSlot = _nextUpdateProcessSlot; - - for (coindex.i = 0; coindex.i < _lastUpdateProcessSlot; coindex.i++) - { - try - { - if (!UpdatePaused[coindex.i] && !UpdateHeld[coindex.i] && UpdateProcesses[coindex.i] != null && !(localTime < UpdateProcesses[coindex.i].Current)) - { - currentCoroutine = _indexToHandle[coindex]; - - if (ProfilerDebugAmount != DebugInfoType.None && _indexToHandle.ContainsKey(coindex)) - { - Profiler.BeginSample(ProfilerDebugAmount == DebugInfoType.SeperateTags ? ("Processing Coroutine" + - (_processTags.ContainsKey(_indexToHandle[coindex]) ? ", tag " + _processTags[_indexToHandle[coindex]] : ", no tag")) - : "Processing Coroutine"); - } - - if (!UpdateProcesses[coindex.i].MoveNext()) - { - if (_indexToHandle.ContainsKey(coindex)) - KillCoroutinesOnInstance(_indexToHandle[coindex]); - } - else if (UpdateProcesses[coindex.i] != null && float.IsNaN(UpdateProcesses[coindex.i].Current)) - { - if (ReplacementFunction != null) - { - UpdateProcesses[coindex.i] = ReplacementFunction(UpdateProcesses[coindex.i], _indexToHandle[coindex]); - ReplacementFunction = null; - } - coindex.i--; - } - - if (ProfilerDebugAmount != DebugInfoType.None) - Profiler.EndSample(); - } - } - catch (System.Exception ex) - { - Debug.LogException(ex); - - if (ex is MissingReferenceException) - Debug.LogError("This exception can probably be fixed by adding \"CancelWith(gameObject)\" when you run the coroutine.\n" - + "Example: Timing.RunCoroutine(_foo().CancelWith(gameObject));"); - } - } - } - - currentCoroutine = default(CoroutineHandle); - - if(++_framesSinceUpdate > FramesUntilMaintenance) - { - _framesSinceUpdate = 0; - - if (ProfilerDebugAmount != DebugInfoType.None) - Profiler.BeginSample("Maintenance Task"); - - RemoveUnused(); - - if (ProfilerDebugAmount != DebugInfoType.None) - Profiler.EndSample(); - } - } - - void FixedUpdate() - { - if (OnPreExecute != null) - OnPreExecute(); - - if (_nextFixedUpdateProcessSlot > 0) - { - ProcessIndex coindex = new ProcessIndex { seg = Segment.FixedUpdate }; - if (UpdateTimeValues(coindex.seg)) - _lastFixedUpdateProcessSlot = _nextFixedUpdateProcessSlot; - - for (coindex.i = 0; coindex.i < _lastFixedUpdateProcessSlot; coindex.i++) - { - try - { - if (!FixedUpdatePaused[coindex.i] && !FixedUpdateHeld[coindex.i] && FixedUpdateProcesses[coindex.i] != null && !(localTime < FixedUpdateProcesses[coindex.i].Current)) - { - currentCoroutine = _indexToHandle[coindex]; - - - if (ProfilerDebugAmount != DebugInfoType.None && _indexToHandle.ContainsKey(coindex)) - { - Profiler.BeginSample(ProfilerDebugAmount == DebugInfoType.SeperateTags ? ("Processing Coroutine" + - (_processTags.ContainsKey(_indexToHandle[coindex]) ? ", tag " + _processTags[_indexToHandle[coindex]] : ", no tag")) - : "Processing Coroutine"); - } - - if (!FixedUpdateProcesses[coindex.i].MoveNext()) - { - if (_indexToHandle.ContainsKey(coindex)) - KillCoroutinesOnInstance(_indexToHandle[coindex]); - } - else if (FixedUpdateProcesses[coindex.i] != null && float.IsNaN(FixedUpdateProcesses[coindex.i].Current)) - { - if (ReplacementFunction != null) - { - FixedUpdateProcesses[coindex.i] = ReplacementFunction(FixedUpdateProcesses[coindex.i], _indexToHandle[coindex]); - ReplacementFunction = null; - } - coindex.i--; - } - - if (ProfilerDebugAmount != DebugInfoType.None) - Profiler.EndSample(); - } - } - catch (System.Exception ex) - { - Debug.LogException(ex); - - if (ex is MissingReferenceException) - Debug.LogError("This exception can probably be fixed by adding \"CancelWith(gameObject)\" when you run the coroutine.\n" - + "Example: Timing.RunCoroutine(_foo().CancelWith(gameObject), Segment.FixedUpdate);"); - } - } - - currentCoroutine = default(CoroutineHandle); - } - } - - void LateUpdate() - { - if (OnPreExecute != null) - OnPreExecute(); - - if (_nextLateUpdateProcessSlot > 0) - { - ProcessIndex coindex = new ProcessIndex { seg = Segment.LateUpdate }; - if (UpdateTimeValues(coindex.seg)) - _lastLateUpdateProcessSlot = _nextLateUpdateProcessSlot; - - for (coindex.i = 0; coindex.i < _lastLateUpdateProcessSlot; coindex.i++) - { - try - { - if (!LateUpdatePaused[coindex.i] && !LateUpdateHeld[coindex.i] && LateUpdateProcesses[coindex.i] != null && !(localTime < LateUpdateProcesses[coindex.i].Current)) - { - currentCoroutine = _indexToHandle[coindex]; - - - if (ProfilerDebugAmount != DebugInfoType.None && _indexToHandle.ContainsKey(coindex)) - { - Profiler.BeginSample(ProfilerDebugAmount == DebugInfoType.SeperateTags ? ("Processing Coroutine" + - (_processTags.ContainsKey(_indexToHandle[coindex]) ? ", tag " + _processTags[_indexToHandle[coindex]] : ", no tag")) - : "Processing Coroutine"); - } - - if (!LateUpdateProcesses[coindex.i].MoveNext()) - { - if (_indexToHandle.ContainsKey(coindex)) - KillCoroutinesOnInstance(_indexToHandle[coindex]); - } - else if (LateUpdateProcesses[coindex.i] != null && float.IsNaN(LateUpdateProcesses[coindex.i].Current)) - { - if (ReplacementFunction != null) - { - LateUpdateProcesses[coindex.i] = ReplacementFunction(LateUpdateProcesses[coindex.i], _indexToHandle[coindex]); - ReplacementFunction = null; - } - coindex.i--; - } - - if (ProfilerDebugAmount != DebugInfoType.None) - Profiler.EndSample(); - } - } - catch (System.Exception ex) - { - Debug.LogException(ex); - - if (ex is MissingReferenceException) - Debug.LogError("This exception can probably be fixed by adding \"CancelWith(gameObject)\" when you run the coroutine.\n" - + "Example: Timing.RunCoroutine(_foo().CancelWith(gameObject), Segment.LateUpdate);"); - } - } - currentCoroutine = default(CoroutineHandle); - } - } - - private void RemoveUnused() - { - var waitTrigsEnum = _waitingTriggers.GetEnumerator(); - while (waitTrigsEnum.MoveNext()) - { - if (waitTrigsEnum.Current.Value.Count == 0) - { - _waitingTriggers.Remove(waitTrigsEnum.Current.Key); - waitTrigsEnum = _waitingTriggers.GetEnumerator(); - continue; - } - - if (_handleToIndex.ContainsKey(waitTrigsEnum.Current.Key) && CoindexIsNull(_handleToIndex[waitTrigsEnum.Current.Key])) - { - CloseWaitingProcess(waitTrigsEnum.Current.Key); - waitTrigsEnum = _waitingTriggers.GetEnumerator(); - } - } - - ProcessIndex outer, inner; - outer.seg = inner.seg = Segment.Update; - - for (outer.i = inner.i = 0; outer.i < _nextUpdateProcessSlot; outer.i++) - { - if (UpdateProcesses[outer.i] != null) - { - if (outer.i != inner.i) - { - UpdateProcesses[inner.i] = UpdateProcesses[outer.i]; - UpdatePaused[inner.i] = UpdatePaused[outer.i]; - UpdateHeld[inner.i] = UpdateHeld[outer.i]; - - if (_indexToHandle.ContainsKey(inner)) - { - RemoveTag(_indexToHandle[inner]); - _handleToIndex.Remove(_indexToHandle[inner]); - _indexToHandle.Remove(inner); - } - - _handleToIndex[_indexToHandle[outer]] = inner; - _indexToHandle.Add(inner, _indexToHandle[outer]); - _indexToHandle.Remove(outer); - } - inner.i++; - } - } - for (outer.i = inner.i; outer.i < _nextUpdateProcessSlot; outer.i++) - { - UpdateProcesses[outer.i] = null; - UpdatePaused[outer.i] = false; - UpdateHeld[outer.i] = false; - - if (_indexToHandle.ContainsKey(outer)) - { - RemoveTag(_indexToHandle[outer]); - - _handleToIndex.Remove(_indexToHandle[outer]); - _indexToHandle.Remove(outer); - } - } - - _lastUpdateProcessSlot -= _nextUpdateProcessSlot - inner.i; - UpdateCoroutines = _nextUpdateProcessSlot = inner.i; - - outer.seg = inner.seg = Segment.FixedUpdate; - for (outer.i = inner.i = 0; outer.i < _nextFixedUpdateProcessSlot; outer.i++) - { - if (FixedUpdateProcesses[outer.i] != null) - { - if (outer.i != inner.i) - { - FixedUpdateProcesses[inner.i] = FixedUpdateProcesses[outer.i]; - FixedUpdatePaused[inner.i] = FixedUpdatePaused[outer.i]; - FixedUpdateHeld[inner.i] = FixedUpdateHeld[outer.i]; - - if (_indexToHandle.ContainsKey(inner)) - { - RemoveTag(_indexToHandle[inner]); - _handleToIndex.Remove(_indexToHandle[inner]); - _indexToHandle.Remove(inner); - } - - _handleToIndex[_indexToHandle[outer]] = inner; - _indexToHandle.Add(inner, _indexToHandle[outer]); - _indexToHandle.Remove(outer); - } - inner.i++; - } - } - for (outer.i = inner.i; outer.i < _nextFixedUpdateProcessSlot; outer.i++) - { - FixedUpdateProcesses[outer.i] = null; - FixedUpdatePaused[outer.i] = false; - FixedUpdateHeld[outer.i] = false; - - if (_indexToHandle.ContainsKey(outer)) - { - RemoveTag(_indexToHandle[outer]); - - _handleToIndex.Remove(_indexToHandle[outer]); - _indexToHandle.Remove(outer); - } - } - - _lastFixedUpdateProcessSlot -= _nextFixedUpdateProcessSlot - inner.i; - FixedUpdateCoroutines = _nextFixedUpdateProcessSlot = inner.i; - - outer.seg = inner.seg = Segment.LateUpdate; - for (outer.i = inner.i = 0; outer.i < _nextLateUpdateProcessSlot; outer.i++) - { - if (LateUpdateProcesses[outer.i] != null) - { - if (outer.i != inner.i) - { - LateUpdateProcesses[inner.i] = LateUpdateProcesses[outer.i]; - LateUpdatePaused[inner.i] = LateUpdatePaused[outer.i]; - LateUpdateHeld[inner.i] = LateUpdateHeld[outer.i]; - - if (_indexToHandle.ContainsKey(inner)) - { - RemoveTag(_indexToHandle[inner]); - _handleToIndex.Remove(_indexToHandle[inner]); - _indexToHandle.Remove(inner); - } - - _handleToIndex[_indexToHandle[outer]] = inner; - _indexToHandle.Add(inner, _indexToHandle[outer]); - _indexToHandle.Remove(outer); - } - inner.i++; - } - } - for (outer.i = inner.i; outer.i < _nextLateUpdateProcessSlot; outer.i++) - { - LateUpdateProcesses[outer.i] = null; - LateUpdatePaused[outer.i] = false; - LateUpdateHeld[outer.i] = false; - - if (_indexToHandle.ContainsKey(outer)) - { - RemoveTag(_indexToHandle[outer]); - - _handleToIndex.Remove(_indexToHandle[outer]); - _indexToHandle.Remove(outer); - } - } - - _lastLateUpdateProcessSlot -= _nextLateUpdateProcessSlot - inner.i; - LateUpdateCoroutines = _nextLateUpdateProcessSlot = inner.i; - - outer.seg = inner.seg = Segment.SlowUpdate; - for (outer.i = inner.i = 0; outer.i < _nextSlowUpdateProcessSlot; outer.i++) - { - if (SlowUpdateProcesses[outer.i] != null) - { - if (outer.i != inner.i) - { - SlowUpdateProcesses[inner.i] = SlowUpdateProcesses[outer.i]; - SlowUpdatePaused[inner.i] = SlowUpdatePaused[outer.i]; - SlowUpdateHeld[inner.i] = SlowUpdateHeld[outer.i]; - - if (_indexToHandle.ContainsKey(inner)) - { - RemoveTag(_indexToHandle[inner]); - _handleToIndex.Remove(_indexToHandle[inner]); - _indexToHandle.Remove(inner); - } - - _handleToIndex[_indexToHandle[outer]] = inner; - _indexToHandle.Add(inner, _indexToHandle[outer]); - _indexToHandle.Remove(outer); - } - inner.i++; - } - } - for (outer.i = inner.i; outer.i < _nextSlowUpdateProcessSlot; outer.i++) - { - SlowUpdateProcesses[outer.i] = null; - SlowUpdatePaused[outer.i] = false; - SlowUpdateHeld[outer.i] = false; - - if (_indexToHandle.ContainsKey(outer)) - { - RemoveTag(_indexToHandle[outer]); - - _handleToIndex.Remove(_indexToHandle[outer]); - _indexToHandle.Remove(outer); - } - } - - _lastSlowUpdateProcessSlot -= _nextSlowUpdateProcessSlot - inner.i; - SlowUpdateCoroutines = _nextSlowUpdateProcessSlot = inner.i; - } - - /// - /// Run a new coroutine in the Update segment. - /// - /// The new coroutine's handle. - /// The coroutine's handle, which can be used for Wait and Kill operations. - public static CoroutineHandle RunCoroutine(IEnumerator coroutine) - { - return coroutine == null ? new CoroutineHandle() - : Instance.RunCoroutineInternal(coroutine, Segment.Update, null, new CoroutineHandle(Instance._instanceID), true); - } - - /// - /// Run a new coroutine in the Update segment. - /// - /// The new coroutine's handle. - /// An optional tag to attach to the coroutine which can later be used for Kill operations. - /// The coroutine's handle, which can be used for Wait and Kill operations. - public static CoroutineHandle RunCoroutine(IEnumerator coroutine, string tag) - { - return coroutine == null ? new CoroutineHandle() - : Instance.RunCoroutineInternal(coroutine, Segment.Update, tag, new CoroutineHandle(Instance._instanceID), true); - } - - /// - /// Run a new coroutine. - /// - /// The new coroutine's handle. - /// The segment that the coroutine should run in. - /// The coroutine's handle, which can be used for Wait and Kill operations. - public static CoroutineHandle RunCoroutine(IEnumerator coroutine, Segment segment) - { - return coroutine == null ? new CoroutineHandle() - : Instance.RunCoroutineInternal(coroutine, segment, null, new CoroutineHandle(Instance._instanceID), true); - } - - /// - /// Run a new coroutine. - /// - /// The new coroutine's handle. - /// The segment that the coroutine should run in. - /// An optional tag to attach to the coroutine which can later be used for Kill operations. - /// The coroutine's handle, which can be used for Wait and Kill operations. - public static CoroutineHandle RunCoroutine(IEnumerator coroutine, Segment segment, string tag) - { - return coroutine == null ? new CoroutineHandle() - : Instance.RunCoroutineInternal(coroutine, segment, tag, new CoroutineHandle(Instance._instanceID), true); - } - - /// - /// Run a new coroutine on this Timing instance in the Update segment. - /// - /// The new coroutine's handle. - /// The coroutine's handle, which can be used for Wait and Kill operations. - public CoroutineHandle RunCoroutineOnInstance(IEnumerator coroutine) - { - return coroutine == null ? new CoroutineHandle() - : RunCoroutineInternal(coroutine, Segment.Update, null, new CoroutineHandle(_instanceID), true); - } - - /// - /// Run a new coroutine on this Timing instance in the Update segment. - /// - /// The new coroutine's handle. - /// An optional tag to attach to the coroutine which can later be used for Kill operations. - /// The coroutine's handle, which can be used for Wait and Kill operations. - public CoroutineHandle RunCoroutineOnInstance(IEnumerator coroutine, string tag) - { - return coroutine == null ? new CoroutineHandle() - : RunCoroutineInternal(coroutine, Segment.Update, tag, new CoroutineHandle(_instanceID), true); - } - - /// - /// Run a new coroutine on this Timing instance. - /// - /// The new coroutine's handle. - /// The segment that the coroutine should run in. - /// The coroutine's handle, which can be used for Wait and Kill operations. - public CoroutineHandle RunCoroutineOnInstance(IEnumerator coroutine, Segment segment) - { - return coroutine == null ? new CoroutineHandle() - : RunCoroutineInternal(coroutine, segment, null, new CoroutineHandle(_instanceID), true); - } - - /// - /// Run a new coroutine on this Timing instance. - /// - /// The new coroutine's handle. - /// The segment that the coroutine should run in. - /// An optional tag to attach to the coroutine which can later be used for Kill operations. - /// The coroutine's handle, which can be used for Wait and Kill operations. - public CoroutineHandle RunCoroutineOnInstance(IEnumerator coroutine, Segment segment, string tag) - { - return coroutine == null ? new CoroutineHandle() - : RunCoroutineInternal(coroutine, segment, tag, new CoroutineHandle(_instanceID), true); - } - - - private CoroutineHandle RunCoroutineInternal(IEnumerator coroutine, Segment segment, string tag, CoroutineHandle handle, bool prewarm) - { - ProcessIndex slot = new ProcessIndex { seg = segment }; - - if (_handleToIndex.ContainsKey(handle)) - { - _indexToHandle.Remove(_handleToIndex[handle]); - _handleToIndex.Remove(handle); - } - - float currentLocalTime = localTime; - float currentDeltaTime = deltaTime; - CoroutineHandle cachedHandle = currentCoroutine; - currentCoroutine = handle; - - switch (segment) - { - case Segment.Update: - - if (_nextUpdateProcessSlot >= UpdateProcesses.Length) - { - IEnumerator[] oldProcArray = UpdateProcesses; - bool[] oldPausedArray = UpdatePaused; - bool[] oldHeldArray = UpdateHeld; - - UpdateProcesses = new IEnumerator[UpdateProcesses.Length + (ProcessArrayChunkSize * _expansions++)]; - UpdatePaused = new bool[UpdateProcesses.Length]; - UpdateHeld = new bool[UpdateProcesses.Length]; - - for (int i = 0; i < oldProcArray.Length; i++) - { - UpdateProcesses[i] = oldProcArray[i]; - UpdatePaused[i] = oldPausedArray[i]; - UpdateHeld[i] = oldHeldArray[i]; - } - } - - if (UpdateTimeValues(slot.seg)) - _lastUpdateProcessSlot = _nextUpdateProcessSlot; - - slot.i = _nextUpdateProcessSlot++; - UpdateProcesses[slot.i] = coroutine; - - if (null != tag) - AddTag(tag, handle); - - _indexToHandle.Add(slot, handle); - _handleToIndex.Add(handle, slot); - - while (prewarm) - { - if (!UpdateProcesses[slot.i].MoveNext()) - { - if (_indexToHandle.ContainsKey(slot)) - KillCoroutinesOnInstance(_indexToHandle[slot]); - - prewarm = false; - } - else if (UpdateProcesses[slot.i] != null && float.IsNaN(UpdateProcesses[slot.i].Current)) - { - if (ReplacementFunction != null) - { - UpdateProcesses[slot.i] = ReplacementFunction(UpdateProcesses[slot.i], _indexToHandle[slot]); - ReplacementFunction = null; - } - prewarm = !UpdatePaused[slot.i] && !UpdateHeld[slot.i]; - } - else - { - prewarm = false; - } - } - - break; - - case Segment.FixedUpdate: - - if (_nextFixedUpdateProcessSlot >= FixedUpdateProcesses.Length) - { - IEnumerator[] oldProcArray = FixedUpdateProcesses; - bool[] oldPausedArray = FixedUpdatePaused; - bool[] oldHeldArray = FixedUpdateHeld; - - FixedUpdateProcesses = new IEnumerator[FixedUpdateProcesses.Length + (ProcessArrayChunkSize * _expansions++)]; - FixedUpdatePaused = new bool[FixedUpdateProcesses.Length]; - FixedUpdateHeld = new bool[FixedUpdateProcesses.Length]; - - for (int i = 0; i < oldProcArray.Length; i++) - { - FixedUpdateProcesses[i] = oldProcArray[i]; - FixedUpdatePaused[i] = oldPausedArray[i]; - FixedUpdateHeld[i] = oldHeldArray[i]; - } - } - - if (UpdateTimeValues(slot.seg)) - _lastFixedUpdateProcessSlot = _nextFixedUpdateProcessSlot; - - slot.i = _nextFixedUpdateProcessSlot++; - FixedUpdateProcesses[slot.i] = coroutine; - - if (null != tag) - AddTag(tag, handle); - - _indexToHandle.Add(slot, handle); - _handleToIndex.Add(handle, slot); - - while (prewarm) - { - if (!FixedUpdateProcesses[slot.i].MoveNext()) - { - if (_indexToHandle.ContainsKey(slot)) - KillCoroutinesOnInstance(_indexToHandle[slot]); - - prewarm = false; - } - else if (FixedUpdateProcesses[slot.i] != null && float.IsNaN(FixedUpdateProcesses[slot.i].Current)) - { - if (ReplacementFunction != null) - { - FixedUpdateProcesses[slot.i] = ReplacementFunction(FixedUpdateProcesses[slot.i], _indexToHandle[slot]); - ReplacementFunction = null; - } - prewarm = !FixedUpdatePaused[slot.i] && !FixedUpdateHeld[slot.i]; - } - else - { - prewarm = false; - } - } - - break; - - case Segment.LateUpdate: - - if (_nextLateUpdateProcessSlot >= LateUpdateProcesses.Length) - { - IEnumerator[] oldProcArray = LateUpdateProcesses; - bool[] oldPausedArray = LateUpdatePaused; - bool[] oldHeldArray = LateUpdateHeld; - - LateUpdateProcesses = new IEnumerator[LateUpdateProcesses.Length + (ProcessArrayChunkSize * _expansions++)]; - LateUpdatePaused = new bool[LateUpdateProcesses.Length]; - LateUpdateHeld = new bool[LateUpdateProcesses.Length]; - - for (int i = 0; i < oldProcArray.Length; i++) - { - LateUpdateProcesses[i] = oldProcArray[i]; - LateUpdatePaused[i] = oldPausedArray[i]; - LateUpdateHeld[i] = oldHeldArray[i]; - } - } - - if (UpdateTimeValues(slot.seg)) - _lastLateUpdateProcessSlot = _nextLateUpdateProcessSlot; - - slot.i = _nextLateUpdateProcessSlot++; - LateUpdateProcesses[slot.i] = coroutine; - - if (tag != null) - AddTag(tag, handle); - - _indexToHandle.Add(slot, handle); - _handleToIndex.Add(handle, slot); - - while (prewarm) - { - if (!LateUpdateProcesses[slot.i].MoveNext()) - { - if (_indexToHandle.ContainsKey(slot)) - KillCoroutinesOnInstance(_indexToHandle[slot]); - - prewarm = false; - } - else if (LateUpdateProcesses[slot.i] != null && float.IsNaN(LateUpdateProcesses[slot.i].Current)) - { - if (ReplacementFunction != null) - { - LateUpdateProcesses[slot.i] = ReplacementFunction(LateUpdateProcesses[slot.i], _indexToHandle[slot]); - ReplacementFunction = null; - } - prewarm = !LateUpdatePaused[slot.i] && !LateUpdateHeld[slot.i]; - } - else - { - prewarm = false; - } - } - - break; - - case Segment.SlowUpdate: - - if (_nextSlowUpdateProcessSlot >= SlowUpdateProcesses.Length) - { - IEnumerator[] oldProcArray = SlowUpdateProcesses; - bool[] oldPausedArray = SlowUpdatePaused; - bool[] oldHeldArray = SlowUpdateHeld; - - SlowUpdateProcesses = new IEnumerator[SlowUpdateProcesses.Length + (ProcessArrayChunkSize * _expansions++)]; - SlowUpdatePaused = new bool[SlowUpdateProcesses.Length]; - SlowUpdateHeld = new bool[SlowUpdateProcesses.Length]; - - for (int i = 0; i < oldProcArray.Length; i++) - { - SlowUpdateProcesses[i] = oldProcArray[i]; - SlowUpdatePaused[i] = oldPausedArray[i]; - SlowUpdateHeld[i] = oldHeldArray[i]; - } - } - - if (UpdateTimeValues(slot.seg)) - _lastSlowUpdateProcessSlot = _nextSlowUpdateProcessSlot; - - slot.i = _nextSlowUpdateProcessSlot++; - SlowUpdateProcesses[slot.i] = coroutine; - - if (tag != null) - AddTag(tag, handle); - - _indexToHandle.Add(slot, handle); - _handleToIndex.Add(handle, slot); - - while (prewarm) - { - if (!SlowUpdateProcesses[slot.i].MoveNext()) - { - if (_indexToHandle.ContainsKey(slot)) - KillCoroutinesOnInstance(_indexToHandle[slot]); - - prewarm = false; - } - else if (SlowUpdateProcesses[slot.i] != null && float.IsNaN(SlowUpdateProcesses[slot.i].Current)) - { - if (ReplacementFunction != null) - { - SlowUpdateProcesses[slot.i] = ReplacementFunction(SlowUpdateProcesses[slot.i], _indexToHandle[slot]); - ReplacementFunction = null; - } - prewarm = !SlowUpdatePaused[slot.i] && !SlowUpdateHeld[slot.i]; - } - else - { - prewarm = false; - } - } - - break; - - default: - handle = new CoroutineHandle(); - break; - } - - localTime = currentLocalTime; - deltaTime = currentDeltaTime; - currentCoroutine = cachedHandle; - - return handle; - } - - /// - /// This will kill all coroutines running on the main MEC instance and reset the context. - /// NOTE: If you call this function from within a running coroutine then you MUST end the current - /// coroutine. If the running coroutine has more work to do you may run a new "part 2" coroutine - /// function to complete the task before ending the current one. - /// - /// The number of coroutines that were killed. - public static int KillCoroutines() - { - return _instance == null ? 0 : _instance.KillCoroutinesOnInstance(); - } - - /// - /// This will kill all coroutines running on the current MEC instance and reset the context. - /// NOTE: If you call this function from within a running coroutine then you MUST end the current - /// coroutine. If the running coroutine has more work to do you may run a new "part 2" coroutine - /// function to complete the task before ending the current one. - /// - /// The number of coroutines that were killed. - public int KillCoroutinesOnInstance() - { - int retVal = _nextUpdateProcessSlot + _nextLateUpdateProcessSlot + _nextFixedUpdateProcessSlot + _nextSlowUpdateProcessSlot; - - UpdateProcesses = new IEnumerator[InitialBufferSizeLarge]; - UpdatePaused = new bool[InitialBufferSizeLarge]; - UpdateHeld = new bool[InitialBufferSizeLarge]; - UpdateCoroutines = 0; - _nextUpdateProcessSlot = 0; - - LateUpdateProcesses = new IEnumerator[InitialBufferSizeSmall]; - LateUpdatePaused = new bool[InitialBufferSizeSmall]; - LateUpdateHeld = new bool[InitialBufferSizeSmall]; - LateUpdateCoroutines = 0; - _nextLateUpdateProcessSlot = 0; - - FixedUpdateProcesses = new IEnumerator[InitialBufferSizeMedium]; - FixedUpdatePaused = new bool[InitialBufferSizeMedium]; - FixedUpdateHeld = new bool[InitialBufferSizeMedium]; - FixedUpdateCoroutines = 0; - _nextFixedUpdateProcessSlot = 0; - - SlowUpdateProcesses = new IEnumerator[InitialBufferSizeMedium]; - SlowUpdatePaused = new bool[InitialBufferSizeMedium]; - SlowUpdateHeld = new bool[InitialBufferSizeMedium]; - SlowUpdateCoroutines = 0; - _nextSlowUpdateProcessSlot = 0; - - _processTags.Clear(); - _taggedProcesses.Clear(); - _handleToIndex.Clear(); - _indexToHandle.Clear(); - _waitingTriggers.Clear(); - _expansions = (ushort)((_expansions / 2) + 1); - - return retVal; - } - - /// - /// Kills the instances of the coroutine handle if it exists. - /// - /// The handle of the coroutine to kill. - /// The number of coroutines that were found and killed (0 or 1). - public static int KillCoroutines(CoroutineHandle handle) - { - return ActiveInstances[handle.Key] != null ? GetInstance(handle.Key).KillCoroutinesOnInstance(handle) : 0; - } - - /// - /// Kills the instance of the coroutine handle on this Timing instance if it exists. - /// - /// The handle of the coroutine to kill. - /// The number of coroutines that were found and killed (0 or 1). - public int KillCoroutinesOnInstance(CoroutineHandle handle) - { - bool foundOne = false; - - if (_handleToIndex.ContainsKey(handle)) - { - if (_waitingTriggers.ContainsKey(handle)) - CloseWaitingProcess(handle); - - foundOne = CoindexExtract(_handleToIndex[handle]) != null; - RemoveTag(handle); - } - - return foundOne ? 1 : 0; - } - - /// - /// Kills all coroutines that have the given tag. - /// - /// All coroutines with this tag will be killed. - /// The number of coroutines that were found and killed. - public static int KillCoroutines(string tag) - { - return _instance == null ? 0 : _instance.KillCoroutinesOnInstance(tag); - } - - /// - /// Kills all coroutines that have the given tag. - /// - /// All coroutines with this tag will be killed. - /// The number of coroutines that were found and killed. - public int KillCoroutinesOnInstance(string tag) - { - if (tag == null) return 0; - int numberFound = 0; - - while (_taggedProcesses.ContainsKey(tag)) - { - var matchEnum = _taggedProcesses[tag].GetEnumerator(); - matchEnum.MoveNext(); - - if (Nullify(_handleToIndex[matchEnum.Current])) - { - if (_waitingTriggers.ContainsKey(matchEnum.Current)) - CloseWaitingProcess(matchEnum.Current); - - numberFound++; - } - - RemoveTag(matchEnum.Current); - - if (_handleToIndex.ContainsKey(matchEnum.Current)) - { - _indexToHandle.Remove(_handleToIndex[matchEnum.Current]); - _handleToIndex.Remove(matchEnum.Current); - } - } - - return numberFound; - } - - /// - /// This will pause all coroutines running on the current MEC instance until ResumeCoroutines is called. - /// - /// The number of coroutines that were paused. - public static int PauseCoroutines() - { - return _instance == null ? 0 : _instance.PauseCoroutinesOnInstance(); - } - - /// - /// This will pause all coroutines running on this MEC instance until ResumeCoroutinesOnInstance is called. - /// - /// The number of coroutines that were paused. - public int PauseCoroutinesOnInstance() - { - int count = 0; - int i; - for (i = 0; i < _nextUpdateProcessSlot; i++) - { - if (!UpdatePaused[i] && UpdateProcesses[i] != null) - { - count++; - UpdatePaused[i] = true; - - if (UpdateProcesses[i].Current > GetSegmentTime(Segment.Update)) - UpdateProcesses[i] = _InjectDelay(UpdateProcesses[i], - UpdateProcesses[i].Current - GetSegmentTime(Segment.Update)); - } - } - - for (i = 0; i < _nextLateUpdateProcessSlot; i++) - { - if (!LateUpdatePaused[i] && LateUpdateProcesses[i] != null) - { - count++; - LateUpdatePaused[i] = true; - - if (LateUpdateProcesses[i].Current > GetSegmentTime(Segment.LateUpdate)) - LateUpdateProcesses[i] = _InjectDelay(LateUpdateProcesses[i], - LateUpdateProcesses[i].Current - GetSegmentTime(Segment.LateUpdate)); - } - } - - for (i = 0; i < _nextFixedUpdateProcessSlot; i++) - { - if (!FixedUpdatePaused[i] && FixedUpdateProcesses[i] != null) - { - count++; - FixedUpdatePaused[i] = true; - - if (FixedUpdateProcesses[i].Current > GetSegmentTime(Segment.FixedUpdate)) - FixedUpdateProcesses[i] = _InjectDelay(FixedUpdateProcesses[i], - FixedUpdateProcesses[i].Current - GetSegmentTime(Segment.FixedUpdate)); - } - } - - for (i = 0; i < _nextSlowUpdateProcessSlot; i++) - { - if (!SlowUpdatePaused[i] && SlowUpdateProcesses[i] != null) - { - count++; - SlowUpdatePaused[i] = true; - - if (SlowUpdateProcesses[i].Current > GetSegmentTime(Segment.SlowUpdate)) - SlowUpdateProcesses[i] = _InjectDelay(SlowUpdateProcesses[i], - SlowUpdateProcesses[i].Current - GetSegmentTime(Segment.SlowUpdate)); - } - } - - return count; - } - - /// - /// This will pause any matching coroutines until ResumeCoroutines is called. - /// - /// The handle of the coroutine to pause. - /// The number of coroutines that were paused (0 or 1). - public static int PauseCoroutines(CoroutineHandle handle) - { - return ActiveInstances[handle.Key] != null ? GetInstance(handle.Key).PauseCoroutinesOnInstance(handle) : 0; - } - - /// - /// This will pause any matching coroutines running on this MEC instance until ResumeCoroutinesOnInstance is called. - /// - /// The handle of the coroutine to pause. - /// The number of coroutines that were paused (0 or 1). - public int PauseCoroutinesOnInstance(CoroutineHandle handle) - { - return _handleToIndex.ContainsKey(handle) && !CoindexIsNull(_handleToIndex[handle]) && !SetPause(_handleToIndex[handle], true) ? 1 : 0; - } - - /// - /// This will pause any matching coroutines running on the current MEC instance until ResumeCoroutines is called. - /// - /// Any coroutines with a matching tag will be paused. - /// The number of coroutines that were paused. - public static int PauseCoroutines(string tag) - { - return _instance == null ? 0 : _instance.PauseCoroutinesOnInstance(tag); - } - - /// - /// This will pause any matching coroutines running on this MEC instance until ResumeCoroutinesOnInstance is called. - /// - /// Any coroutines with a matching tag will be paused. - /// The number of coroutines that were paused. - public int PauseCoroutinesOnInstance(string tag) - { - if (tag == null || !_taggedProcesses.ContainsKey(tag)) - return 0; - - int count = 0; - var matchesEnum = _taggedProcesses[tag].GetEnumerator(); - - while (matchesEnum.MoveNext()) - if (!CoindexIsNull(_handleToIndex[matchesEnum.Current]) && !SetPause(_handleToIndex[matchesEnum.Current], true)) - count++; - - return count; - } - - /// - /// This resumes all coroutines on the current MEC instance if they are currently paused, otherwise it has - /// no effect. - /// - /// The number of coroutines that were resumed. - public static int ResumeCoroutines() - { - return _instance == null ? 0 : _instance.ResumeCoroutinesOnInstance(); - } - - /// - /// This resumes all coroutines on this MEC instance if they are currently paused, otherwise it has no effect. - /// - /// The number of coroutines that were resumed. - public int ResumeCoroutinesOnInstance() - { - int count = 0; - ProcessIndex coindex; - for (coindex.i = 0, coindex.seg = Segment.Update; coindex.i < _nextUpdateProcessSlot; coindex.i++) - { - if (UpdatePaused[coindex.i] && UpdateProcesses[coindex.i] != null) - { - UpdatePaused[coindex.i] = false; - count++; - } - } - - for (coindex.i = 0, coindex.seg = Segment.LateUpdate; coindex.i < _nextLateUpdateProcessSlot; coindex.i++) - { - if (LateUpdatePaused[coindex.i] && LateUpdateProcesses[coindex.i] != null) - { - LateUpdatePaused[coindex.i] = false; - count++; - } - } - - for (coindex.i = 0, coindex.seg = Segment.FixedUpdate; coindex.i < _nextFixedUpdateProcessSlot; coindex.i++) - { - if (FixedUpdatePaused[coindex.i] && FixedUpdateProcesses[coindex.i] != null) - { - FixedUpdatePaused[coindex.i] = false; - count++; - } - } - - for (coindex.i = 0, coindex.seg = Segment.SlowUpdate; coindex.i < _nextSlowUpdateProcessSlot; coindex.i++) - { - if (SlowUpdatePaused[coindex.i] && SlowUpdateProcesses[coindex.i] != null) - { - SlowUpdatePaused[coindex.i] = false; - count++; - } - } - - return count; - } - - /// - /// This will resume any matching coroutines. - /// - /// The handle of the coroutine to resume. - /// The number of coroutines that were resumed (0 or 1). - public static int ResumeCoroutines(CoroutineHandle handle) - { - return ActiveInstances[handle.Key] != null ? GetInstance(handle.Key).ResumeCoroutinesOnInstance(handle) : 0; - } - - /// - /// This will resume any matching coroutines running on this MEC instance. - /// - /// The handle of the coroutine to resume. - /// The number of coroutines that were resumed (0 or 1). - public int ResumeCoroutinesOnInstance(CoroutineHandle handle) - { - return _handleToIndex.ContainsKey(handle) && - !CoindexIsNull(_handleToIndex[handle]) && SetPause(_handleToIndex[handle], false) ? 1 : 0; - } - - /// - /// This resumes any matching coroutines on the current MEC instance if they are currently paused, otherwise it has - /// no effect. - /// - /// Any coroutines previously paused with a matching tag will be resumend. - /// The number of coroutines that were resumed. - public static int ResumeCoroutines(string tag) - { - return _instance == null ? 0 : _instance.ResumeCoroutinesOnInstance(tag); - } - - /// - /// This resumes any matching coroutines on this MEC instance if they are currently paused, otherwise it has no effect. - /// - /// Any coroutines previously paused with a matching tag will be resumend. - /// The number of coroutines that were resumed. - public int ResumeCoroutinesOnInstance(string tag) - { - if (tag == null || !_taggedProcesses.ContainsKey(tag)) - return 0; - int count = 0; - - var indexesEnum = _taggedProcesses[tag].GetEnumerator(); - while (indexesEnum.MoveNext()) - { - if (!CoindexIsNull(_handleToIndex[indexesEnum.Current]) && SetPause(_handleToIndex[indexesEnum.Current], false)) - { - count++; - } - } - - return count; - } - - private bool UpdateTimeValues(Segment segment) - { - switch(segment) - { - case Segment.Update: - if (_currentUpdateFrame != Time.frameCount) - { - deltaTime = Time.deltaTime; - _lastUpdateTime += deltaTime; - localTime = _lastUpdateTime; - _currentUpdateFrame = Time.frameCount; - return true; - } - else - { - deltaTime = Time.deltaTime; - localTime = _lastUpdateTime; - return false; - } - case Segment.LateUpdate: - if (_currentLateUpdateFrame != Time.frameCount) - { - deltaTime = Time.deltaTime; - _lastLateUpdateTime += deltaTime; - localTime = _lastLateUpdateTime; - _currentLateUpdateFrame = Time.frameCount; - return true; - } - else - { - deltaTime = Time.deltaTime; - localTime = _lastLateUpdateTime; - return false; - } - case Segment.FixedUpdate: - deltaTime = Time.fixedDeltaTime; - localTime = Time.fixedTime; - - if (_lastFixedUpdateTime + 0.0001f < Time.fixedTime) - { - _lastFixedUpdateTime = Time.fixedTime; - return true; - } - - return false; - case Segment.SlowUpdate: - if (_currentSlowUpdateFrame != Time.frameCount) - { - deltaTime = _lastSlowUpdateDeltaTime = Time.realtimeSinceStartup - _lastSlowUpdateTime; - localTime = _lastSlowUpdateTime = Time.realtimeSinceStartup; - _currentSlowUpdateFrame = Time.frameCount; - return true; - } - else - { - deltaTime = _lastSlowUpdateDeltaTime; - localTime = _lastSlowUpdateTime; - return false; - } - } - return true; - } - - private float GetSegmentTime(Segment segment) - { - switch (segment) - { - case Segment.Update: - if (_currentUpdateFrame == Time.frameCount) - return _lastUpdateTime; - else - return _lastUpdateTime + Time.deltaTime; - case Segment.LateUpdate: - if (_currentUpdateFrame == Time.frameCount) - return _lastLateUpdateTime; - else - return _lastLateUpdateTime + Time.deltaTime; - case Segment.FixedUpdate: - return Time.fixedTime; - case Segment.SlowUpdate: - return Time.realtimeSinceStartup; - default: - return 0f; - } - } - - /// - /// Retrieves the MEC manager that corresponds to the supplied instance id. - /// - /// The instance ID. - /// The manager, or null if not found. - public static Timing GetInstance(byte ID) - { - if (ID >= 0x10) - return null; - return ActiveInstances[ID]; - } - - private void AddTag(string tag, CoroutineHandle coindex) - { - _processTags.Add(coindex, tag); - - if (_taggedProcesses.ContainsKey(tag)) - _taggedProcesses[tag].Add(coindex); - else - _taggedProcesses.Add(tag, new HashSet { coindex }); - } - - private void RemoveTag(CoroutineHandle coindex) - { - if (_processTags.ContainsKey(coindex)) - { - if (_taggedProcesses[_processTags[coindex]].Count > 1) - _taggedProcesses[_processTags[coindex]].Remove(coindex); - else - _taggedProcesses.Remove(_processTags[coindex]); - - _processTags.Remove(coindex); - } - } - - /// Whether it was already null. - private bool Nullify(ProcessIndex coindex) - { - bool retVal; - - switch (coindex.seg) - { - case Segment.Update: - retVal = UpdateProcesses[coindex.i] != null; - UpdateProcesses[coindex.i] = null; - return retVal; - case Segment.FixedUpdate: - retVal = FixedUpdateProcesses[coindex.i] != null; - FixedUpdateProcesses[coindex.i] = null; - return retVal; - case Segment.LateUpdate: - retVal = LateUpdateProcesses[coindex.i] != null; - LateUpdateProcesses[coindex.i] = null; - return retVal; - case Segment.SlowUpdate: - retVal = SlowUpdateProcesses[coindex.i] != null; - SlowUpdateProcesses[coindex.i] = null; - return retVal; - default: - return false; - } - } - - private IEnumerator CoindexExtract(ProcessIndex coindex) - { - IEnumerator retVal; - - switch (coindex.seg) - { - case Segment.Update: - retVal = UpdateProcesses[coindex.i]; - UpdateProcesses[coindex.i] = null; - return retVal; - case Segment.FixedUpdate: - retVal = FixedUpdateProcesses[coindex.i]; - FixedUpdateProcesses[coindex.i] = null; - return retVal; - case Segment.LateUpdate: - retVal = LateUpdateProcesses[coindex.i]; - LateUpdateProcesses[coindex.i] = null; - return retVal; - case Segment.SlowUpdate: - retVal = SlowUpdateProcesses[coindex.i]; - SlowUpdateProcesses[coindex.i] = null; - return retVal; - default: - return null; - } - } - - private IEnumerator CoindexPeek(ProcessIndex coindex) - { - switch (coindex.seg) - { - case Segment.Update: - return UpdateProcesses[coindex.i]; - case Segment.FixedUpdate: - return FixedUpdateProcesses[coindex.i]; - case Segment.LateUpdate: - return LateUpdateProcesses[coindex.i]; - case Segment.SlowUpdate: - return SlowUpdateProcesses[coindex.i]; - default: - return null; - } - } - - private bool CoindexIsNull(ProcessIndex coindex) - { - switch (coindex.seg) - { - case Segment.Update: - return UpdateProcesses[coindex.i] == null; - case Segment.FixedUpdate: - return FixedUpdateProcesses[coindex.i] == null; - case Segment.LateUpdate: - return LateUpdateProcesses[coindex.i] == null; - case Segment.SlowUpdate: - return SlowUpdateProcesses[coindex.i] == null; - default: - return true; - } - } - - private bool SetPause(ProcessIndex coindex, bool newPausedState) - { - if (CoindexPeek(coindex) == null) - return false; - - bool isPaused; - - switch (coindex.seg) - { - case Segment.Update: - isPaused = UpdatePaused[coindex.i]; - UpdatePaused[coindex.i] = newPausedState; - - if (newPausedState && UpdateProcesses[coindex.i].Current > GetSegmentTime(coindex.seg)) - UpdateProcesses[coindex.i] = _InjectDelay(UpdateProcesses[coindex.i], - UpdateProcesses[coindex.i].Current - GetSegmentTime(coindex.seg)); - - return isPaused; - case Segment.FixedUpdate: - isPaused = FixedUpdatePaused[coindex.i]; - FixedUpdatePaused[coindex.i] = newPausedState; - - if (newPausedState && FixedUpdateProcesses[coindex.i].Current > GetSegmentTime(coindex.seg)) - FixedUpdateProcesses[coindex.i] = _InjectDelay(FixedUpdateProcesses[coindex.i], - FixedUpdateProcesses[coindex.i].Current - GetSegmentTime(coindex.seg)); - - return isPaused; - case Segment.LateUpdate: - isPaused = LateUpdatePaused[coindex.i]; - LateUpdatePaused[coindex.i] = newPausedState; - - if (newPausedState && LateUpdateProcesses[coindex.i].Current > GetSegmentTime(coindex.seg)) - LateUpdateProcesses[coindex.i] = _InjectDelay(LateUpdateProcesses[coindex.i], - LateUpdateProcesses[coindex.i].Current - GetSegmentTime(coindex.seg)); - - return isPaused; - case Segment.SlowUpdate: - isPaused = SlowUpdatePaused[coindex.i]; - SlowUpdatePaused[coindex.i] = newPausedState; - - if (newPausedState && SlowUpdateProcesses[coindex.i].Current > GetSegmentTime(coindex.seg)) - SlowUpdateProcesses[coindex.i] = _InjectDelay(SlowUpdateProcesses[coindex.i], - SlowUpdateProcesses[coindex.i].Current - GetSegmentTime(coindex.seg)); - - return isPaused; - default: - return false; - } - } - - private bool SetHeld(ProcessIndex coindex, bool newHeldState) - { - if (CoindexPeek(coindex) == null) - return false; - - bool isHeld; - - switch (coindex.seg) - { - case Segment.Update: - isHeld = UpdateHeld[coindex.i]; - UpdateHeld[coindex.i] = newHeldState; - - if (newHeldState && UpdateProcesses[coindex.i].Current > GetSegmentTime(coindex.seg)) - UpdateProcesses[coindex.i] = _InjectDelay(UpdateProcesses[coindex.i], - UpdateProcesses[coindex.i].Current - GetSegmentTime(coindex.seg)); - - return isHeld; - case Segment.FixedUpdate: - isHeld = FixedUpdateHeld[coindex.i]; - FixedUpdateHeld[coindex.i] = newHeldState; - - if (newHeldState && FixedUpdateProcesses[coindex.i].Current > GetSegmentTime(coindex.seg)) - FixedUpdateProcesses[coindex.i] = _InjectDelay(FixedUpdateProcesses[coindex.i], - FixedUpdateProcesses[coindex.i].Current - GetSegmentTime(coindex.seg)); - - return isHeld; - case Segment.LateUpdate: - isHeld = LateUpdateHeld[coindex.i]; - LateUpdateHeld[coindex.i] = newHeldState; - - if (newHeldState && LateUpdateProcesses[coindex.i].Current > GetSegmentTime(coindex.seg)) - LateUpdateProcesses[coindex.i] = _InjectDelay(LateUpdateProcesses[coindex.i], - LateUpdateProcesses[coindex.i].Current - GetSegmentTime(coindex.seg)); - - return isHeld; - case Segment.SlowUpdate: - isHeld = SlowUpdateHeld[coindex.i]; - SlowUpdateHeld[coindex.i] = newHeldState; - - if (newHeldState && SlowUpdateProcesses[coindex.i].Current > GetSegmentTime(coindex.seg)) - SlowUpdateProcesses[coindex.i] = _InjectDelay(SlowUpdateProcesses[coindex.i], - SlowUpdateProcesses[coindex.i].Current - GetSegmentTime(coindex.seg)); - - return isHeld; - default: - return false; - } - } - - private IEnumerator _InjectDelay(IEnumerator proc, float delayTime) - { - yield return WaitForSecondsOnInstance(delayTime); - - _tmpRef = proc; - ReplacementFunction = ReturnTmpRefForRepFunc; - yield return float.NaN; - } - - private bool CoindexIsPaused(ProcessIndex coindex) - { - switch (coindex.seg) - { - case Segment.Update: - return UpdatePaused[coindex.i]; - case Segment.FixedUpdate: - return FixedUpdatePaused[coindex.i]; - case Segment.LateUpdate: - return LateUpdatePaused[coindex.i]; - case Segment.SlowUpdate: - return SlowUpdatePaused[coindex.i]; - default: - return false; - } - } - - private bool CoindexIsHeld(ProcessIndex coindex) - { - switch (coindex.seg) - { - case Segment.Update: - return UpdateHeld[coindex.i]; - case Segment.FixedUpdate: - return FixedUpdateHeld[coindex.i]; - case Segment.LateUpdate: - return LateUpdateHeld[coindex.i]; - case Segment.SlowUpdate: - return SlowUpdateHeld[coindex.i]; - default: - return false; - } - } - - private void CoindexReplace(ProcessIndex coindex, IEnumerator replacement) - { - switch (coindex.seg) - { - case Segment.Update: - UpdateProcesses[coindex.i] = replacement; - return; - case Segment.FixedUpdate: - FixedUpdateProcesses[coindex.i] = replacement; - return; - case Segment.LateUpdate: - LateUpdateProcesses[coindex.i] = replacement; - return; - case Segment.SlowUpdate: - SlowUpdateProcesses[coindex.i] = replacement; - return; - } - } - - /// - /// Use "yield return Timing.WaitForSeconds(time);" to wait for the specified number of seconds. - /// - /// Number of seconds to wait. - public static float WaitForSeconds(float waitTime) - { - if (float.IsNaN(waitTime)) waitTime = 0f; - return LocalTime + waitTime; - } - - /// - /// Use "yield return timingInstance.WaitForSecondsOnInstance(time);" to wait for the specified number of seconds. - /// - /// Number of seconds to wait. - public float WaitForSecondsOnInstance(float waitTime) - { - if (float.IsNaN(waitTime)) waitTime = 0f; - return localTime + waitTime; - } - - /// - /// Use the command "yield return Timing.WaitUntilDone(otherCoroutine);" to pause the current - /// coroutine until otherCoroutine is done. - /// - /// The coroutine to pause for. - public static float WaitUntilDone(CoroutineHandle otherCoroutine) - { - return WaitUntilDone(otherCoroutine, true); - } - - /// - /// Use the command "yield return Timing.WaitUntilDone(otherCoroutine, false);" to pause the current - /// coroutine until otherCoroutine is done, supressing warnings. - /// - /// The coroutine to pause for. - /// Post a warning to the console if no hold action was actually performed. - public static float WaitUntilDone(CoroutineHandle otherCoroutine, bool warnOnIssue) - { - Timing inst = GetInstance(otherCoroutine.Key); - - if (inst != null && inst._handleToIndex.ContainsKey(otherCoroutine)) - { - if (inst.CoindexIsNull(inst._handleToIndex[otherCoroutine])) - return 0f; - - if (!inst._waitingTriggers.ContainsKey(otherCoroutine)) - { - inst.CoindexReplace(inst._handleToIndex[otherCoroutine], - inst._StartWhenDone(otherCoroutine, inst.CoindexPeek(inst._handleToIndex[otherCoroutine]))); - inst._waitingTriggers.Add(otherCoroutine, new HashSet()); - } - - if (inst.currentCoroutine == otherCoroutine) - { - Assert.IsFalse(warnOnIssue, "A coroutine cannot wait for itself."); - return WaitForOneFrame; - } - if (!inst.currentCoroutine.IsValid) - { - Assert.IsFalse(warnOnIssue, "The two coroutines are not running on the same MEC instance."); - return WaitForOneFrame; - } - - inst._waitingTriggers[otherCoroutine].Add(inst.currentCoroutine); - if (!inst._allWaiting.Contains(inst.currentCoroutine)) - inst._allWaiting.Add(inst.currentCoroutine); - inst.SetHeld(inst._handleToIndex[inst.currentCoroutine], true); - inst.SwapToLast(otherCoroutine, inst.currentCoroutine); - - return float.NaN; - } - - Assert.IsFalse(warnOnIssue, "WaitUntilDone cannot hold: The coroutine handle that was passed in is invalid.\n" + otherCoroutine); - return WaitForOneFrame; - } - - private IEnumerator _StartWhenDone(CoroutineHandle handle, IEnumerator proc) - { - if (!_waitingTriggers.ContainsKey(handle)) yield break; - - try - { - if (proc.Current > localTime) - yield return proc.Current; - - while (proc.MoveNext()) - yield return proc.Current; - } - finally - { - CloseWaitingProcess(handle); - } - } - - private void SwapToLast(CoroutineHandle firstHandle, CoroutineHandle lastHandle) - { - if (firstHandle.Key != lastHandle.Key) - return; - - ProcessIndex firstIndex = _handleToIndex[firstHandle]; - ProcessIndex lastIndex = _handleToIndex[lastHandle]; - - if (firstIndex.seg != lastIndex.seg || firstIndex.i < lastIndex.i) - return; - - IEnumerator tempCoptr = CoindexPeek(firstIndex); - CoindexReplace(firstIndex, CoindexPeek(lastIndex)); - CoindexReplace(lastIndex, tempCoptr); - - _indexToHandle[firstIndex] = lastHandle; - _indexToHandle[lastIndex] = firstHandle; - _handleToIndex[firstHandle] = lastIndex; - _handleToIndex[lastHandle] = firstIndex; - bool tmpB = SetPause(firstIndex, CoindexIsPaused(lastIndex)); - SetPause(lastIndex, tmpB); - tmpB = SetHeld(firstIndex, CoindexIsHeld(lastIndex)); - SetHeld(lastIndex, tmpB); - - if (_waitingTriggers.ContainsKey(lastHandle)) - { - var trigsEnum = _waitingTriggers[lastHandle].GetEnumerator(); - while (trigsEnum.MoveNext()) - SwapToLast(lastHandle, trigsEnum.Current); - } - - if (_allWaiting.Contains(firstHandle)) - { - var keyEnum = _waitingTriggers.GetEnumerator(); - while (keyEnum.MoveNext()) - { - var valueEnum = keyEnum.Current.Value.GetEnumerator(); - while (valueEnum.MoveNext()) - if (valueEnum.Current == firstHandle) - SwapToLast(keyEnum.Current.Key, firstHandle); - } - } - } - - private void CloseWaitingProcess(CoroutineHandle handle) - { - if (!_waitingTriggers.ContainsKey(handle)) return; - - var tasksEnum = _waitingTriggers[handle].GetEnumerator(); - _waitingTriggers.Remove(handle); - - while (tasksEnum.MoveNext()) - { - if (_handleToIndex.ContainsKey(tasksEnum.Current) && !HandleIsInWaitingList(tasksEnum.Current)) - { - SetHeld(_handleToIndex[tasksEnum.Current], false); - _allWaiting.Remove(tasksEnum.Current); - } - } - } - - private bool HandleIsInWaitingList(CoroutineHandle handle) - { - var triggersEnum = _waitingTriggers.GetEnumerator(); - while (triggersEnum.MoveNext()) - if (triggersEnum.Current.Value.Contains(handle)) - return true; - - return false; - } - - private static IEnumerator ReturnTmpRefForRepFunc(IEnumerator coptr, CoroutineHandle handle) - { - return _tmpRef as IEnumerator; - } - -#if !UNITY_2018_3_OR_NEWER - /// - /// Use the command "yield return Timing.WaitUntilDone(wwwObject);" to pause the current - /// coroutine until the wwwObject is done. - /// - /// The www object to pause for. - public static float WaitUntilDone(WWW wwwObject) - { - if (wwwObject == null || wwwObject.isDone) return 0f; - - _tmpRef = wwwObject; - ReplacementFunction = WaitUntilDoneWwwHelper; - return float.NaN; - } - - - private static IEnumerator WaitUntilDoneWwwHelper(IEnumerator coptr, CoroutineHandle handle) - { - return _StartWhenDone(_tmpRef as WWW, coptr); - } - - private static IEnumerator _StartWhenDone(WWW www, IEnumerator pausedProc) - { - while (!www.isDone) - yield return WaitForOneFrame; - - _tmpRef = pausedProc; - ReplacementFunction = ReturnTmpRefForRepFunc; - yield return float.NaN; - } -#endif - - /// - /// Use the command "yield return Timing.WaitUntilDone(operation);" to pause the current - /// coroutine until the operation is done. - /// - /// The operation variable returned. - public static float WaitUntilDone(AsyncOperation operation) - { - if (operation == null || operation.isDone) return float.NaN; - - CoroutineHandle handle = CurrentCoroutine; - Timing inst = GetInstance(CurrentCoroutine.Key); - if (inst == null) return float.NaN; - - _tmpRef = _StartWhenDone(operation, inst.CoindexPeek(inst._handleToIndex[handle])); - ReplacementFunction = ReturnTmpRefForRepFunc; - return float.NaN; - } - - private static IEnumerator _StartWhenDone(AsyncOperation operation, IEnumerator pausedProc) - { - while (!operation.isDone) - yield return WaitForOneFrame; - - _tmpRef = pausedProc; - ReplacementFunction = ReturnTmpRefForRepFunc; - yield return float.NaN; - } - - /// - /// Use the command "yield return Timing.WaitUntilDone(operation);" to pause the current - /// coroutine until the operation is done. - /// - /// The operation variable returned. - public static float WaitUntilDone(CustomYieldInstruction operation) - { - if (operation == null || !operation.keepWaiting) return float.NaN; - - CoroutineHandle handle = CurrentCoroutine; - Timing inst = GetInstance(CurrentCoroutine.Key); - if (inst == null) return float.NaN; - - _tmpRef = _StartWhenDone(operation, inst.CoindexPeek(inst._handleToIndex[handle])); - ReplacementFunction = ReturnTmpRefForRepFunc; - return float.NaN; - } - - private static IEnumerator _StartWhenDone(CustomYieldInstruction operation, IEnumerator pausedProc) - { - while (operation.keepWaiting) - yield return WaitForOneFrame; - - _tmpRef = pausedProc; - ReplacementFunction = ReturnTmpRefForRepFunc; - yield return float.NaN; - } - - /// - /// Keeps this coroutine from executing until UnlockCoroutine is called with a matching key. - /// - /// The handle to the coroutine to be locked. - /// The key to use. A new key can be generated by calling "new CoroutineHandle(0)". - /// Whether the lock was successful. - public bool LockCoroutine(CoroutineHandle coroutine, CoroutineHandle key) - { - if (coroutine.Key != _instanceID || key == new CoroutineHandle() || key.Key != 0) - return false; - - if (!_waitingTriggers.ContainsKey(key)) - _waitingTriggers.Add(key, new HashSet { coroutine }); - else - _waitingTriggers[key].Add(coroutine); - - _allWaiting.Add(coroutine); - - SetHeld(_handleToIndex[coroutine], true); - - return true; - } - - /// - /// Unlocks a coroutine that has been locked, so long as the key matches. - /// - /// The handle to the coroutine to be unlocked. - /// The key that the coroutine was previously locked with. - /// Whether the coroutine was successfully unlocked. - public bool UnlockCoroutine(CoroutineHandle coroutine, CoroutineHandle key) - { - if (coroutine.Key != _instanceID || key == new CoroutineHandle() || - !_handleToIndex.ContainsKey(coroutine) || !_waitingTriggers.ContainsKey(key)) - return false; - - if (_waitingTriggers[key].Count == 1) - _waitingTriggers.Remove(key); - else - _waitingTriggers[key].Remove(coroutine); - - if (!HandleIsInWaitingList(coroutine)) - { - SetHeld(_handleToIndex[coroutine], false); - _allWaiting.Remove(coroutine); - } - - return true; - } - - /// - /// Calls the specified action after a specified number of seconds. - /// - /// The number of seconds to wait before calling the action. - /// The action to call. - /// The handle to the coroutine that is started by this function. - public static CoroutineHandle CallDelayed(float delay, System.Action action) - { - return action == null ? new CoroutineHandle() : RunCoroutine(Instance._DelayedCall(delay, action, null)); - } - - /// - /// Calls the specified action after a specified number of seconds. - /// - /// The number of seconds to wait before calling the action. - /// The action to call. - /// The handle to the coroutine that is started by this function. - public CoroutineHandle CallDelayedOnInstance(float delay, System.Action action) - { - return action == null ? new CoroutineHandle() : RunCoroutineOnInstance(_DelayedCall(delay, action, null)); - } - - /// - /// Calls the specified action after a specified number of seconds. - /// - /// The number of seconds to wait before calling the action. - /// The action to call. - /// A GameObject that will be checked to make sure it hasn't been destroyed before calling the action. - /// The handle to the coroutine that is started by this function. - public static CoroutineHandle CallDelayed(float delay, System.Action action, GameObject cancelWith) - { - return action == null ? new CoroutineHandle() : RunCoroutine(Instance._DelayedCall(delay, action, cancelWith)); - } - - /// - /// Calls the specified action after a specified number of seconds. - /// - /// The number of seconds to wait before calling the action. - /// The action to call. - /// A GameObject that will be checked to make sure it hasn't been destroyed before calling the action. - /// The handle to the coroutine that is started by this function. - public CoroutineHandle CallDelayedOnInstance(float delay, System.Action action, GameObject cancelWith) - { - return action == null ? new CoroutineHandle() : RunCoroutineOnInstance(_DelayedCall(delay, action, cancelWith)); - } - - /// - /// Calls the specified action after a specified number of seconds. - /// - /// The number of seconds to wait before calling the action. - /// The action to call. - /// The timing segment that the call should be made in. - /// The handle to the coroutine that is started by this function. - public static CoroutineHandle CallDelayed(float delay, Segment segment, System.Action action) - { - return action == null ? new CoroutineHandle() : RunCoroutine(Instance._DelayedCall(delay, action, null), segment); - } - - /// - /// Calls the specified action after a specified number of seconds. - /// - /// The number of seconds to wait before calling the action. - /// The action to call. - /// The timing segment that the call should be made in. - /// The handle to the coroutine that is started by this function. - public CoroutineHandle CallDelayedOnInstance(float delay, Segment segment, System.Action action) - { - return action == null ? new CoroutineHandle() : RunCoroutineOnInstance(_DelayedCall(delay, action, null), segment); - } - - /// - /// Calls the specified action after a specified number of seconds. - /// - /// The number of seconds to wait before calling the action. - /// The action to call. - /// A GameObject that will be checked to make sure it hasn't been destroyed - /// before calling the action. - /// The timing segment that the call should be made in. - /// The handle to the coroutine that is started by this function. - public static CoroutineHandle CallDelayed(float delay, Segment segment, System.Action action, GameObject gameObject) - { - return action == null ? new CoroutineHandle() : RunCoroutine(Instance._DelayedCall(delay, action, gameObject), segment); - } - - /// - /// Calls the specified action after a specified number of seconds. - /// - /// The number of seconds to wait before calling the action. - /// The action to call. - /// A GameObject that will be tagged onto the coroutine and checked to make sure it hasn't been destroyed - /// before calling the action. - /// The timing segment that the call should be made in. - /// The handle to the coroutine that is started by this function. - public CoroutineHandle CallDelayedOnInstance(float delay, Segment segment, System.Action action, GameObject gameObject) - { - return action == null ? new CoroutineHandle() : RunCoroutineOnInstance(_DelayedCall(delay, action, gameObject), segment); - } - - private IEnumerator _DelayedCall(float delay, System.Action action, GameObject cancelWith) - { - yield return WaitForSecondsOnInstance(delay); - - if(ReferenceEquals(cancelWith, null) || cancelWith != null) - action(); - } - - /// - /// Calls the supplied action at the given rate for a given number of seconds. - /// - /// The number of seconds that this function should run. - /// The amount of time between calls. - /// The action to call every frame. - /// An optional action to call when this function finishes. - /// The handle to the coroutine that is started by this function. - public static CoroutineHandle CallPeriodically(float timeframe, float period, System.Action action, System.Action onDone = null) - { - return action == null ? new CoroutineHandle() : RunCoroutine(Instance._CallContinuously(timeframe, period, action, onDone), Segment.Update); - } - - /// - /// Calls the supplied action at the given rate for a given number of seconds. - /// - /// The number of seconds that this function should run. - /// The amount of time between calls. - /// The action to call every frame. - /// An optional action to call when this function finishes. - /// The handle to the coroutine that is started by this function. - public CoroutineHandle CallPeriodicallyOnInstance(float timeframe, float period, System.Action action, System.Action onDone = null) - { - return action == null ? new CoroutineHandle() : RunCoroutineOnInstance(_CallContinuously(timeframe, period, action, onDone), Segment.Update); - } - - /// - /// Calls the supplied action at the given rate for a given number of seconds. - /// - /// The number of seconds that this function should run. - /// The amount of time between calls. - /// The action to call every frame. - /// The timing segment to run in. - /// An optional action to call when this function finishes. - /// The handle to the coroutine that is started by this function. - public static CoroutineHandle CallPeriodically(float timeframe, float period, System.Action action, Segment segment, System.Action onDone = null) - { - return action == null ? new CoroutineHandle() : RunCoroutine(Instance._CallContinuously(timeframe, period, action, onDone), segment); - } - - /// - /// Calls the supplied action at the given rate for a given number of seconds. - /// - /// The number of seconds that this function should run. - /// The amount of time between calls. - /// The action to call every frame. - /// The timing segment to run in. - /// An optional action to call when this function finishes. - /// The handle to the coroutine that is started by this function. - public CoroutineHandle CallPeriodicallyOnInstance(float timeframe, float period, System.Action action, Segment segment, System.Action onDone = null) - { - return action == null ? new CoroutineHandle() : RunCoroutineOnInstance(_CallContinuously(timeframe, period, action, onDone), segment); - } - - /// - /// Calls the supplied action at the given rate for a given number of seconds. - /// - /// The number of seconds that this function should run. - /// The action to call every frame. - /// An optional action to call when this function finishes. - /// The handle to the coroutine that is started by this function. - public static CoroutineHandle CallContinuously(float timeframe, System.Action action, System.Action onDone = null) - { - return action == null ? new CoroutineHandle() : RunCoroutine(Instance._CallContinuously(timeframe, 0f, action, onDone), Segment.Update); - } - - /// - /// Calls the supplied action at the given rate for a given number of seconds. - /// - /// The number of seconds that this function should run. - /// The action to call every frame. - /// An optional action to call when this function finishes. - /// The handle to the coroutine that is started by this function. - public CoroutineHandle CallContinuouslyOnInstance(float timeframe, System.Action action, System.Action onDone = null) - { - return action == null ? new CoroutineHandle() : RunCoroutineOnInstance(_CallContinuously(timeframe, 0f, action, onDone), Segment.Update); - } - - /// - /// Calls the supplied action every frame for a given number of seconds. - /// - /// The number of seconds that this function should run. - /// The action to call every frame. - /// The timing segment to run in. - /// An optional action to call when this function finishes. - /// The handle to the coroutine that is started by this function. - public static CoroutineHandle CallContinuously(float timeframe, System.Action action, Segment timing, System.Action onDone = null) - { - return action == null ? new CoroutineHandle() : RunCoroutine(Instance._CallContinuously(timeframe, 0f, action, onDone), timing); - } - - /// - /// Calls the supplied action every frame for a given number of seconds. - /// - /// The number of seconds that this function should run. - /// The action to call every frame. - /// The timing segment to run in. - /// An optional action to call when this function finishes. - /// The handle to the coroutine that is started by this function. - public CoroutineHandle CallContinuouslyOnInstance(float timeframe, System.Action action, Segment timing, System.Action onDone = null) - { - return action == null ? new CoroutineHandle() : RunCoroutineOnInstance(_CallContinuously(timeframe, 0f, action, onDone), timing); - } - - private IEnumerator _CallContinuously(float timeframe, float period, System.Action action, System.Action onDone) - { - double startTime = localTime; - while (localTime <= startTime + timeframe) - { - yield return WaitForSecondsOnInstance(period); - - action(); - } - - if (onDone != null) - onDone(); - } - - /// - /// Calls the supplied action at the given rate for a given number of seconds. - /// - /// A value that will be passed in to the supplied action each period. - /// The number of seconds that this function should run. - /// The amount of time between calls. - /// The action to call every frame. - /// An optional action to call when this function finishes. - /// The handle to the coroutine that is started by this function. - public static CoroutineHandle CallPeriodically - (T reference, float timeframe, float period, System.Action action, System.Action onDone = null) - { - return action == null ? new CoroutineHandle() : - RunCoroutine(Instance._CallContinuously(reference, timeframe, period, action, onDone), Segment.Update); - } - - /// - /// Calls the supplied action at the given rate for a given number of seconds. - /// - /// A value that will be passed in to the supplied action each period. - /// The number of seconds that this function should run. - /// The amount of time between calls. - /// The action to call every frame. - /// An optional action to call when this function finishes. - /// The handle to the coroutine that is started by this function. - public CoroutineHandle CallPeriodicallyOnInstance - (T reference, float timeframe, float period, System.Action action, System.Action onDone = null) - { - return action == null ? new CoroutineHandle() : - RunCoroutineOnInstance(_CallContinuously(reference, timeframe, period, action, onDone), Segment.Update); - } - - /// - /// Calls the supplied action at the given rate for a given number of seconds. - /// - /// A value that will be passed in to the supplied action each period. - /// The number of seconds that this function should run. - /// The amount of time between calls. - /// The action to call every frame. - /// The timing segment to run in. - /// An optional action to call when this function finishes. - /// The handle to the coroutine that is started by this function. - public static CoroutineHandle CallPeriodically(T reference, float timeframe, float period, System.Action action, - Segment timing, System.Action onDone = null) - { - return action == null ? new CoroutineHandle() : - RunCoroutine(Instance._CallContinuously(reference, timeframe, period, action, onDone), timing); - } - - /// - /// Calls the supplied action at the given rate for a given number of seconds. - /// - /// A value that will be passed in to the supplied action each period. - /// The number of seconds that this function should run. - /// The amount of time between calls. - /// The action to call every frame. - /// The timing segment to run in. - /// An optional action to call when this function finishes. - /// The handle to the coroutine that is started by this function. - public CoroutineHandle CallPeriodicallyOnInstance(T reference, float timeframe, float period, System.Action action, - Segment timing, System.Action onDone = null) - { - return action == null ? new CoroutineHandle() : - RunCoroutineOnInstance(_CallContinuously(reference, timeframe, period, action, onDone), timing); - } - - /// - /// Calls the supplied action every frame for a given number of seconds. - /// - /// A value that will be passed in to the supplied action each frame. - /// The number of seconds that this function should run. - /// The action to call every frame. - /// An optional action to call when this function finishes. - /// The handle to the coroutine that is started by this function. - public static CoroutineHandle CallContinuously(T reference, float timeframe, System.Action action, System.Action onDone = null) - { - return action == null ? new CoroutineHandle() : - RunCoroutine(Instance._CallContinuously(reference, timeframe, 0f, action, onDone), Segment.Update); - } - - /// - /// Calls the supplied action every frame for a given number of seconds. - /// - /// A value that will be passed in to the supplied action each frame. - /// The number of seconds that this function should run. - /// The action to call every frame. - /// An optional action to call when this function finishes. - /// The handle to the coroutine that is started by this function. - public CoroutineHandle CallContinuouslyOnInstance(T reference, float timeframe, System.Action action, System.Action onDone = null) - { - return action == null ? new CoroutineHandle() : - RunCoroutineOnInstance(_CallContinuously(reference, timeframe, 0f, action, onDone), Segment.Update); - } - - /// - /// Calls the supplied action every frame for a given number of seconds. - /// - /// A value that will be passed in to the supplied action each frame. - /// The number of seconds that this function should run. - /// The action to call every frame. - /// The timing segment to run in. - /// An optional action to call when this function finishes. - /// The handle to the coroutine that is started by this function. - public static CoroutineHandle CallContinuously(T reference, float timeframe, System.Action action, - Segment timing, System.Action onDone = null) - { - return action == null ? new CoroutineHandle() : - RunCoroutine(Instance._CallContinuously(reference, timeframe, 0f, action, onDone), timing); - } - - /// - /// Calls the supplied action every frame for a given number of seconds. - /// - /// A value that will be passed in to the supplied action each frame. - /// The number of seconds that this function should run. - /// The action to call every frame. - /// The timing segment to run in. - /// An optional action to call when this function finishes. - /// The handle to the coroutine that is started by this function. - public CoroutineHandle CallContinuouslyOnInstance(T reference, float timeframe, System.Action action, - Segment timing, System.Action onDone = null) - { - return action == null ? new CoroutineHandle() : - RunCoroutineOnInstance(_CallContinuously(reference, timeframe, 0f, action, onDone), timing); - } - - private IEnumerator _CallContinuously(T reference, float timeframe, float period, - System.Action action, System.Action onDone = null) - { - double startTime = localTime; - while (localTime <= startTime + timeframe) - { - yield return WaitForSecondsOnInstance(period); - - action(reference); - } - - if (onDone != null) - onDone(reference); - } - - private struct ProcessIndex : System.IEquatable - { - public Segment seg; - public int i; - - public bool Equals(ProcessIndex other) - { - return seg == other.seg && i == other.i; - } - - public override bool Equals(object other) - { - if (other is ProcessIndex) - return Equals((ProcessIndex)other); - return false; - } - - public static bool operator ==(ProcessIndex a, ProcessIndex b) - { - return a.seg == b.seg && a.i == b.i; - } - - public static bool operator !=(ProcessIndex a, ProcessIndex b) - { - return a.seg != b.seg || a.i != b.i; - } - - public override int GetHashCode() - { - return (((int)seg - 2) * (int.MaxValue / 3)) + i; - } - } - - [System.Obsolete("Unity coroutine function, use RunCoroutine instead.", true)] - public new Coroutine StartCoroutine(System.Collections.IEnumerator routine) { return null; } - - [System.Obsolete("Unity coroutine function, use RunCoroutine instead.", true)] - public new Coroutine StartCoroutine(string methodName, object value) { return null; } - - [System.Obsolete("Unity coroutine function, use RunCoroutine instead.", true)] - public new Coroutine StartCoroutine(string methodName) { return null; } - - [System.Obsolete("Unity coroutine function, use RunCoroutine instead.", true)] - public new Coroutine StartCoroutine_Auto(System.Collections.IEnumerator routine) { return null; } - - [System.Obsolete("Unity coroutine function, use KillCoroutines instead.", true)] - public new void StopCoroutine(string methodName) { } - - [System.Obsolete("Unity coroutine function, use KillCoroutines instead.", true)] - public new void StopCoroutine(System.Collections.IEnumerator routine) { } - - [System.Obsolete("Unity coroutine function, use KillCoroutines instead.", true)] - public new void StopCoroutine(Coroutine routine) { } - - [System.Obsolete("Unity coroutine function, use KillCoroutines instead.", true)] - public new void StopAllCoroutines() { } - - [System.Obsolete("Use your own GameObject for this.", true)] - public new static void Destroy(Object obj) { } - - [System.Obsolete("Use your own GameObject for this.", true)] - public new static void Destroy(Object obj, float f) { } - - [System.Obsolete("Use your own GameObject for this.", true)] - public new static void DestroyObject(Object obj) { } - - [System.Obsolete("Use your own GameObject for this.", true)] - public new static void DestroyObject(Object obj, float f) { } - - [System.Obsolete("Use your own GameObject for this.", true)] - public new static void DestroyImmediate(Object obj) { } - - [System.Obsolete("Use your own GameObject for this.", true)] - public new static void DestroyImmediate(Object obj, bool b) { } - - [System.Obsolete("Use your own GameObject for this.", true)] - public new static void Instantiate(Object obj) { } - - [System.Obsolete("Use your own GameObject for this.", true)] - public new static void Instantiate(Object original, Vector3 position, Quaternion rotation) { } - - [System.Obsolete("Use your own GameObject for this.", true)] - public new static void Instantiate(T original) where T : Object { } - - [System.Obsolete("Just.. no.", true)] - public new static T FindObjectOfType() where T : Object { return null; } - - [System.Obsolete("Just.. no.", true)] - public new static Object FindObjectOfType(System.Type t) { return null; } - - [System.Obsolete("Just.. no.", true)] - public new static T[] FindObjectsOfType() where T : Object { return null; } - - [System.Obsolete("Just.. no.", true)] - public new static Object[] FindObjectsOfType(System.Type t) { return null; } - - [System.Obsolete("Just.. no.", true)] - public new static void print(object message) { } - } - - /// - /// The timing segment that a coroutine is running in or should be run in. - /// - public enum Segment - { - /// - /// Sometimes returned as an error state - /// - Invalid = -1, - /// - /// This is the default timing segment - /// - Update, - /// - /// This is primarily used for physics calculations - /// - FixedUpdate, - /// - /// This is run immediately after update - /// - LateUpdate, - /// - /// This executes, by default, about as quickly as the eye can detect changes in a text field - /// - SlowUpdate - } - - /// - /// How much debug info should be sent to the Unity profiler. NOTE: Setting this to anything above none shows up in the profiler as a - /// decrease in performance and a memory alloc. Those effects do not translate onto device. - /// - public enum DebugInfoType - { - /// - /// None coroutines will be separated in the Unity profiler - /// - None, - /// - /// The Unity profiler will identify each coroutine individually - /// - SeperateCoroutines, - /// - /// Coroutines will be separated and any tags or layers will be identified - /// - SeperateTags - } - - /// - /// A handle for a MEC coroutine. - /// - public struct CoroutineHandle : System.IEquatable - { - private const byte ReservedSpace = 0x0F; - private readonly static int[] NextIndex = { ReservedSpace + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - private readonly int _id; - - public byte Key { get { return (byte)(_id & ReservedSpace); } } - - public CoroutineHandle(byte ind) - { - if (ind > ReservedSpace) - ind -= ReservedSpace; - - _id = NextIndex[ind] + ind; - NextIndex[ind] += ReservedSpace + 1; - } - - public bool Equals(CoroutineHandle other) - { - return _id == other._id; - } - - public override bool Equals(object other) - { - if (other is CoroutineHandle) - return Equals((CoroutineHandle)other); - return false; - } - - public static bool operator==(CoroutineHandle a, CoroutineHandle b) - { - return a._id == b._id; - } - - public static bool operator!=(CoroutineHandle a, CoroutineHandle b) - { - return a._id != b._id; - } - - public override int GetHashCode() - { - return _id; - } - - /// - /// Is true if this handle may have been a valid handle at some point. (i.e. is not an uninitialized handle, error handle, or a key to a coroutine lock) - /// - public bool IsValid - { - get { return Key != 0; } - } - } - - public static class MECExtensionMethods1 - { - /// - /// Run a new coroutine in the Update segment. - /// - /// The new coroutine's handle. - /// The coroutine's handle, which can be used for Wait and Kill operations. - public static CoroutineHandle RunCoroutine(this IEnumerator coroutine) - { - return Timing.RunCoroutine(coroutine); - } - - /// - /// Run a new coroutine in the Update segment. - /// - /// The new coroutine's handle. - /// An optional tag to attach to the coroutine which can later be used to identify this coroutine. - /// The coroutine's handle, which can be used for Wait and Kill operations. - public static CoroutineHandle RunCoroutine(this IEnumerator coroutine, string tag) - { - return Timing.RunCoroutine(coroutine, tag); - } - - /// - /// Run a new coroutine. - /// - /// The new coroutine's handle. - /// The segment that the coroutine should run in. - /// The coroutine's handle, which can be used for Wait and Kill operations. - public static CoroutineHandle RunCoroutine(this IEnumerator coroutine, Segment segment) - { - return Timing.RunCoroutine(coroutine, segment); - } - - /// - /// Run a new coroutine. - /// - /// The new coroutine's handle. - /// The segment that the coroutine should run in. - /// An optional tag to attach to the coroutine which can later be used to identify this coroutine. - /// The coroutine's handle, which can be used for Wait and Kill operations. - public static CoroutineHandle RunCoroutine(this IEnumerator coroutine, Segment segment, string tag) - { - return Timing.RunCoroutine(coroutine, segment, tag); - } - } -} - -public static class MECExtensionMethods2 -{ - /// - /// Cancels this coroutine when the supplied game object is destroyed or made inactive. - /// - /// The coroutine handle to act upon. - /// The GameObject to test. - /// The modified coroutine handle. - public static IEnumerator CancelWith(this IEnumerator coroutine, GameObject gameObject) - { - while (MEC.Timing.MainThread != System.Threading.Thread.CurrentThread || (gameObject && gameObject.activeInHierarchy && coroutine.MoveNext())) - yield return coroutine.Current; - } - - /// - /// Cancels this coroutine when the supplied game objects are destroyed or made inactive. - /// - /// The coroutine handle to act upon. - /// The first GameObject to test. - /// The second GameObject to test - /// The modified coroutine handle. - public static IEnumerator CancelWith(this IEnumerator coroutine, GameObject gameObject1, GameObject gameObject2) - { - while (MEC.Timing.MainThread != System.Threading.Thread.CurrentThread || (gameObject1 && gameObject1.activeInHierarchy && - gameObject2 && gameObject2.activeInHierarchy && coroutine.MoveNext())) - yield return coroutine.Current; - } - - /// - /// Cancels this coroutine when the supplied game objects are destroyed or made inactive. - /// - /// The coroutine handle to act upon. - /// The first GameObject to test. - /// The second GameObject to test - /// The third GameObject to test. - /// The modified coroutine handle. - public static IEnumerator CancelWith(this IEnumerator coroutine, - GameObject gameObject1, GameObject gameObject2, GameObject gameObject3) - { - while (MEC.Timing.MainThread != System.Threading.Thread.CurrentThread || (gameObject1 && gameObject1.activeInHierarchy && - gameObject2 && gameObject2.activeInHierarchy && gameObject3 && gameObject3.activeInHierarchy && coroutine.MoveNext())) - yield return coroutine.Current; - } -} -- cgit v1.1-26-g67d0