예제 #1
0
        // Call this as you would call MonoBehaviour.StartCoroutine
        public SCoroutine StartCoroutine(IEnumerator ie)
        {
            var sc = new SCoroutine();

            sc.Start(ie);
            runningCoroutines.Add(sc);
            return(sc);
        }
예제 #2
0
        public void Start(IEnumerator routine)
        {
            ienumeratorStack.Clear();
            ienumeratorStack.Push(routine);
            nestedCoroutine = null;
            yieldFrame      = -1;

            Update();
        }
예제 #3
0
        // Execute a single step of the coroutine. Unity equivalent is the MoveNext you see in coroutine stack traces
        // Returns true if the coroutine should continue running
        public bool Update()
        {
            // This ensures yield return null waits a frame in all situations
            if (yieldFrame > Time.frameCount)
            {
                return(true);
            }

            // Do not continue with the IEnumerators until the last returned SCoroutine has finished running
            if (nestedCoroutine != null && nestedCoroutine.IsRunning())
            {
                return(true);
            }
            nestedCoroutine = null;

            if (ienumeratorStack.Count > 0)
            {
                var ie = ienumeratorStack.Peek(); // The top of the stack is the currently executing IEnumerator
                if (ie.MoveNext())                // Execute IEnumerator until next yield (true) or break/end (false)
                {
                    // ie.Current is what was yield returned in the IEnumerator
                    object yielded = ie.Current;
                    if (yielded is IEnumerator)
                    {
                        // Move to execute a nested IEnumerator
                        ienumeratorStack.Push(yielded as IEnumerator);
                        return(Update()); // Start nested IEnumerator execution without frame delay
                    }
                    else if (yielded is SCoroutine)
                    {
                        // Start waiting on a nested SCoroutine
                        nestedCoroutine = yielded as SCoroutine;
                    }
                    else
                    {
                        // Yielding anything else (like null) causes execution to resume next frame
                        yieldFrame = Time.frameCount + 1;
                    }
                    // TODO: Support Unity's YieldInstruction by starting a real coroutine and yielding it there
                    // TODO: Add logic for custom yieldable objects here
                }
                else
                {
                    ienumeratorStack.Pop();
                    return(Update()); // Immediately continue the previous IEnumerator in the stack without frame delay
                }
                return(true);
            }
            else
            {
                return(false);
            }
        }