diff --git a/GFramework.Core.Abstractions/coroutine/CoroutineState.cs b/GFramework.Core.Abstractions/coroutine/CoroutineState.cs
index e9c7c07..6eb7535 100644
--- a/GFramework.Core.Abstractions/coroutine/CoroutineState.cs
+++ b/GFramework.Core.Abstractions/coroutine/CoroutineState.cs
@@ -15,11 +15,6 @@ public enum CoroutineState
///
Paused,
- ///
- /// 协程被锁定或等待其他协程完成
- ///
- Held,
-
///
/// 协程已完成执行
///
diff --git a/GFramework.Core/coroutine/CoroutineMetadata.cs b/GFramework.Core/coroutine/CoroutineMetadata.cs
index d967d37..47e0fe4 100644
--- a/GFramework.Core/coroutine/CoroutineMetadata.cs
+++ b/GFramework.Core/coroutine/CoroutineMetadata.cs
@@ -27,6 +27,5 @@ internal class CoroutineMetadata
///
public bool IsActive =>
State is CoroutineState.Running
- or CoroutineState.Paused
- or CoroutineState.Held;
+ or CoroutineState.Paused;
}
\ No newline at end of file
diff --git a/GFramework.Core/coroutine/CoroutineScheduler.cs b/GFramework.Core/coroutine/CoroutineScheduler.cs
index 6115b05..9e5bedc 100644
--- a/GFramework.Core/coroutine/CoroutineScheduler.cs
+++ b/GFramework.Core/coroutine/CoroutineScheduler.cs
@@ -162,16 +162,39 @@ public sealed class CoroutineScheduler(
/// yield指令
private void HandleYieldInstruction(CoroutineSlot slot, IYieldInstruction instruction)
{
- // 处理 WaitForCoroutine 指令
- if (instruction is WaitForCoroutine waitForCoroutine)
+ switch (instruction)
{
- // 启动被等待的协程并建立等待关系
- var targetHandle = Run(waitForCoroutine.Coroutine);
- WaitForCoroutine(slot.Handle, targetHandle);
- }
- else
- {
- slot.Waiting = instruction;
+ // 处理 WaitForCoroutine 指令
+ case WaitForCoroutine waitForCoroutine:
+ {
+ // 启动被等待的协程并建立等待关系
+ var targetHandle = Run(waitForCoroutine.Coroutine);
+ slot.Waiting = waitForCoroutine;
+ WaitForCoroutine(slot.Handle, targetHandle);
+ break;
+ }
+ case WaitForAllCoroutines waitForAll:
+ {
+ slot.Waiting = waitForAll;
+ // 为所有待完成的协程建立等待关系
+ foreach (var handle in waitForAll.PendingHandles)
+ {
+ if (_metadata.ContainsKey(handle))
+ {
+ WaitForCoroutine(slot.Handle, handle);
+ }
+ else
+ {
+ // 协程已完成,立即通知
+ waitForAll.NotifyCoroutineComplete(handle);
+ }
+ }
+
+ break;
+ }
+ default:
+ slot.Waiting = instruction;
+ break;
}
}
@@ -250,16 +273,6 @@ public sealed class CoroutineScheduler(
if (!_metadata.ContainsKey(target))
return;
- if (_metadata.TryGetValue(current, out var meta))
- {
- var slot = _slots[meta.SlotIndex];
- if (slot != null)
- {
- slot.State = CoroutineState.Held;
- meta.State = CoroutineState.Held;
- }
- }
-
if (!_waiting.TryGetValue(target, out var set))
{
set = [];
@@ -354,10 +367,15 @@ 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)
+ switch (s.Waiting)
{
- wfc.Complete();
+ // 通知 WaitForCoroutine 指令协程已完成
+ case WaitForCoroutine wfc:
+ wfc.Complete();
+ break;
+ case WaitForAllCoroutines wfa:
+ wfa.NotifyCoroutineComplete(handle);
+ break;
}
s.State = CoroutineState.Running;
diff --git a/GFramework.Core/coroutine/extensions/CoroutineExtensions.cs b/GFramework.Core/coroutine/extensions/CoroutineExtensions.cs
index 24d232e..3dc564a 100644
--- a/GFramework.Core/coroutine/extensions/CoroutineExtensions.cs
+++ b/GFramework.Core/coroutine/extensions/CoroutineExtensions.cs
@@ -86,7 +86,7 @@ public static class CoroutineExtensions
}
// 等待所有协程完成
- yield return new WaitForAllCoroutines(scheduler, handles);
+ yield return new WaitForAllCoroutines(handles);
}
///
diff --git a/GFramework.Core/coroutine/instructions/WaitForAllCoroutines.cs b/GFramework.Core/coroutine/instructions/WaitForAllCoroutines.cs
index c0a33a8..16ad295 100644
--- a/GFramework.Core/coroutine/instructions/WaitForAllCoroutines.cs
+++ b/GFramework.Core/coroutine/instructions/WaitForAllCoroutines.cs
@@ -7,28 +7,49 @@ namespace GFramework.Core.coroutine.instructions;
///
public sealed class WaitForAllCoroutines : IYieldInstruction
{
- private readonly IReadOnlyList _handles;
- private readonly CoroutineScheduler _scheduler;
+ private readonly HashSet _pendingHandles;
private bool _isDone;
- public WaitForAllCoroutines(
- CoroutineScheduler scheduler,
- IReadOnlyList handles)
+ ///
+ /// 初始化 WaitForAllCoroutines 类的新实例
+ ///
+ /// 要等待完成的协程句柄列表
+ public WaitForAllCoroutines(IReadOnlyList handles)
{
- _scheduler = scheduler ?? throw new ArgumentNullException(nameof(scheduler));
- _handles = handles ?? throw new ArgumentNullException(nameof(handles));
+ ArgumentNullException.ThrowIfNull(handles);
- // 空列表直接完成
- _isDone = _handles.Count == 0;
+ _pendingHandles = new HashSet(handles);
+ _isDone = _pendingHandles.Count == 0;
}
+ ///
+ /// 获取所有待完成的协程句柄
+ ///
+ internal IReadOnlyCollection PendingHandles => _pendingHandles;
+
+ ///
+ /// 更新方法 - 由调度器调用
+ ///
+ /// 时间增量
public void Update(double deltaTime)
{
- if (_isDone) return;
-
- // 检查所有协程是否都已完成
- _isDone = _handles.All(handle => !_scheduler.IsCoroutineAlive(handle));
+ // 不需要做任何事,由调度器通知完成
}
+ ///
+ /// 获取一个值,指示是否所有协程都已完成
+ ///
public bool IsDone => _isDone;
+
+ ///
+ /// 通知某个协程已完成
+ ///
+ /// 已完成的协程句柄
+ internal void NotifyCoroutineComplete(CoroutineHandle handle)
+ {
+ // 从待处理句柄集合中移除已完成的协程句柄
+ _pendingHandles.Remove(handle);
+ if (_pendingHandles.Count == 0)
+ _isDone = true;
+ }
}
\ No newline at end of file