From 120fd14cd847276c8371b78d7cd00c8a7c1ad44e Mon Sep 17 00:00:00 2001 From: GeWuYou <95328647+GeWuYou@users.noreply.github.com> Date: Sun, 1 Feb 2026 15:11:51 +0800 Subject: [PATCH] =?UTF-8?q?refactor(coroutine):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E5=8D=8F=E7=A8=8B=E8=B0=83=E5=BA=A6=E5=99=A8=E4=BB=A5=E6=94=AF?= =?UTF-8?q?=E6=8C=81WaitForCoroutine=E6=8C=87=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将WaitForCoroutine改为构造函数注入协程枚举器的方式 - 添加ProcessWaitingInstruction方法专门处理等待指令 - 添加IsWaiting方法判断协程等待状态 - 添加ProcessCoroutineStep方法处理协程步骤推进 - 添加HandleYieldInstruction方法处理yield指令逻辑 - 实现WaitForCoroutine指令的完整协程等待功能 - 在协程完成时通知WaitForCoroutine指令标记完成状态 - 优化协程调度器的执行流程和异常处理机制 --- .../coroutine/CoroutineScheduler.cs | 86 ++++++++++++++++--- .../instructions/WaitForCoroutine.cs | 22 +++-- 2 files changed, 87 insertions(+), 21 deletions(-) diff --git a/GFramework.Core/coroutine/CoroutineScheduler.cs b/GFramework.Core/coroutine/CoroutineScheduler.cs index 664d6a9..6115b05 100644 --- a/GFramework.Core/coroutine/CoroutineScheduler.cs +++ b/GFramework.Core/coroutine/CoroutineScheduler.cs @@ -1,4 +1,5 @@ using GFramework.Core.Abstractions.coroutine; +using GFramework.Core.coroutine.instructions; namespace GFramework.Core.coroutine; @@ -98,21 +99,12 @@ public sealed class CoroutineScheduler( try { - // 1️⃣ 处理等待指令 - if (slot.Waiting != null) + ProcessWaitingInstruction(slot, delta); + + if (!IsWaiting(slot)) { - slot.Waiting.Update(delta); - if (!slot.Waiting.IsDone) - continue; - - slot.Waiting = null; + ProcessCoroutineStep(slot, i); } - - // 2️⃣ 推进协程 - if (!slot.Enumerator.MoveNext()) - Complete(i); - else - slot.Waiting = slot.Enumerator.Current; } catch (Exception ex) { @@ -121,6 +113,68 @@ public sealed class CoroutineScheduler( } } + /// + /// 处理协程的等待指令 + /// + /// 协程槽位 + /// 时间差值 + private static void ProcessWaitingInstruction(CoroutineSlot slot, double delta) + { + if (slot.Waiting == null) + return; + + slot.Waiting.Update(delta); + if (slot.Waiting.IsDone) + slot.Waiting = null; + } + + /// + /// 判断协程是否正在等待 + /// + /// 协程槽位 + /// 是否正在等待 + private static bool IsWaiting(CoroutineSlot slot) + { + return slot.Waiting != null && !slot.Waiting.IsDone; + } + + /// + /// 处理协程步骤推进 + /// + /// 协程槽位 + /// 槽位索引 + private void ProcessCoroutineStep(CoroutineSlot slot, int slotIndex) + { + if (!slot.Enumerator.MoveNext()) + { + Complete(slotIndex); + return; + } + + var current = slot.Enumerator.Current; + HandleYieldInstruction(slot, current); + } + + /// + /// 处理协程的yield指令 + /// + /// 协程槽位 + /// yield指令 + private void HandleYieldInstruction(CoroutineSlot slot, IYieldInstruction instruction) + { + // 处理 WaitForCoroutine 指令 + if (instruction is WaitForCoroutine waitForCoroutine) + { + // 启动被等待的协程并建立等待关系 + var targetHandle = Run(waitForCoroutine.Coroutine); + WaitForCoroutine(slot.Handle, targetHandle); + } + else + { + slot.Waiting = instruction; + } + } + #endregion #region Pause / Resume / Kill @@ -300,6 +354,12 @@ public sealed class CoroutineScheduler( if (!_metadata.TryGetValue(waiter, out var meta)) continue; var s = _slots[meta.SlotIndex]; if (s == null) continue; + // 通知 WaitForCoroutine 指令协程已完成 + if (s.Waiting is WaitForCoroutine wfc) + { + wfc.Complete(); + } + s.State = CoroutineState.Running; meta.State = CoroutineState.Running; } diff --git a/GFramework.Core/coroutine/instructions/WaitForCoroutine.cs b/GFramework.Core/coroutine/instructions/WaitForCoroutine.cs index ad716e1..acacbc7 100644 --- a/GFramework.Core/coroutine/instructions/WaitForCoroutine.cs +++ b/GFramework.Core/coroutine/instructions/WaitForCoroutine.cs @@ -5,10 +5,21 @@ namespace GFramework.Core.coroutine.instructions; /// /// 等待协程完成的指令类,实现IYieldInstruction接口 /// -public sealed class WaitForCoroutine : IYieldInstruction +/// 需要等待完成的协程枚举器 +public sealed class WaitForCoroutine(IEnumerator coroutine) : IYieldInstruction { /// - /// 更新方法,用于处理时间更新逻辑 + /// 获取内部协程枚举器 + /// + internal IEnumerator Coroutine => coroutine; + + /// + /// 获取当前等待的协程是否已完成 + /// + public bool IsDone { get; private set; } + + /// + /// 更新方法,用于处理协程等待逻辑 /// /// 时间增量 public void Update(double delta) @@ -16,12 +27,7 @@ public sealed class WaitForCoroutine : IYieldInstruction } /// - /// 获取协程是否已完成的状态 - /// - public bool IsDone { get; private set; } - - /// - /// 内部方法,用于标记协程完成状态 + /// 标记协程等待完成 /// internal void Complete() {