GeWuYou a79f02c987 docs(api): 添加 Core API 参考文档与事件系统接口文档
- 新增 Core API 参考文档,涵盖架构与模块、数据模型与系统、命令与查询等核心组件
- 添加事件系统接口详细文档,包括 IEvent、IEventBus、IUnRegister 等接口说明
- 提供完整的 API 使用示例路径、最佳实践与性能建议
- 包含架构图、依赖关系图与故障排查指南
- 添加测试用例参考与扩展方法说明
- [skip ci]
2026-01-21 23:45:10 +08:00

18 KiB
Raw Blame History

Godot协程集成

**本文档引用的文件** - [CoroutineExtensions.cs](file://GFramework.Godot/coroutine/CoroutineExtensions.cs) - [GodotTimeSource.cs](file://GFramework.Godot/coroutine/GodotTimeSource.cs) - [Segment.cs](file://GFramework.Godot/coroutine/Segment.cs) - [Timing.cs](file://GFramework.Godot/coroutine/Timing.cs) - [ITimeSource.cs](file://GFramework.Core.Abstractions/coroutine/ITimeSource.cs) - [CoroutineScheduler.cs](file://GFramework.Core/coroutine/CoroutineScheduler.cs) - [Delay.cs](file://GFramework.Core/coroutine/Delay.cs) - [WaitForFrames.cs](file://GFramework.Core/coroutine/WaitForFrames.cs) - [WaitOneFrame.cs](file://GFramework.Core/coroutine/WaitOneFrame.cs) - [WaitUntil.cs](file://GFramework.Core/coroutine/WaitUntil.cs) - [WaitWhile.cs](file://GFramework.Core/coroutine/WaitWhile.cs) - [CoroutineHandle.cs](file://GFramework.Core/coroutine/CoroutineHandle.cs) - [CoroutineSchedulerTests.cs](file://GFramework.Core.Tests/coroutine/CoroutineSchedulerTests.cs) - [YieldInstructionTests.cs](file://GFramework.Core.Tests/coroutine/YieldInstructionTests.cs)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构概览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考虑
  8. 故障排除指南
  9. 结论
  10. 附录

简介

GFramework的Godot协程集成为Godot引擎提供了强大的异步编程能力。该集成通过CoroutineExtensions将GFramework的核心协程系统与Godot的场景树和节点生命周期无缝连接实现了基于帧率和时间管理机制的精确协程调度。

本系统的核心特性包括:

  • 多段执行支持支持Process、PhysicsProcess和DeferredProcess三种执行段
  • 节点生命周期集成:协程能够自动响应节点的创建和销毁
  • 精确时间测量基于Godot引擎的帧率和时间管理机制
  • 性能监控:内置活跃协程数量统计和调试信息
  • 灵活的等待指令:支持延迟、帧等待、条件等待等多种等待类型

项目结构

GFramework的Godot协程集成位于GFramework.Godot项目中主要包含以下关键文件

graph TB
subgraph "GFramework.Godot 协程模块"
CE[CoroutineExtensions.cs<br/>协程扩展方法]
GTS[GodotTimeSource.cs<br/>Godot时间源实现]
S[Segment.cs<br/>执行段枚举]
T[Timing.cs<br/>协程管理器]
end
subgraph "GFramework.Core 核心协程"
CS[CoroutineScheduler.cs<br/>协程调度器]
CH[CoroutineHandle.cs<br/>协程句柄]
D[Delay.cs<br/>延迟等待指令]
WF[WaitForFrames.cs<br/>帧等待指令]
WOF[WaitOneFrame.cs<br/>单帧等待指令]
WU[WaitUntil.cs<br/>条件等待指令]
WW[WaitWhile.cs<br/>条件等待指令]
end
subgraph "抽象接口"
ITS[ITimeSource.cs<br/>时间源接口]
end
CE --> T
T --> CS
CS --> CH
CS --> ITS
GTS --> ITS
T --> GTS
CS --> D
CS --> WF
CS --> WOF
CS --> WU
CS --> WW

图表来源

章节来源

核心组件

协程扩展方法 (CoroutineExtensions)

CoroutineExtensions提供了简洁的API来启动和管理协程主要包含以下功能

  1. RunCoroutine扩展方法:启动协程并在指定执行段中运行
  2. CancelWith扩展方法:让协程在节点销毁时自动取消
  3. 多节点取消支持:支持同时监控多个节点的状态

Godot时间源实现 (GodotTimeSource)

GodotTimeSource实现了ITimeSource接口为协程系统提供基于Godot引擎的时间信息

  • CurrentTime属性:当前累计时间
  • DeltaTime属性:上一帧的时间增量
  • Update方法:更新时间源状态
  • Reset方法:重置时间源到初始状态

执行段枚举 (Segment)

定义了协程执行的不同时间段:

  • Process:普通处理阶段
  • PhysicsProcess:物理处理阶段
  • DeferredProcess:延迟处理阶段

协程管理器 (Timing)

Timing是Godot协程系统的核心继承自Node类提供完整的协程生命周期管理

  • 单例模式:确保全局唯一的协程管理器
  • 多调度器支持:为不同执行段维护独立的调度器
  • 生命周期集成与Godot节点生命周期完全同步
  • 调试信息:提供活跃协程数量统计

章节来源

架构概览

GFramework的Godot协程集成采用分层架构设计实现了清晰的关注点分离

graph TB
subgraph "应用层"
App[用户代码<br/>IEnumerator<IYieldInstruction>]
end
subgraph "Godot集成层"
CE[CoroutineExtensions<br/>扩展方法]
T[Timing<br/>协程管理器]
end
subgraph "核心协程层"
CS[CoroutineScheduler<br/>调度器]
CH[CoroutineHandle<br/>句柄]
TS[GodotTimeSource<br/>时间源]
end
subgraph "等待指令层"
D[Delay<br/>延迟等待]
WF[WaitForFrames<br/>帧等待]
WOF[WaitOneFrame<br/>单帧等待]
WU[WaitUntil<br/>条件等待]
WW[WaitWhile<br/>条件等待]
end
subgraph "Godot引擎层"
GT[Godot引擎<br/>帧率管理]
end
App --> CE
CE --> T
T --> CS
CS --> CH
CS --> TS
CS --> D
CS --> WF
CS --> WOF
CS --> WU
CS --> WW
TS --> GT

图表来源

该架构的关键优势:

  • 解耦设计:各层职责明确,便于维护和扩展
  • 性能优化使用固定大小数组和池化技术减少GC压力
  • 线程安全通过Godot的单线程模型保证协程执行的安全性
  • 资源管理:自动管理协程生命周期,防止内存泄漏

详细组件分析

Timing协程管理器

Timing类是整个协程系统的核心负责协调所有协程的执行

生命周期管理

sequenceDiagram
participant Scene as 场景树
participant Timing as Timing节点
participant Scheduler as 协程调度器
Scene->>Timing : 创建节点
Timing->>Timing : _Ready()
Timing->>Scheduler : InitializeSchedulers()
Scheduler->>Scheduler : 创建Process/Physics/Deferred调度器
loop 每帧更新
Scene->>Timing : _Process(delta)
Timing->>Scheduler : ProcessScheduler.Update()
Timing->>Timing : CallDeferred(ProcessDeferred)
Timing->>Timing : ProcessDeferred()
Timing->>Scheduler : DeferredScheduler.Update()
Scene->>Timing : _PhysicsProcess(delta)
Timing->>Scheduler : PhysicsScheduler.Update()
end
Scene->>Timing : _ExitTree()
Timing->>Timing : CleanupInstanceIfNecessary()

图表来源

协程执行策略

Timing实现了三种不同的执行策略

  1. Process段每帧常规处理适合UI动画和一般逻辑
  2. PhysicsProcess段:物理更新循环,适合与物理引擎同步的操作
  3. DeferredProcess段:当前帧结束后延迟执行,避免帧内竞争

协程句柄系统

classDiagram
class CoroutineHandle {
-int _id
+byte Key
+bool IsValid
+CoroutineHandle(byte instanceId)
+Equals(CoroutineHandle) bool
+GetHashCode() int
}
class CoroutineScheduler {
-Dictionary~CoroutineHandle, CoroutineMetadata~ _metadata
-Dictionary~string, HashSet~CoroutineHandle~~ _tagged
-CoroutineSlot~[] _slots
+int ActiveCoroutineCount
+CoroutineHandle Run(IEnumerator, string) CoroutineHandle
+void Update() void
+bool Pause(CoroutineHandle) bool
+bool Resume(CoroutineHandle) bool
+bool Kill(CoroutineHandle) bool
}
class CoroutineMetadata {
+int SlotIndex
+CoroutineState State
+string Tag
}
CoroutineScheduler --> CoroutineHandle : "管理"
CoroutineScheduler --> CoroutineMetadata : "存储元数据"

图表来源

章节来源

等待指令系统

GFramework提供了多种等待指令来满足不同的协程需求

延迟等待指令 (Delay)

Delay指令是最基础的等待类型基于时间进行等待

flowchart TD
Start([开始延迟]) --> Init["初始化剩余时间<br/>_remaining = Math.Max(0, seconds)"]
Init --> Update["Update(deltaTime)<br/>_remaining -= deltaTime"]
Update --> Check{"_remaining <= 0?"}
Check --> |否| Continue["继续等待"]
Check --> |是| Done["等待完成<br/>IsDone = true"]
Continue --> Update

图表来源

帧等待指令 (WaitForFrames)

WaitForFrames指令等待指定数量的帧数

flowchart TD
Start([开始帧等待]) --> Init["初始化剩余帧数<br/>_remaining = Math.Max(1, frames)"]
Init --> Update["Update(deltaTime)<br/>_remaining--"]
Update --> Check{"_remaining <= 0?"}
Check --> |否| Continue["继续等待"]
Check --> |是| Done["等待完成<br/>IsDone = true"]
Continue --> Update

图表来源

条件等待指令

条件等待指令基于布尔条件进行等待:

  • WaitUntil等待条件变为true
  • WaitWhile等待条件变为false

章节来源

协程扩展方法

CoroutineExtensions提供了便捷的方法来集成Godot的节点生命周期

自动取消机制

sequenceDiagram
participant User as 用户代码
participant Ext as CancelWith扩展
participant Timing as Timing系统
participant Node as Godot节点
User->>Ext : coroutine.CancelWith(node)
loop 协程执行
Ext->>Timing : IsNodeAlive(node)
Timing->>Node : 检查节点状态
alt 节点仍然存活
Ext->>Ext : coroutine.MoveNext()
Ext-->>User : yield return coroutine.Current
else 节点已销毁
Ext-->>User : 协程自动结束
end
end

图表来源

章节来源

依赖关系分析

GFramework的协程系统采用了清晰的依赖层次结构

graph TB
subgraph "抽象层"
ITimeSource[ITimeSource接口]
IYieldInstruction[IYieldInstruction接口]
end
subgraph "Godot集成层"
GodotTimeSource[GodotTimeSource实现]
CoroutineExtensions[协程扩展方法]
Timing[Timing管理器]
end
subgraph "核心实现层"
CoroutineScheduler[协程调度器]
CoroutineHandle[协程句柄]
CoroutineSlot[协程槽位]
end
subgraph "等待指令层"
Delay[Delay指令]
WaitForFrames[WaitForFrames指令]
WaitOneFrame[WaitOneFrame指令]
WaitUntil[WaitUntil指令]
WaitWhile[WaitWhile指令]
end
ITimeSource --> GodotTimeSource
IYieldInstruction --> Delay
IYieldInstruction --> WaitForFrames
IYieldInstruction --> WaitOneFrame
IYieldInstruction --> WaitUntil
IYieldInstruction --> WaitWhile
GodotTimeSource --> CoroutineScheduler
CoroutineExtensions --> Timing
Timing --> CoroutineScheduler
CoroutineScheduler --> CoroutineHandle
CoroutineScheduler --> CoroutineSlot
Delay --> CoroutineScheduler
WaitForFrames --> CoroutineScheduler
WaitOneFrame --> CoroutineScheduler
WaitUntil --> CoroutineScheduler
WaitWhile --> CoroutineScheduler

图表来源

章节来源

性能考虑

内存管理优化

GFramework协程系统采用了多项内存优化技术

  1. 固定大小数组使用预分配的数组而不是动态集合减少GC压力
  2. 对象池化:复用协程槽位和元数据对象
  3. 轻量级句柄CoroutineHandle使用结构体设计避免额外的内存分配
  4. 延迟初始化:只在需要时创建调度器和时间源

执行效率优化

  1. 直接索引访问:通过槽位数组直接访问协程,避免字典查找开销
  2. 批量更新:每帧统一更新所有协程,减少方法调用次数
  3. 早期退出:跳过非运行状态的协程,提高更新效率
  4. 异常处理优化最小化try-catch块的范围减少异常开销

资源限制

系统实现了严格的资源限制来防止内存泄漏:

  • 最大实例数量最多支持15个Timing实例
  • 活跃协程限制:每个调度器都有初始容量限制
  • 自动清理:节点销毁时自动清理相关协程

章节来源

故障排除指南

常见问题及解决方案

协程未执行问题

症状:协程启动但没有执行任何代码

可能原因

  1. Timing实例未正确初始化
  2. 协程句柄无效
  3. 调度器未正确配置

解决方案

  • 确保Timing节点存在于场景树中
  • 检查协程句柄的IsValid属性
  • 验证调度器的初始化状态

协程无法停止问题

症状:协程无法被暂停或终止

可能原因

  1. 协程句柄不正确
  2. 协程已执行完毕
  3. 协程在错误的实例上运行

解决方案

  • 使用正确的协程句柄进行控制
  • 检查协程的ActiveCoroutineCount
  • 确认协程在预期的实例上运行

内存泄漏问题

症状:应用内存持续增长

可能原因

  1. 协程未正确清理
  2. 节点生命周期管理不当
  3. 大量活跃协程

解决方案

  • 确保所有协程在节点销毁时自动清理
  • 使用CancelWith扩展方法
  • 监控活跃协程数量

调试技巧

  1. 活跃协程监控使用Timing类的调试属性监控协程数量
  2. 日志记录:在关键节点添加日志输出
  3. 单元测试:编写针对协程行为的测试用例

章节来源

结论

GFramework的Godot协程集成为开发者提供了一个强大而高效的异步编程框架。通过将GFramework的核心协程系统与Godot的场景树和节点生命周期深度集成该系统实现了

  • 无缝集成与Godot引擎的帧率和时间管理机制完美配合
  • 灵活执行:支持多种执行段和等待指令
  • 性能优化:采用多项优化技术确保高效执行
  • 易于使用提供简洁的API和丰富的扩展方法
  • 可靠稳定:完善的错误处理和资源管理机制

该系统特别适合需要复杂异步逻辑的游戏开发场景如UI动画、游戏流程控制、网络请求处理等。通过遵循最佳实践和合理使用提供的工具开发者可以构建高性能、可维护的协程驱动应用。

附录

使用示例

基本协程启动

// 在Process段启动协程
IEnumerator<IYieldInstruction> myCoroutine = MyCoroutineMethod();
CoroutineHandle handle = coroutine.RunCoroutine(Segment.Process);

// 在PhysicsProcess段启动协程
CoroutineHandle physicsHandle = coroutine.RunCoroutine(Segment.PhysicsProcess);

自动取消协程

// 协程在节点销毁时自动取消
IEnumerator<IYieldInstruction> cancellableCoroutine = 
    someCoroutine.CancelWith(this);

// 监控多个节点
IEnumerator<IYieldInstruction> multiNodeCoroutine = 
    someCoroutine.CancelWith(node1, node2, node3);

延迟调用

// 延迟执行动作
Timing.CallDelayed(2.0, () => Console.WriteLine("2秒后执行"));

// 带取消条件的延迟调用
Timing.CallDelayed(1.0, () => DoSomething(), targetNode);

最佳实践

  1. 合理选择执行段:根据协程的性质选择合适的执行段
  2. 及时清理资源:确保协程在不需要时能够正确清理
  3. 监控性能:定期检查活跃协程数量和内存使用情况
  4. 错误处理:为协程添加适当的异常处理机制
  5. 测试验证:编写单元测试验证协程的行为正确性