void IPoolable.OnDespawned() { var poolableYieldInstruction = Enumerator as IPoolableYieldInstruction; if (poolableYieldInstruction != null) { poolableYieldInstruction.Despawn(); } Id = -1; IsDone = false; UpdateLoop = UpdateLoop.Update; Enumerator = null; Parent = null; Child = null; WaitTillTime = float.MinValue; WaitTimeIsUnscaled = false; WaitingForEndOfFrame = false; LinkedObject = null; LinkedComponent = null; IsLinkedToObject = false; IsLinkedToComponent = false; }
private static void Start(BetterCoroutine coroutine) { var scaledTime = GetTime(coroutine.UpdateLoop, false); var unscaledTime = GetTime(coroutine.UpdateLoop, true); var continueRunning = UpdateCoroutine(scaledTime, unscaledTime, coroutine); if (!continueRunning) { PoolHelper <BetterCoroutine> .Despawn(coroutine); return; } IdToCoroutine[coroutine.Id] = coroutine; var list = GetList(coroutine.UpdateLoop); if (_current != null && _current.List == list.BackingList) { list.AddBefore(_current, coroutine); } else { list.AddFirst(coroutine); } }
private static void StartChild(IEnumerator enumerator, BetterCoroutine parent) { var child = SpawnCoroutine(enumerator, parent.UpdateLoopId); child.Parent = parent; parent.Child = child; Start(child); }
private static void Stop(BetterCoroutine coroutine) { if (coroutine.IsDone) { return; } if (coroutine.Parent != null) { coroutine.Parent.Child = null; } while (coroutine != null) { coroutine.IsDone = true; coroutine = coroutine.Child; } }
private static void Start(BetterCoroutine coroutine) { var scaledTime = GetTime(coroutine.UpdateLoopId, false); var unscaledTime = GetTime(coroutine.UpdateLoopId, true); IdToCoroutine[coroutine.Id] = coroutine; var list = GetList(coroutine.UpdateLoopId); if (list == null) { UpdateLoopToCoroutines[coroutine.UpdateLoopId] = list = new PooledLinkedList <BetterCoroutine>(SharedNodePool); ManagedUpdate.AddListener(coroutine.UpdateLoopId, Instance); } var node = list.AddFirst(coroutine); var prevCurrent = _current; _current = node; var continueRunning = UpdateCoroutine(scaledTime, unscaledTime, coroutine); if (!continueRunning) { IdToCoroutine.Remove(coroutine.Id); list.Remove(coroutine); if (coroutine.Parent != null) { coroutine.Parent.Child = null; } PoolHelper <BetterCoroutine> .Despawn(coroutine); } _current = prevCurrent; }
// this method has gotten out of hand.. private static bool UpdateCoroutine(float scaledTime, float unscaledTime, BetterCoroutine coroutine) { if (coroutine.IsDone) { return(false); } if (coroutine.IsLinkedToObject && (!coroutine.LinkedObject || !coroutine.LinkedObject.activeInHierarchy)) { return(false); } if (coroutine.IsLinkedToComponent && (!coroutine.LinkedComponent || !coroutine.LinkedComponent.isActiveAndEnabled)) { return(false); } if (coroutine.IsPaused || coroutine.IsParentPaused) { return(true); } if (coroutine.Child != null) { return(true); } if (coroutine.WaitingForEndOfFrame) { return(true); } var time = coroutine.WaitTimeIsUnscaled ? unscaledTime : scaledTime; if (coroutine.WaitTillTime > time) { return(true); } var enumerator = coroutine.Enumerator; try { if (!enumerator.MoveNext()) { return(false); } } catch (Exception e) { // something bad happened in the coroutine, just print out the error and stop the problematic routine. // todo: should this stop parent coroutines as well? Debug.LogError(e); return(false); } var current = enumerator.Current; if (current == null) { return(true); } var subroutineId = current as int?; if (subroutineId != null) { var subroutine = IdToCoroutine[subroutineId.Value]; if (subroutine != null) { coroutine.Child = subroutine; subroutine.Parent = coroutine; } return(true); } var subEnumerator = current as IEnumerator; if (subEnumerator != null) { StartChild(subEnumerator, coroutine); return(true); } var waitForSeconds = current as WaitForSecondsLite; if (waitForSeconds != null) { time = waitForSeconds.Unscaled ? unscaledTime : scaledTime; coroutine.WaitTimeIsUnscaled = waitForSeconds.Unscaled; coroutine.WaitTillTime = time + waitForSeconds.Duration; return(true); } if (current is WaitForEndOfFrame) { coroutine.WaitingForEndOfFrame = true; CoroutinesWaitingForEndOfFrame.AddFirst(coroutine); return(true); } var www = current as WWW; if (www != null) { if (!www.isDone) { StartChild(Coroutines.WaitForWWW.Create(www), coroutine); } return(true); } var asyncOperation = current as AsyncOperation; if (asyncOperation != null) { if (!asyncOperation.isDone) { StartChild(Coroutines.WaitForAsyncOperation.Create(asyncOperation), coroutine); } return(true); } // we could use reflection, but it's slow and users really should switch over. if (current is WaitForSeconds) { Debug.LogError("UnityEngine.WaitForSeconds is not supported in BetterCoroutines. Please use BetterCoroutines.WaitForSeconds() instead."); } return(true); }