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; }
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; } }
//执行协程的一帧,凡是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."); }