Example #1
0
        private void FixedUpdateCoroutine(CoroutineContext ctx)
        {
            ctx.fixedUpdateCnt++;
            var curr = ctx.Current;

            if (curr is WaitForFixedUpdate)
            {
                if (ctx.initFixFrame)
                {
                    ctx.initFixFrame = false;
                }
                else
                {
                    var s = ctx.MoveNext();
                    if (!s)
                    {
                        _ctxList.Remove(ctx);
                    }
                }
            }

            ctx.initFixFrame = false;
        }
Example #2
0
        private void UpdateCoroutine(CoroutineContext ctx)
        {
            ctx.updateCnt++;
            var curr = ctx.Current;

            if (curr is WaitForEndOfFrame)
            {
                if (ctx.initFrame)
                {
                    ctx.initFrame = false;
                }
                else
                {
                    var s = ctx.MoveNext();
                    if (!s)
                    {
                        _ctxList.Remove(ctx);
                    }
                }
            }
            else if (curr is WaitForSeconds)
            {
                if (CheckWaitForSecondsDone(ctx, curr as WaitForSeconds))
                {
                    var s = ctx.MoveNext();
                    if (!s)
                    {
                        _ctxList.Remove(ctx);
                    }
                }
            }
            else if (curr is WaitForSecondsRealtime)
            {
                if (Time.realtimeSinceStartup - ctx.frameRealTime >= (curr as WaitForSecondsRealtime).waitTime)
                {
                    var s = ctx.MoveNext();
                    if (!s)
                    {
                        _ctxList.Remove(ctx);
                    }
                }
            }
            else if (curr is AsyncOperation)
            {
                if ((curr as AsyncOperation).isDone)
                {
                    var s = ctx.MoveNext();
                    if (!s)
                    {
                        _ctxList.Remove(ctx);
                    }
                }
            }
            else if (curr is CustomYieldInstruction)
            {
                if (!(curr as CustomYieldInstruction).keepWaiting)
                {
                    var s = ctx.MoveNext();
                    if (!s)
                    {
                        _ctxList.Remove(ctx);
                    }
                }
            }
            else if (curr is CoroutineContextHandle)
            {
                var node = FindNode((curr as CoroutineContextHandle).Id);
                if (node == null)
                {
                    var s = ctx.MoveNext();
                    if (!s)
                    {
                        _ctxList.Remove(ctx);
                    }
                }
                else if (node.Value.isDone)
                {
                    _ctxList.Remove(ctx);
                }
            }
            else if (curr is WaitForFixedUpdate)
            {
            }
            else if (curr == null || curr.GetType().IsValueType)
            {
                var s = ctx.MoveNext();
                if (!s)
                {
                    _ctxList.Remove(ctx);
                }
            }
            else
            {
                Debug.LogError("不支持的yield类型:" + curr.GetType().ToString());
            }

            ctx.initFrame = false;
            if (!(curr is WaitForSeconds))
            {
                ctx.frameTime = Time.time;
            }

            if (!(curr is WaitForSecondsRealtime))
            {
                ctx.frameRealTime = Time.realtimeSinceStartup;
            }
        }
Example #3
0
        //执行协程的一帧,凡是yield return的位置,至少要等一帧
        private void YieldDo(CoroutineContext context)
        {
            //主动暂停
            if (context.IsSuspended)
            {
                return;
            }
            //等待事件
            if (context.IsWaitForEvent)
            {
                return;
            }

            context.Yield = null;

            try
            {
                //当前协程执行完毕
                if (!context.MoveNext())
                {
                    context.IsDisposed = true;
                    context.Callback();
                    return;
                }
            }
            catch (Exception e)
            {
                context.IsDisposed = true;
                try
                {
                    OnException?.Invoke(context.Handle, e);
                }
                catch (Exception)
                {
                    //todo 处理异常
                }
                return;
            }

            var obj = context.Current;

            if (obj is IEnumerator enumerator)
            {
                obj = new WaitForCoroutine(StartCoroutine(enumerator));
            }

            if (obj is ICoroutineYieldNeedInit yield)
            {
                yield.Init(timeGetter);
            }

            if (obj is WaitForMilliseconds coroutineTimer)
            {
                context.IsInTimer = true;
                timerManager.StartTimer(now + coroutineTimer.After, () =>
                {
                    context.IsInTimer = false;
                    coroutines.Add(context);
                });

                return;
            }

            if (obj is ICoroutineYield coroutineYield)
            {
                context.Yield = coroutineYield;
                return;
            }

            throw new CoroutineException($"Cannot use type {obj.GetType()} in yield.");
        }