///--------------------- /// Garbage free static public IYieldInstruction Return(this object target, object returnValue = null) { _ReturnValue pInstruction = CoroutineMgr._Instance._returnValuePool.Get(); pInstruction.returnValue = returnValue; return(pInstruction); }
internal void _FreeReturnValue(_ReturnValue pReturnValue) { _returnValuePool.Free(pReturnValue); }
/// 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); }