///---------------------
        /// Garbage free
        static public IYieldInstruction Return(this object target, object returnValue = null)
        {
            _ReturnValue pInstruction = CoroutineMgr._Instance._returnValuePool.Get();

            pInstruction.returnValue = returnValue;

            return(pInstruction);
        }
Beispiel #2
0
 internal void _FreeReturnValue(_ReturnValue pReturnValue)
 {
     _returnValuePool.Free(pReturnValue);
 }
Beispiel #3
0
        /// Return value indicate whether this coroutine is dead.
        internal bool _Update(float fTime)
        {
            bool bIsDead = false;

            try
            {
                if (_onUpdate != null && state == CoroutineState.Running)
                {
                    _onUpdate(_pCurrentInstruction);
                }
            }
            catch (Exception e)
            {
                _HandleException(new CoroutineException(e, this));
                bIsDead = true;
            }

            bool bIsComplete = false;

            if (_state < CoroutineState.Running)
            {
                if (_state == CoroutineState.Paused)
                {
                    return(false);
                }
                else if (_state == CoroutineState.Stopped)
                {
                    bIsComplete = true;
                }
                else if (_state == CoroutineState.Disposed)
                {
                    /// Occurred when a manual coroutine is Removed.
                    return(true);
                }
                else
                {
                    Debugger.Assert(false);
                }
            }

            try
            {
                _pCoroutineMgr._CoEnterLogStack.Push(this);

                if (bIsComplete)
                {
                    if (!__bIsManualStopped)
                    {
                        __doComplete();
                    }
                    return(true);
                }

                ///-------------------
                bIsDead = false;

                Debugger.Assert(_pCurrentInstruction != null);

                Debugger.DebugSection(() =>
                {
                    if (_pCurrentInstruction.GetInstructionType() == YieldInstructionType.Coroutine)
                    {
                        var coroutine = _pCurrentInstruction as Coroutine;
                        Debugger.ConditionalAssert(coroutine._bPooled, coroutine.state != CoroutineState.Freed);
                    }
                });

                if (_pCurrentInstruction.GetInstructionType() == YieldInstructionType.ReturnValue)
                {
                    bIsDead = true;

                    _ReturnValue pReturnValue = _pCurrentInstruction as _ReturnValue;

                    __doComplete(pReturnValue.returnValue);
                }
                else
                {
                    _pCurrentInstruction.Update(fTime);

                    if (_pCurrentInstruction.IsDone())
                    {
                        if (_onYieldDone != null)
                        {
                            _onYieldDone(_pCurrentInstruction);
                        }

                        if (state != CoroutineState.Stopped)
                        {
                            Debugger.Assert(_pCurrentInstruction != null);
                            _pCurrentInstruction.Stop();

                            if (!_pCoroutineFunc.MoveNext())
                            {
                                _pCurrentInstruction.DecRef();
                                _pCurrentInstruction = null;

                                bIsDead = true;
                                __doComplete();
                            }
                            else
                            {
                                if (_state != CoroutineState.Stopped)
                                {
                                    Debugger.Assert(_state != CoroutineState.Freed && _state != CoroutineState.Disposed);
                                    Debugger.Assert(_pCoroutineFunc != null, "Coroutine function is null but still in update, you may be operated on a dead coroutine!!!");

                                    /// Why defRef here? Because MoveNext() may cause current instruction
                                    _pCurrentInstruction.DecRef();

                                    _pCurrentInstruction = _pCoroutineFunc.Current as IYieldInstruction;
                                    if (_pCurrentInstruction == null)
                                    {
                                        throw new UnsupportedYieldInstruction();
                                    }

                                    _pCurrentInstruction.Start(fTime);
                                    _pCurrentInstruction.IncRef();
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Debugger.Assert(!(e is CoroutineException));
                _HandleException(new CoroutineException(e, this));
                bIsDead = true;
            }
            finally
            {
                Debugger.Assert(_pCoroutineMgr._CoEnterLogStack.Peek() == this);
                _pCoroutineMgr._CoEnterLogStack.Pop();
            }

            return(bIsDead);
        }