/// <summary> /// Starts a coroutine, the coroutine does not run immediately but on the /// next call to UpdateAllCoroutines. The execution of a coroutine can /// be paused at any point using the yield statement. The yield return value /// specifies when the coroutine is resumed. /// </summary> /// <param name="fiber">The fiber.</param> /// <returns></returns> public CoroutineNode StartCoroutine(IEnumerator fiber) { // if function does not have a yield, fiber will be null and we no-op if (fiber == null) { return null; } // create coroutine node and run until we reach first yield CoroutineNode coroutine = new CoroutineNode(fiber); AddCoroutine(coroutine); return coroutine; }
private void RemoveCoroutine(CoroutineNode coroutine) { if (this._firstNode == coroutine) { // remove first this._firstNode = coroutine.listNext; } else { // not head of list if (coroutine.listNext != null) { // remove between coroutine.listPrevious.listNext = coroutine.listNext; coroutine.listNext.listPrevious = coroutine.listPrevious; } else if (coroutine.listPrevious != null) { // and listNext is null coroutine.listPrevious.listNext = null; // remove last } } coroutine.listPrevious = null; coroutine.listNext = null; }
/** * Executes coroutine until next yield. If coroutine has finished, flags * it as finished and removes it from scheduler list. */ private void UpdateCoroutine(CoroutineNode coroutine) { IEnumerator fiber = coroutine.fiber; if (coroutine.fiber.MoveNext()) { System.Object yieldCommand = fiber.Current == null ? (System.Object)1 : fiber.Current; if (yieldCommand.GetType() == typeof(int)) { coroutine.waitForFrame = (int)yieldCommand; coroutine.waitForFrame += (int)_currentFrame; } else if (yieldCommand.GetType() == typeof(float)) { coroutine.waitForTime = (float)yieldCommand; coroutine.waitForTime += (float)_currentTime; } else if (yieldCommand.GetType() == typeof(CoroutineNode)) { coroutine.waitForCoroutine = (CoroutineNode)yieldCommand; } else { throw new System.ArgumentException("CoroutineScheduler: Unexpected coroutine yield type: " + yieldCommand.GetType()); } } else { // coroutine finished coroutine.finished = true; RemoveCoroutine(coroutine); } }
private void AddCoroutine(CoroutineNode coroutine) { if (this._firstNode != null) { coroutine.listNext = this._firstNode; _firstNode.listPrevious = coroutine; } _firstNode = coroutine; }
/// <summary> /// Stops all coroutines running on this behaviour. Use of this method is /// discouraged, think of a natural way for your coroutines to finish /// on their own instead of being forcefully stopped before they finish. /// If you need finer control over stopping coroutines you can use multiple /// schedulers. /// </summary> public void StopAllCoroutines() { _firstNode = null; }