using System.Collections; using GFramework.Game.Abstractions.coroutine; namespace GFramework.Game.coroutine; /// /// 协程句柄类,用于管理和控制协程的执行状态 /// 实现了IYieldInstruction和ICoroutineHandle接口 /// public class CoroutineHandle : IYieldInstruction, ICoroutineHandle { /// /// 存储协程执行栈的堆栈结构 /// private readonly Stack _stack = new(); /// /// 当前等待执行的指令 /// private IYieldInstruction? _waitingInstruction; /// /// 初始化一个新的协程句柄实例 /// /// 要执行的枚举器协程 /// 协程上下文环境 /// 初始等待的指令 internal CoroutineHandle(IEnumerator routine, CoroutineContext context, IYieldInstruction? waitingInstruction) { _stack.Push(routine); Context = context; _waitingInstruction = waitingInstruction; } /// /// 获取协程的上下文环境 /// public CoroutineContext Context { get; } /// /// 获取协程句柄的上下文环境(接口实现) /// ICoroutineContext ICoroutineHandle.Context => Context; /// /// 获取协程是否已被取消的标志 /// public bool IsCancelled { get; private set; } /// /// 协程完成时触发的事件 /// public event Action? OnComplete; /// /// 协程发生错误时触发的事件 /// public event Action? OnError; /// /// 取消协程的执行 /// public void Cancel() { if (IsDone) return; IsDone = true; IsCancelled = true; _stack.Clear(); _waitingInstruction = null; OnComplete?.Invoke(); } /// /// 获取协程是否已完成的标志 /// public bool IsDone { get; private set; } /// /// 更新协程执行状态(接口实现) /// /// 时间增量 void IYieldInstruction.Update(float deltaTime) { InternalUpdate(deltaTime); } /// /// 内部更新协程执行逻辑 /// /// 时间增量 /// 如果协程仍在运行返回true,否则返回false private bool InternalUpdate(float deltaTime) { if (IsDone) return false; // 检查并更新当前等待的指令 if (_waitingInstruction != null) { _waitingInstruction.Update(deltaTime); if (!_waitingInstruction.IsDone) return true; _waitingInstruction = null; } if (_stack.Count == 0) { Complete(); return false; } try { var current = _stack.Peek(); if (current.MoveNext()) { ProcessYieldValue(current.Current); return true; } _stack.Pop(); return _stack.Count > 0 || !CompleteCheck(); } catch (Exception ex) { HandleError(ex); return false; } } /// /// 处理协程中yield返回的值,根据类型决定如何处理 /// /// 协程yield返回的对象 private void ProcessYieldValue(object yielded) { switch (yielded) { case CoroutineHandle otherHandle: _waitingInstruction = otherHandle; break; case IEnumerator nested: _stack.Push(nested); break; case IYieldInstruction instruction: _waitingInstruction = instruction; break; case null: break; default: throw new InvalidOperationException($"Unsupported yield type: {yielded.GetType()}"); } } /// /// 检查协程是否完成并进行相应处理 /// /// 如果协程已完成返回true,否则返回false private bool CompleteCheck() { if (_stack.Count == 0) Complete(); return IsDone; } /// /// 标记协程完成并清理相关资源 /// private void Complete() { if (IsDone) return; IsDone = true; _stack.Clear(); _waitingInstruction = null; OnComplete?.Invoke(); } /// /// 处理协程执行过程中发生的异常 /// /// 发生的异常 private void HandleError(Exception ex) { IsDone = true; _stack.Clear(); _waitingInstruction = null; OnError?.Invoke(ex); } }