mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-25 21:34:28 +08:00
- 新增 Core API 参考文档,涵盖架构与模块、数据模型与系统、命令与查询等核心组件 - 添加事件系统接口详细文档,包括 IEvent、IEventBus、IUnRegister 等接口说明 - 提供完整的 API 使用示例路径、最佳实践与性能建议 - 包含架构图、依赖关系图与故障排查指南 - 添加测试用例参考与扩展方法说明 - [skip ci]
20 KiB
20 KiB
事件系统
**本文引用的文件** - [EventBus.cs](file://GFramework.Core/events/EventBus.cs) - [EasyEvent.cs](file://GFramework.Core/events/EasyEvent.cs) - [EasyEvents.cs](file://GFramework.Core/events/EasyEvents.cs) - [EasyEventGeneric.cs](file://GFramework.Core/events/EasyEventGeneric.cs) - [OrEvent.cs](file://GFramework.Core/events/OrEvent.cs) - [UnRegisterList.cs](file://GFramework.Core/events/UnRegisterList.cs) - [DefaultUnRegister.cs](file://GFramework.Core/events/DefaultUnRegister.cs) - [IEvent.cs](file://GFramework.Core.Abstractions/events/IEvent.cs) - [IEventBus.cs](file://GFramework.Core.Abstractions/events/IEventBus.cs) - [IUnRegister.cs](file://GFramework.Core.Abstractions/events/IUnRegister.cs) - [IUnRegisterList.cs](file://GFramework.Core.Abstractions/events/IUnRegisterList.cs) - [UnRegisterListExtension.cs](file://GFramework.Core/extensions/UnRegisterListExtension.cs) - [README.md](file://GFramework.Core/events/README.md) - [EventBusTests.cs](file://GFramework.Core.Tests/events/EventBusTests.cs) - [EasyEventsTests.cs](file://GFramework.Core.Tests/events/EasyEventsTests.cs) - [OrEventTests.cs](file://GFramework.Core.Tests/events/OrEventTests.cs) - [UnRegisterTests.cs](file://GFramework.Core.Tests/events/UnRegisterTests.cs)目录
简介
本文件系统性地解析 GFramework 事件系统,涵盖 EventBus 的类型化事件发布订阅机制、EasyEvent/EasyEvents 的事件定义与注册/触发/注销流程、OrEvent 的组合事件与传播策略、UnRegisterList 的自动注销与内存防护、以及性能优化与最佳实践。文档面向不同技术背景读者,既提供高层概览也给出代码级图示与来源标注。
项目结构
事件系统位于 GFramework.Core 的 events 目录,配合抽象接口层与扩展方法,形成“接口定义 + 具体实现 + 工具扩展”的分层结构;测试用例覆盖核心行为验证。
graph TB
subgraph "事件抽象层"
IE["IEvent 接口"]
IEB["IEventBus 接口"]
IUR["IUnRegister 接口"]
IURL["IUnRegisterList 接口"]
end
subgraph "事件实现层"
EE["EasyEvent 无参事件"]
EET["Event<T> 单参事件"]
EETK["Event<T,TK> 双参事件"]
EES["EasyEvents 全局事件管理器"]
EB["EventBus 类型化事件总线"]
OR["OrEvent 或组合事件"]
UR["DefaultUnRegister 默认注销器"]
URL["UnRegisterList 批量注销列表"]
end
subgraph "扩展与工具"
URE["UnRegisterListExtension 扩展方法"]
end
IE --> EE
IE --> EET
IE --> EETK
IEB --> EB
IUR --> UR
IURL --> URL
EB --> EES
EES --> EET
EES --> EETK
OR --> IE
OR --> URL
URE --> IUR
URE --> IURL
图表来源
- IEvent.cs
- IEventBus.cs
- IUnRegister.cs
- IUnRegisterList.cs
- EasyEvent.cs
- EasyEventGeneric.cs
- EasyEvents.cs
- EventBus.cs
- OrEvent.cs
- DefaultUnRegister.cs
- UnRegisterList.cs
- UnRegisterListExtension.cs
章节来源
核心组件
- IEvent/IEventBus/IUnRegister/IUnRegisterList:定义事件注册、发送、注销与批量管理的契约。
- EasyEvent/EasyEventGeneric:无参与单/双参事件的具体实现,支持注册、注销、触发。
- EasyEvents:全局事件管理器,按类型缓存事件实例,提供静态访问与懒加载。
- EventBus:类型化事件总线,封装 Send/Register/UnRegister 的统一入口。
- OrEvent:组合事件,支持“任一触发即触发”的或逻辑组合。
- UnRegisterList/DefaultUnRegister:注销对象与批量注销列表,保障资源回收与内存安全。
- UnRegisterListExtension:扩展方法,简化注册对象加入注销列表与批量注销。
章节来源
- IEvent.cs
- IEventBus.cs
- IUnRegister.cs
- IUnRegisterList.cs
- EasyEvent.cs
- EasyEventGeneric.cs
- EasyEvents.cs
- EventBus.cs
- OrEvent.cs
- UnRegisterList.cs
- DefaultUnRegister.cs
- UnRegisterListExtension.cs
架构总览
事件系统采用“接口 + 具体实现 + 扩展”的分层设计,EventBus 作为门面协调 EasyEvents 的事件实例与用户回调之间的注册/触发关系;OrEvent 提供组合能力;UnRegisterList/DefaultUnRegister 提供生命周期管理与内存防护。
classDiagram
class IEvent {
+Register(onEvent) IUnRegister
}
class IEventBus {
+Send<T>()
+Send<T>(e)
+Register<T>(onEvent) IUnRegister
+UnRegister<T>(onEvent)
}
class IUnRegister {
+UnRegister()
}
class IUnRegisterList {
+UnregisterList : IList~IUnRegister~
}
class EasyEvent
class Event_T_
class Event_T_TK_
class EasyEvents {
+GetOrAdd<T>() T
+GetEvent<T>() T
}
class EventBus
class OrEvent {
+Or(event) OrEvent
+Register(onEvent) IUnRegister
+UnRegister(onEvent)
}
class DefaultUnRegister
class UnRegisterList {
+Add(unRegister)
+UnRegisterAll()
}
IEvent <|.. EasyEvent
IEvent <|.. Event_T_
IEvent <|.. Event_T_TK_
IEventBus <|.. EventBus
IUnRegister <|.. DefaultUnRegister
IUnRegisterList <|.. UnRegisterList
OrEvent ..|> IUnRegisterList
EventBus --> EasyEvents : "GetOrAddEvent"
EasyEvents --> Event_T_ : "缓存/获取"
EasyEvents --> Event_T_TK_ : "缓存/获取"
OrEvent --> IEvent : "组合触发"
UnRegisterList --> IUnRegister : "聚合"
图表来源
- IEvent.cs
- IEventBus.cs
- IUnRegister.cs
- IUnRegisterList.cs
- EasyEvent.cs
- EasyEventGeneric.cs
- EasyEvents.cs
- EventBus.cs
- OrEvent.cs
- DefaultUnRegister.cs
- UnRegisterList.cs
详细组件分析
EventBus:类型化事件总线
- 设计要点
- 基于 EasyEvents 的类型缓存,按类型获取/创建事件实例。
- Send() 自动构造事件实例并触发;Send(T e) 直接触发指定实例。
- Register/UnRegister 将用户回调与具体事件绑定,返回可注销句柄。
- 关键流程
- 注册:通过 EasyEvents.GetOrAddEvent<Event>() 获取事件,再调用其 Register。
- 发送:根据是否传入实例选择自动构造或直接触发。
- 注销:定位事件实例并调用 UnRegister 移除回调。
sequenceDiagram
participant Client as "客户端"
participant Bus as "EventBus"
participant EMgr as "EasyEvents"
participant Ev as "Event<T>"
participant Handler as "回调"
Client->>Bus : "Register<T>(onEvent)"
Bus->>EMgr : "GetOrAddEvent<Event<T>>()"
EMgr-->>Bus : "Event<T> 实例"
Bus->>Ev : "Register(onEvent)"
Ev-->>Bus : "IUnRegister 句柄"
Client->>Bus : "Send<T>(e)"
Bus->>Ev : "Trigger(e)"
Ev->>Handler : "onEvent(e)"
图表来源
章节来源
EasyEvent 与 Event/Event<T,TK>:事件定义与触发
- EasyEvent:无参事件,支持注册/注销/触发,内部以空操作委托避免空检查。
- Event/Event<T,TK>:泛型事件,支持单/双参数触发,同时显式实现 IEvent.Register(Action),允许无参订阅。
- 注册/注销:均返回 IUnRegister,确保可随时注销;触发时调用内部委托链。
flowchart TD
Start(["注册回调"]) --> Add["加入内部委托链"]
Add --> Handle["返回 IUnRegister 句柄"]
Handle --> Trigger["触发事件"]
Trigger --> Invoke["依次调用回调"]
Invoke --> End(["完成"])
图表来源
章节来源
EasyEvents:全局事件管理器
- 功能:全局单例缓存事件类型与其实例映射;提供静态/实例方法获取/注册/添加事件。
- 行为:GetOrAddEvent() 若不存在则自动构造并加入字典;GetEvent() 返回默认值(若不存在)。
- 用途:为 EventBus 提供事件实例的集中管理与复用。
flowchart TD
A["请求事件类型 T"] --> B{"字典中存在 T ?"}
B -- 否 --> C["new T() 并加入字典"]
B -- 是 --> D["返回缓存实例"]
C --> E["返回新实例"]
D --> E
图表来源
章节来源
OrEvent:组合事件与传播策略
- 设计:将多个 IEvent 通过 Or 进行“或”组合,任意子事件触发即触发 OrEvent。
- 传播:内部维护回调链,子事件触发时调用私有 Trigger(),进而触发所有注册到 OrEvent 的回调。
- 注销:支持普通注销;注销回调时会触发 UnRegisterAll,清理组合内的子事件注册。
sequenceDiagram
participant O as "OrEvent"
participant E1 as "Event<T>"
participant E2 as "Event<T>"
participant H as "回调"
O->>E1 : "Register(Trigger)"
O->>E2 : "Register(Trigger)"
E1-->>O : "Trigger()"
O->>H : "回调被触发"
E2-->>O : "Trigger()"
O->>H : "再次触发回调"
图表来源
章节来源
UnRegisterList 与 DefaultUnRegister:自动注销与内存防护
- DefaultUnRegister:封装注销回调,执行后清理引用,避免重复执行。
- UnRegisterList:聚合多个 IUnRegister,提供 UnRegisterAll 一键注销并清空列表。
- 扩展方法:AddToUnregisterList/UnRegisterAll 简化注册与批量注销流程。
sequenceDiagram
participant C as "组件"
participant L as "UnRegisterList"
participant R as "IUnRegister"
participant U as "DefaultUnRegister"
C->>R : "注册事件并获得句柄"
R-->>C : "IUnRegister"
C->>L : "AddToUnregisterList(L)"
Note over C,L : "收集多个注销句柄"
C->>L : "UnRegisterAll()"
L->>R : "遍历调用 UnRegister()"
R->>U : "执行注销回调并清理"
图表来源
章节来源
依赖分析
- 组件内聚与耦合
- EventBus 与 EasyEvents 高度耦合:前者依赖后者进行事件实例缓存与获取。
- EasyEvent/EasyEventGeneric 与 IEvent 解耦,通过接口约束统一注册/触发行为。
- OrEvent 与 IEvent/IUnRegisterList 解耦,通过组合与扩展方法实现功能。
- UnRegisterList 与 IUnRegister 解耦,通过聚合实现批量管理。
- 外部依赖
- 无外部第三方库依赖,纯 .NET 抽象与标准集合。
- 循环依赖
- 未发现循环依赖;EventBus 依赖 EasyEvents,EasyEvents 依赖事件类型,但不反向依赖。
graph LR
EB["EventBus"] --> EES["EasyEvents"]
EES --> EET["Event<T>"]
EES --> EETK["Event<T,TK>"]
OR["OrEvent"] --> IE["IEvent"]
URL["UnRegisterList"] --> IUR["IUnRegister"]
URE["UnRegisterListExtension"] --> IUR
URE --> IURL
图表来源
- EventBus.cs
- EasyEvents.cs
- EasyEventGeneric.cs
- OrEvent.cs
- UnRegisterList.cs
- UnRegisterListExtension.cs
章节来源
性能考量
- 事件缓存与懒加载
- EasyEvents 使用字典缓存事件实例,避免重复构造,降低 GC 压力。
- 委托链与空操作
- 内部默认使用空操作委托,减少 null 检查与分支开销。
- 结构体事件
- README 建议使用 struct 事件以减少堆分配,提升吞吐。
- 触发频率控制
- 避免高频事件(如每帧触发),建议使用批处理或节流策略。
- 回调轻量化
- 事件处理器应保持轻量,避免长耗时逻辑阻塞主线程。
章节来源
故障排除指南
- 注册后未触发
- 检查事件类型是否一致;确认 Send() 是否传入了正确的事件实例。
- 参考测试用例验证注册/触发流程。
- 注销无效
- 确认使用的是同一回调引用;注销需与注册时的委托引用一致。
- 使用 UnRegisterList 统一管理,避免遗漏。
- OrEvent 未按预期触发
- 确认已通过 Or() 将子事件加入组合;检查子事件是否已注册回调。
- 内存泄漏风险
- 确保在组件生命周期结束时调用 UnRegisterAll;避免持有事件实例的强引用导致无法释放。
- 回调重复执行
- DefaultUnRegister 在执行后会清理回调引用,避免重复执行;若仍出现,请检查是否重复注册。
章节来源
结论
GFramework 事件系统通过清晰的接口与分层实现,提供了类型安全、易于组合、可批量管理的事件机制。EventBus/EasyEvents 提供统一入口与缓存;EasyEvent/EasyEventGeneric 支持多参数场景;OrEvent 实现灵活的组合传播;UnRegisterList/DefaultUnRegister 强化生命周期管理与内存安全。结合性能建议与最佳实践,可在复杂游戏架构中构建松耦合、高可维护的组件通信体系。
附录
API 参考(摘要)
- IEvent
- Register(Action onEvent) IUnRegister
- IEventBus
- Send()(自动构造)
- Send(T e)
- Register(Action onEvent) IUnRegister
- UnRegister(Action onEvent)
- IUnRegister
- UnRegister()
- IUnRegisterList
- UnregisterList : IList
- EasyEvent
- Register(Action) IUnRegister
- UnRegister(Action)
- Trigger()
- Event/Event<T,TK>
- Register(Action) / Register(Action<T,TK>) IUnRegister
- UnRegister(Action) / UnRegister(Action<T,TK>)
- Trigger(T) / Trigger(T,TK)
- EasyEvents
- GetOrAdd() T
- GetEvent() T
- OrEvent
- Or(IEvent) OrEvent
- Register(Action) IUnRegister
- UnRegister(Action)
- UnRegisterList
- Add(IUnRegister)
- UnRegisterAll()
- DefaultUnRegister
- UnRegister()
章节来源
- IEvent.cs
- IEventBus.cs
- IUnRegister.cs
- IUnRegisterList.cs
- EasyEvent.cs
- EasyEventGeneric.cs
- EasyEvents.cs
- OrEvent.cs
- UnRegisterList.cs
- DefaultUnRegister.cs
使用示例(路径指引)
- 无参事件
- 单/双参事件
- 全局事件管理
- 事件总线
- 组合事件
- 批量注销
- 架构集成与控制器注册
最佳实践(摘要)
- 事件命名与数据设计:使用过去式 + Event 后缀;事件结构体化;最小化数据。
- 避免事件循环:谨慎在处理器中发送新事件;必要时使用命令。
- 合理使用事件:通知状态变化与跨模块通信;查询使用 Query。
- 注销管理:始终注销;使用 IUnRegisterList;利用节点生命周期。
- 性能优化:避免高频事件;处理器轻量化;使用结构体事件减少 GC。
章节来源