Ejemplo n.º 1
0
        internal void _HandleException(CoroutineException e)
        {
            if (_pCurrentInstruction != null)
            {
                _pCurrentInstruction.Stop();
                _pCurrentInstruction.DecRef();
                _pCurrentInstruction = null;
            }

            _pCoroutineFunc = null;
            _state          = CoroutineState.Stopped;

            if (_onException != null)
            {
                _onException(this, e);
            }
            else
            {
                if (_Parent != null)
                {
                    /// 'Throw up' to parent
                    _Parent._HandleException(e);
                }
                else
                {
                    CoroutineMgr._ThrowException(e);
                }
            }

            if (_onStopped != null)
            {
                _onStopped(this);
                _Parent = null;
            }
        }
Ejemplo n.º 2
0
 private IEnumerator <IYieldInstruction> MockCoroutineOptionalYield(IYieldInstruction yieldInstruction, Func <bool> onStep)
 {
     while (onStep())
     {
         yield return(yieldInstruction);
     }
 }
Ejemplo n.º 3
0
            public bool MoveNext()
            {
                bool move = asyncInstruction.MoveNext();

                yieldInstruction = asyncInstruction.Current == null ? NotWait.notWait : asyncInstruction.Current;

                return(move);
            }
Ejemplo n.º 4
0
        private IEnumerator <IYieldInstruction> MockCoroutine(IYieldInstruction yieldInstruction, Hangout.Shared.Action onStep)
        {
            while (true)
            {
                yield return(yieldInstruction);

                onStep();
            }
        }
Ejemplo n.º 5
0
        public static IEnumerator RepeatFor(float time, Action <float> method, IYieldInstruction yieldInstruction)
        {
            var current = 0.0f;

            while (current < time)
            {
                yield return(yieldInstruction.Wait());

                current += yieldInstruction.Increment();

                method(Mathf.Clamp01(current / time));
            }
            method(1.0f);
        }
Ejemplo n.º 6
0
        ///--------
        private void __doComplete(object returnValue = null)
        {
            _pCoroutineFunc = null;

            if (_pCurrentInstruction != null)
            {
                _pCurrentInstruction.DecRef();
                _pCurrentInstruction = null;
            }

            if (_onComplete != null)
            {
                _onComplete(this, returnValue);
            }

            _doStop();
        }
Ejemplo n.º 7
0
        override public void Stop()
        {
            Debugger.Assert(GetRef() != 0);
            Debugger.ConditionalAssert(_bPooled
                                       , !_AutoKill, "You can call pause/resume/stop a pooled coroutine only when AutoKill is false.");

            if (_state == CoroutineState.Stopped)
            {
                return;
            }

            __bIsManualStopped = true;
            _pCoroutineFunc    = null;

            if (_pCurrentInstruction != null)
            {
                _pCurrentInstruction.Stop();
                _pCurrentInstruction.DecRef();
                _pCurrentInstruction = null;
            }

            _doStop();
        }
Ejemplo n.º 8
0
        override public bool IsDone()
        {
            bool bIsDone = false;

            if (_type == _WaitType.All)
            {
                bIsDone = true;

                foreach (var instruction in _arrInstructions)
                {
                    if (!instruction.IsDone())
                    {
                        bIsDone = false;
                        break;
                    }
                }
            }
            else if (_type == _WaitType.OneOf)
            {
                foreach (var instruction in _arrInstructions)
                {
                    if (instruction.IsDone())
                    {
                        _firstDoneInstruction = instruction;
                        bIsDone = true;
                        break;
                    }
                }
            }
            else if (_type == _WaitType.NumOf)
            {
                if (_doneInstructions.Count != 0)
                {
                    return(true);
                }
                else
                {
                    Debugger.Assert(_doneInstructions.Count <= _arrInstructions.Length);

                    int nNum = 0;
                    foreach (var instruction in _arrInstructions)
                    {
                        if (instruction.IsDone())
                        {
                            nNum++;

                            if (nNum == _number)
                            {
                                bIsDone = true;
                                break;
                            }
                        }
                    }

                    if (bIsDone)
                    {
                        foreach (var instruction in _arrInstructions)
                        {
                            if (instruction.IsDone())
                            {
                                _doneInstructions.Add(instruction);
                            }
                        }
                    }
                }
            }

            return(bIsDone);
        }
Ejemplo n.º 9
0
 private void Yield(IYieldInstruction instruction)
 {
     State = CoroutineState.Continue;
     instruction.Yield(this, YieldReturn);
 }
Ejemplo n.º 10
0
        public static IEnumerator DoAfter(Action method, IYieldInstruction yieldInstruction)
        {
            yield return(yieldInstruction.Wait());

            method();
        }
Ejemplo n.º 11
0
 private void Yield(IYieldInstruction instruction)
 {
     State = CoroutineState.Continue;
     instruction.Yield(this, YieldReturn);
 }
Ejemplo n.º 12
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);
        }
Ejemplo n.º 13
0
        internal void _Start(IEnumerator pCoroutineFunc)
        {
            Debugger.Assert(GetRef() != 0);

            _Parent = _pCoroutineMgr.Current();
            if (_Parent != null)
            {
                _Parent._DoChildCoStart(this);
            }

            Debugger.Assert(_state != CoroutineState.Disposed);
            if (_state == CoroutineState.Running || _state == CoroutineState.Paused)
            {
                Stop();
            }

            try
            {
                _pCoroutineMgr._CoEnterLogStack.Push(this);

                if (!_bInQueue)
                {
                    CoroutineMgr._Instance._AddToQueue(this);
                }

                _pCoroutineFunc = pCoroutineFunc;

                if (_onStart != null)
                {
                    _onStart(this);
                }

                _state = CoroutineState.Running;

                if (_pCoroutineFunc.MoveNext())
                {
                    /// 如果子Coroutine的第一行代码抛出异常,_state会被设置为Stopped
                    if (_state != CoroutineState.Stopped)
                    {
                        Debugger.Assert(_state != CoroutineState.Disposed && _state != CoroutineState.Freed);

                        _pCurrentInstruction = _pCoroutineFunc.Current as IYieldInstruction;

                        if (_pCurrentInstruction == null)
                        {
                            throw new UnsupportedYieldInstruction();
                        }

                        _pCurrentInstruction.Start(scalable ? _pCoroutineMgr._Time : _pCoroutineMgr._RealTime);
                        _pCurrentInstruction.IncRef();
                    }
                }
                else
                {
                    /// When coroutine has the 'yield break' at first line, will reach here.
                    /// The onStop will be called at next _Update.
                    _state = CoroutineState.Stopped;
                }
            }
            catch (Exception e)
            {
                if (e is CoroutineException)
                {
                    _HandleException(e as CoroutineException);
                }
                else
                {
                    _HandleException(new CoroutineException(e, this));
                }
            }
            finally
            {
                Debugger.Assert(_pCoroutineMgr._CoEnterLogStack.Peek() == this);
                _pCoroutineMgr._CoEnterLogStack.Pop();
            }
        }