mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
refactor(coroutine): 重构协程调度器以支持WaitForCoroutine指令
- 将WaitForCoroutine改为构造函数注入协程枚举器的方式 - 添加ProcessWaitingInstruction方法专门处理等待指令 - 添加IsWaiting方法判断协程等待状态 - 添加ProcessCoroutineStep方法处理协程步骤推进 - 添加HandleYieldInstruction方法处理yield指令逻辑 - 实现WaitForCoroutine指令的完整协程等待功能 - 在协程完成时通知WaitForCoroutine指令标记完成状态 - 优化协程调度器的执行流程和异常处理机制
This commit is contained in:
parent
4943fc5c70
commit
120fd14cd8
@ -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(
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理协程的等待指令
|
||||
/// </summary>
|
||||
/// <param name="slot">协程槽位</param>
|
||||
/// <param name="delta">时间差值</param>
|
||||
private static void ProcessWaitingInstruction(CoroutineSlot slot, double delta)
|
||||
{
|
||||
if (slot.Waiting == null)
|
||||
return;
|
||||
|
||||
slot.Waiting.Update(delta);
|
||||
if (slot.Waiting.IsDone)
|
||||
slot.Waiting = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断协程是否正在等待
|
||||
/// </summary>
|
||||
/// <param name="slot">协程槽位</param>
|
||||
/// <returns>是否正在等待</returns>
|
||||
private static bool IsWaiting(CoroutineSlot slot)
|
||||
{
|
||||
return slot.Waiting != null && !slot.Waiting.IsDone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理协程步骤推进
|
||||
/// </summary>
|
||||
/// <param name="slot">协程槽位</param>
|
||||
/// <param name="slotIndex">槽位索引</param>
|
||||
private void ProcessCoroutineStep(CoroutineSlot slot, int slotIndex)
|
||||
{
|
||||
if (!slot.Enumerator.MoveNext())
|
||||
{
|
||||
Complete(slotIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
var current = slot.Enumerator.Current;
|
||||
HandleYieldInstruction(slot, current);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理协程的yield指令
|
||||
/// </summary>
|
||||
/// <param name="slot">协程槽位</param>
|
||||
/// <param name="instruction">yield指令</param>
|
||||
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;
|
||||
}
|
||||
|
||||
@ -5,10 +5,21 @@ namespace GFramework.Core.coroutine.instructions;
|
||||
/// <summary>
|
||||
/// 等待协程完成的指令类,实现IYieldInstruction接口
|
||||
/// </summary>
|
||||
public sealed class WaitForCoroutine : IYieldInstruction
|
||||
/// <param name="coroutine">需要等待完成的协程枚举器</param>
|
||||
public sealed class WaitForCoroutine(IEnumerator<IYieldInstruction> coroutine) : IYieldInstruction
|
||||
{
|
||||
/// <summary>
|
||||
/// 更新方法,用于处理时间更新逻辑
|
||||
/// 获取内部协程枚举器
|
||||
/// </summary>
|
||||
internal IEnumerator<IYieldInstruction> Coroutine => coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前等待的协程是否已完成
|
||||
/// </summary>
|
||||
public bool IsDone { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新方法,用于处理协程等待逻辑
|
||||
/// </summary>
|
||||
/// <param name="delta">时间增量</param>
|
||||
public void Update(double delta)
|
||||
@ -16,12 +27,7 @@ public sealed class WaitForCoroutine : IYieldInstruction
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取协程是否已完成的状态
|
||||
/// </summary>
|
||||
public bool IsDone { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 内部方法,用于标记协程完成状态
|
||||
/// 标记协程等待完成
|
||||
/// </summary>
|
||||
internal void Complete()
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user