# EasyEvent事件机制
**本文档引用的文件**
- [EasyEvent.cs](file://GFramework.Core/events/EasyEvent.cs)
- [EasyEventGeneric.cs](file://GFramework.Core/events/EasyEventGeneric.cs)
- [EventBus.cs](file://GFramework.Core/events/EventBus.cs)
- [EasyEvents.cs](file://GFramework.Core/events/EasyEvents.cs)
- [DefaultUnRegister.cs](file://GFramework.Core/events/DefaultUnRegister.cs)
- [UnRegisterList.cs](file://GFramework.Core/events/UnRegisterList.cs)
- [OrEvent.cs](file://GFramework.Core/events/OrEvent.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)
- [UnRegisterListExtension.cs](file://GFramework.Core/extensions/UnRegisterListExtension.cs)
- [README.md](file://GFramework.Core/events/README.md)
- [EventTests.cs](file://GFramework.Core.Tests/events/EventTests.cs)
- [EasyEventsTests.cs](file://GFramework.Core.Tests/events/EasyEventsTests.cs)
- [EventBusTests.cs](file://GFramework.Core.Tests/events/EventBusTests.cs)
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构概览](#架构概览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排除指南](#故障排除指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
EasyEvent事件机制是GFramework框架中一套完整的事件系统,实现了观察者模式(Observer Pattern),为游戏开发提供了松耦合的组件间通信能力。该系统支持无参和带参事件、事件注册/注销、以及灵活的事件组合。
事件机制的核心设计理念包括:
- **松耦合通信**:组件间通过事件进行解耦
- **类型安全**:利用泛型确保编译时类型安全
- **内存优化**:采用空操作委托避免null检查
- **生命周期管理**:提供完整的注册和注销机制
- **批量处理**:支持事件处理器的批量添加和移除
## 项目结构
事件系统位于GFramework.Core项目的events目录下,采用分层设计:
```mermaid
graph TB
subgraph "事件抽象层"
IEvent[IEvent接口]
IEventBus[IEventBus接口]
IUnRegister[IUnRegister接口]
end
subgraph "事件实现层"
EasyEvent[EasyEvent]
EventT[Event]
EventTTK[Event]
EventBus[EventBus]
EasyEvents[EasyEvents]
OrEvent[OrEvent]
end
subgraph "辅助组件"
DefaultUnRegister[DefaultUnRegister]
UnRegisterList[UnRegisterList]
UnRegisterListExtension[UnRegisterListExtension]
end
IEvent --> EasyEvent
IEvent --> EventT
IEvent --> EventTTK
IEventBus --> EventBus
IUnRegister --> DefaultUnRegister
UnRegisterListExtension --> UnRegisterList
```
**图表来源**
- [IEvent.cs](file://GFramework.Core.Abstractions/events/IEvent.cs#L8-L16)
- [IEventBus.cs](file://GFramework.Core.Abstractions/events/IEventBus.cs#L8-L37)
- [EasyEvent.cs](file://GFramework.Core/events/EasyEvent.cs#L8-L39)
- [EasyEventGeneric.cs](file://GFramework.Core/events/EasyEventGeneric.cs#L10-L123)
**章节来源**
- [README.md](file://GFramework.Core/events/README.md#L1-L523)
## 核心组件
### 事件接口体系
事件系统基于三个核心接口构建:
1. **IEvent接口**:定义事件注册的基本功能
2. **IEventBus接口**:提供基于类型的事件发送和注册
3. **IUnRegister接口**:用于取消事件注册
```mermaid
classDiagram
class IEvent {
<>
+Register(onEvent) IUnRegister
}
class IEventBus {
<>
+Send~T~() void
+Send~T~(e) void
+Register~T~(onEvent) IUnRegister
+UnRegister~T~(onEvent) void
}
class IUnRegister {
<>
+UnRegister() void
}
class EasyEvent {
-_mOnEvent Action
+Register(onEvent) IUnRegister
+UnRegister(onEvent) void
+Trigger() void
}
class Event~T~ {
-_mOnEvent Action~T~
+Register(onEvent) IUnRegister
+UnRegister(onEvent) void
+Trigger(t) void
}
IEvent <|-- EasyEvent
IEvent <|-- Event~T~
IEventBus <|-- EventBus
IUnRegister <|-- DefaultUnRegister
```
**图表来源**
- [IEvent.cs](file://GFramework.Core.Abstractions/events/IEvent.cs#L8-L16)
- [IEventBus.cs](file://GFramework.Core.Abstractions/events/IEventBus.cs#L8-L37)
- [EasyEvent.cs](file://GFramework.Core/events/EasyEvent.cs#L8-L39)
- [EasyEventGeneric.cs](file://GFramework.Core/events/EasyEventGeneric.cs#L10-L62)
**章节来源**
- [IEvent.cs](file://GFramework.Core.Abstractions/events/IEvent.cs#L1-L16)
- [IEventBus.cs](file://GFramework.Core.Abstractions/events/IEventBus.cs#L1-L37)
- [IUnRegister.cs](file://GFramework.Core.Abstractions/events/IUnRegister.cs#L1-L12)
## 架构概览
事件系统采用分层架构设计,从底层的事件实现到上层的事件总线,形成了完整的事件处理生态:
```mermaid
graph TD
subgraph "应用层"
Controllers[控制器]
Systems[系统]
Models[模型]
end
subgraph "事件管理层"
EventBus[事件总线]
EasyEvents[全局事件管理器]
OrEvent[事件组合器]
end
subgraph "事件实现层"
EasyEvent[简单事件]
EventT[单参数事件]
EventTTK[双参数事件]
UnRegisterList[注销列表]
end
subgraph "基础设施层"
DefaultUnRegister[默认注销器]
UnRegisterListExtension[注销扩展]
end
Controllers --> EventBus
Systems --> EventBus
Models --> EventBus
EventBus --> EasyEvents
EventBus --> OrEvent
EasyEvents --> EasyEvent
EasyEvents --> EventT
EasyEvents --> EventTTK
UnRegisterListExtension --> UnRegisterList
DefaultUnRegister --> UnRegisterList
```
**图表来源**
- [EventBus.cs](file://GFramework.Core/events/EventBus.cs#L8-L55)
- [EasyEvents.cs](file://GFramework.Core/events/EasyEvents.cs#L9-L85)
- [OrEvent.cs](file://GFramework.Core/events/OrEvent.cs#L9-L57)
## 详细组件分析
### EasyEvent组件分析
EasyEvent是最简单的事件实现,支持无参事件的注册、注销和触发:
```mermaid
sequenceDiagram
participant Client as 客户端
participant Event as EasyEvent
participant Handler as 事件处理器
participant UnReg as 注销器
Client->>Event : Register(handler)
Event->>Event : 添加到_mOnEvent委托链
Event->>UnReg : 创建DefaultUnRegister
UnReg-->>Client : 返回注销对象
Client->>Event : Trigger()
Event->>Handler : 调用所有注册的处理器
Handler-->>Event : 处理完成
Client->>UnReg : UnRegister()
UnReg->>Event : 调用注销回调
Event->>Event : 从_mOnEvent委托链移除
```
**图表来源**
- [EasyEvent.cs](file://GFramework.Core/events/EasyEvent.cs#L17-L38)
- [DefaultUnRegister.cs](file://GFramework.Core/events/DefaultUnRegister.cs#L9-L22)
EasyEvent的关键特性:
- **委托链管理**:使用Action委托链存储多个处理器
- **空操作优化**:初始状态为空操作委托,避免null检查
- **即时注销**:注册时返回的注销对象支持立即注销
**章节来源**
- [EasyEvent.cs](file://GFramework.Core/events/EasyEvent.cs#L1-L39)
### 泛型事件组件分析
EasyEventGeneric提供了支持泛型参数的事件实现,包括单参数和双参数事件:
```mermaid
classDiagram
class Event~T~ {
-_mOnEvent Action~T~
+Register(onEvent) IUnRegister
+UnRegister(onEvent) void
+Trigger(t) void
+IEvent.Register(onEvent) IUnRegister
}
class Event~T,TK~ {
-_mOnEvent Action~T,TK~
+Register(onEvent) IUnRegister
+UnRegister(onEvent) void
+Trigger(t, k) void
+IEvent.Register(onEvent) IUnRegister
}
class IEvent {
<>
+Register(onEvent) IUnRegister
}
IEvent <|-- Event~T~
IEvent <|-- Event~T,TK~
```
**图表来源**
- [EasyEventGeneric.cs](file://GFramework.Core/events/EasyEventGeneric.cs#L10-L123)
泛型事件的实现特点:
- **类型安全**:编译时确保参数类型正确
- **接口显式实现**:支持无参Action的注册
- **委托链优化**:同样采用空操作委托避免null检查
**章节来源**
- [EasyEventGeneric.cs](file://GFramework.Core/events/EasyEventGeneric.cs#L1-L123)
### 事件总线组件分析
EventBus提供了基于类型的事件发送、注册和注销功能:
```mermaid
sequenceDiagram
participant Client as 客户端
participant Bus as EventBus
participant Manager as EasyEvents
participant Event as Event
participant Handler as 处理器
Note over Client,Bus : 发送事件
Client->>Bus : Send()
Bus->>Manager : GetOrAddEvent>()
Manager->>Event : 创建或获取事件实例
Bus->>Event : Trigger(new T())
Event->>Handler : 调用所有处理器
Note over Client,Bus : 注册事件
Client->>Bus : Register(handler)
Bus->>Manager : GetOrAddEvent>()
Manager->>Event : 获取事件实例
Bus->>Event : Register(handler)
Event-->>Client : 返回注销对象
```
**图表来源**
- [EventBus.cs](file://GFramework.Core/events/EventBus.cs#L16-L54)
- [EasyEvents.cs](file://GFramework.Core/events/EasyEvents.cs#L74-L84)
**章节来源**
- [EventBus.cs](file://GFramework.Core/events/EventBus.cs#L1-L55)
- [EasyEvents.cs](file://GFramework.Core/events/EasyEvents.cs#L1-L85)
### 注销管理组件分析
事件系统提供了多种注销管理策略:
```mermaid
classDiagram
class IUnRegister {
<>
+UnRegister() void
}
class DefaultUnRegister {
-_mOnUnRegister Action?
+UnRegister() void
}
class UnRegisterList {
-_unRegisterList IUnRegister[]
+Add(unRegister) void
+UnRegisterAll() void
+UnregisterList IList~IUnRegister~
}
class OrEvent {
-_mOnEvent Action?
+Or(event) OrEvent
+Register(onEvent) IUnRegister
+UnRegister(onEvent) void
+UnRegisterAll() void
}
IUnRegister <|-- DefaultUnRegister
IUnRegister <|.. UnRegisterList
IUnRegister <|.. OrEvent
```
**图表来源**
- [DefaultUnRegister.cs](file://GFramework.Core/events/DefaultUnRegister.cs#L9-L22)
- [UnRegisterList.cs](file://GFramework.Core/events/UnRegisterList.cs#L8-L37)
- [OrEvent.cs](file://GFramework.Core/events/OrEvent.cs#L9-L57)
**章节来源**
- [DefaultUnRegister.cs](file://GFramework.Core/events/DefaultUnRegister.cs#L1-L22)
- [UnRegisterList.cs](file://GFramework.Core/events/UnRegisterList.cs#L1-L37)
- [OrEvent.cs](file://GFramework.Core/events/OrEvent.cs#L1-L57)
## 依赖分析
事件系统各组件之间的依赖关系如下:
```mermaid
graph TB
subgraph "抽象接口层"
IEvent[IEvent接口]
IEventBus[IEventBus接口]
IUnRegister[IUnRegister接口]
end
subgraph "具体实现层"
EasyEvent[EasyEvent]
EventT[Event]
EventTTK[Event]
EventBus[EventBus]
EasyEvents[EasyEvents]
OrEvent[OrEvent]
DefaultUnRegister[DefaultUnRegister]
UnRegisterList[UnRegisterList]
end
subgraph "扩展工具层"
UnRegisterListExtension[UnRegisterListExtension]
end
IEvent --> EasyEvent
IEvent --> EventT
IEvent --> EventTTK
IEventBus --> EventBus
IUnRegister --> DefaultUnRegister
UnRegisterListExtension --> UnRegisterList
EventBus --> EasyEvents
EasyEvents --> EventT
EasyEvents --> EventTTK
OrEvent --> IUnRegister
```
**图表来源**
- [README.md](file://GFramework.Core/events/README.md#L1-L523)
**章节来源**
- [README.md](file://GFramework.Core/events/README.md#L1-L523)
## 性能考虑
事件系统在设计时充分考虑了性能优化:
### 内存优化策略
1. **空操作委托**:事件初始状态使用空操作委托,避免null检查开销
2. **委托链管理**:使用.NET内置的委托链机制,提供高效的事件分发
3. **类型安全**:通过泛型避免装箱拆箱操作
### 性能特性
- **O(1)** 注册/注销复杂度:委托链的添加和移除操作
- **O(n)** 触发复杂度:n为已注册处理器数量
- **零GC压力**:事件处理器作为委托,避免额外的对象分配
### 最佳实践建议
1. **避免频繁触发**:对于高频事件(如每帧触发),考虑使用批处理策略
2. **处理器轻量化**:事件处理器应保持简洁,避免复杂的计算逻辑
3. **及时注销**:在适当的生命周期结束时注销事件处理器
## 故障排除指南
### 常见问题及解决方案
#### 1. 事件处理器未被调用
**可能原因**:
- 事件处理器已被注销
- 事件实例未正确创建
- 注册时机不当
**解决方法**:
- 检查注销对象是否被意外调用
- 确认事件实例的生命周期
- 验证注册时机的正确性
#### 2. 内存泄漏问题
**可能原因**:
- 未及时注销事件处理器
- 长生命周期对象持有短生命周期事件
**解决方法**:
- 使用UnRegisterList统一管理注销
- 利用框架提供的生命周期管理工具
- 定期检查事件处理器的注册状态
#### 3. 事件循环问题
**可能原因**:
- 事件处理器中直接触发相同事件
- 事件处理逻辑相互依赖
**解决方法**:
- 避免在事件处理器中直接发送新事件
- 使用命令模式替代事件循环
- 实施事件过滤和条件处理
**章节来源**
- [README.md](file://GFramework.Core/events/README.md#L437-L523)
## 结论
EasyEvent事件机制为游戏开发提供了强大而灵活的组件间通信能力。通过精心设计的接口体系和优化的实现策略,该系统在保证类型安全的同时,提供了优秀的性能表现和易用性。
关键优势包括:
- **设计简洁**:接口设计直观,易于理解和使用
- **性能优秀**:采用委托链机制,提供高效的事件分发
- **类型安全**:泛型支持确保编译时类型检查
- **生命周期友好**:完善的注销管理机制
- **扩展性强**:支持事件组合和批量处理
在游戏开发中,该事件机制特别适用于:
- 游戏状态变化通知
- 跨模块通信
- 用户输入处理
- 游戏事件记录
- 系统间解耦通信
## 附录
### 使用示例
以下是一些典型的使用场景和代码示例:
#### 基础事件使用
```csharp
// 创建简单事件
var onClicked = new EasyEvent();
// 注册监听
var unregister = onClicked.Register(() =>
{
GD.Print("Button clicked!");
});
// 触发事件
onClicked.Trigger();
// 取消注册
unregister.UnRegister();
```
#### 泛型事件使用
```csharp
// 创建带参数的事件
var onScoreChanged = new Event();
// 注册监听
onScoreChanged.Register(newScore =>
{
GD.Print($"Score changed to: {newScore}");
});
// 触发事件并传递参数
onScoreChanged.Trigger(100);
```
#### 事件总线使用
```csharp
// 使用全局事件系统
var eventBus = new EventBus();
// 注册类型化事件
eventBus.Register(e =>
{
GD.Print($"Player died at position: {e.Position}");
});
// 发送事件(传递实例)
eventBus.Send(new PlayerDiedEvent
{
Position = new Vector3(10, 0, 5)
});
// 发送事件(自动创建实例)
eventBus.Send();
```
#### 批量事件管理
```csharp
var unregisterList = new UnRegisterList();
// 添加到列表
someEvent.Register(OnEvent).AddToUnregisterList(unregisterList);
// 批量注销
unregisterList.UnRegisterAll();
```
**章节来源**
- [README.md](file://GFramework.Core/events/README.md#L54-L523)