Skip to content

Commit ecd6c36

Browse files
committed
Add EventEmitter base class and refactor event handling
- Introduce EventEmitter base class for unified event management - Refactor DisplayManager, WindowManager, and KeyboardMonitor to inherit EventEmitter - Remove redundant event dispatcher code from managers - Update macOS platform code to use EventEmitter methods - Add EventEmitter documentation and example usage
1 parent a3d9102 commit ecd6c36

File tree

10 files changed

+660
-115
lines changed

10 files changed

+660
-115
lines changed

docs/EventEmitter.md

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
# EventEmitter 使用指南
2+
3+
## 概述
4+
5+
`EventEmitter` 是一个基类,继承它即可为您的类提供完整的事件发射和监听功能。它基于观察者模式实现,支持类型安全的事件处理、同步和异步事件分发。
6+
7+
## 基本用法
8+
9+
### 1. 定义事件类
10+
11+
首先,您需要定义事件类。有几种方式:
12+
13+
#### 方式一:手动定义(推荐)
14+
```cpp
15+
class MyEvent : public TypedEvent<MyEvent> {
16+
public:
17+
std::string message;
18+
int value;
19+
20+
MyEvent(std::string msg, int val)
21+
: message(std::move(msg)), value(val) {}
22+
};
23+
```
24+
25+
#### 方式二:使用宏定义
26+
```cpp
27+
DEFINE_EVENT_BEGIN(MyEvent)
28+
std::string message;
29+
int value;
30+
31+
MyEvent(std::string msg, int val)
32+
: message(std::move(msg)), value(val) {}
33+
DEFINE_EVENT_END()
34+
```
35+
36+
#### 方式三:简单事件(仅数据成员)
37+
```cpp
38+
SIMPLE_EVENT(StatusEvent,
39+
bool success;
40+
std::string error_message;
41+
)
42+
```
43+
44+
### 2. 创建继承 EventEmitter 的类
45+
46+
```cpp
47+
class MyClass : public EventEmitter {
48+
public:
49+
void DoSomething() {
50+
// 触发同步事件
51+
EmitSync<MyEvent>("Hello", 42);
52+
53+
// 触发异步事件
54+
EmitAsync<MyEvent>("Async Hello", 100);
55+
}
56+
57+
void DoSomethingElse(const std::string& msg, int val) {
58+
// 直接传递参数构造事件
59+
EmitSync<MyEvent>(msg, val);
60+
}
61+
};
62+
```
63+
64+
### 3. 添加事件监听器
65+
66+
#### Lambda 函数监听器(推荐)
67+
```cpp
68+
MyClass obj;
69+
70+
size_t listener_id = obj.AddListener<MyEvent>([](const MyEvent& event) {
71+
std::cout << "收到事件: " << event.message << ", 值: " << event.value << std::endl;
72+
});
73+
```
74+
75+
#### 类型化监听器
76+
```cpp
77+
class MyListener : public TypedEventListener<MyEvent> {
78+
public:
79+
void OnTypedEvent(const MyEvent& event) override {
80+
std::cout << "监听器收到: " << event.message << std::endl;
81+
}
82+
};
83+
84+
MyListener listener;
85+
size_t id = obj.AddListener<MyEvent>(&listener);
86+
```
87+
88+
### 4. 管理监听器
89+
90+
```cpp
91+
// 移除特定监听器
92+
obj.RemoveListener(listener_id);
93+
94+
// 移除某种事件类型的所有监听器
95+
obj.RemoveAllListeners<MyEvent>();
96+
97+
// 移除所有监听器
98+
obj.RemoveAllListeners();
99+
100+
// 检查监听器数量
101+
size_t count = obj.GetListenerCount<MyEvent>();
102+
size_t total = obj.GetTotalListenerCount();
103+
104+
// 检查是否有监听器
105+
bool has_listeners = obj.HasListeners<MyEvent>();
106+
```
107+
108+
## API 参考
109+
110+
### EventEmitter 公共方法
111+
112+
#### 添加监听器
113+
- `size_t AddListener<EventType>(TypedEventListener<EventType>* listener)`
114+
- 添加类型化监听器
115+
- 返回监听器 ID
116+
117+
- `size_t AddListener<EventType>(std::function<void(const EventType&)> callback)`
118+
- 添加 Lambda 函数监听器
119+
- 返回监听器 ID
120+
121+
#### 移除监听器
122+
- `bool RemoveListener(size_t listener_id)`
123+
- 根据 ID 移除监听器
124+
- 返回是否成功
125+
126+
- `void RemoveAllListeners<EventType>()`
127+
- 移除指定类型的所有监听器
128+
129+
- `void RemoveAllListeners()`
130+
- 移除所有监听器
131+
132+
#### 查询方法
133+
- `size_t GetListenerCount<EventType>() const`
134+
- 获取指定事件类型的监听器数量
135+
136+
- `size_t GetTotalListenerCount() const`
137+
- 获取总监听器数量
138+
139+
- `bool HasListeners<EventType>() const`
140+
- 检查是否有指定类型的监听器
141+
142+
### EventEmitter 受保护方法(用于子类)
143+
144+
#### 发射事件
145+
- `void EmitSync(const Event& event)`
146+
- 同步发射事件对象
147+
148+
- `void EmitSync<EventType>(Args&&... args)`
149+
- 同步发射事件(完美转发参数)
150+
151+
- `void EmitAsync(std::unique_ptr<Event> event)`
152+
- 异步发射事件对象
153+
154+
- `void EmitAsync<EventType>(Args&&... args)`
155+
- 异步发射事件(完美转发参数)
156+
157+
## 完整示例
158+
159+
```cpp
160+
#include "event_emitter.h"
161+
#include <iostream>
162+
163+
// 定义事件
164+
class ButtonClickEvent : public TypedEvent<ButtonClickEvent> {
165+
public:
166+
std::string button_name;
167+
int x, y;
168+
169+
ButtonClickEvent(std::string name, int x_pos, int y_pos)
170+
: button_name(std::move(name)), x(x_pos), y(y_pos) {}
171+
};
172+
173+
// 继承 EventEmitter 的类
174+
class Button : public EventEmitter {
175+
public:
176+
Button(std::string name) : name_(std::move(name)) {}
177+
178+
void Click(int x, int y) {
179+
std::cout << "按钮 '" << name_ << "' 被点击" << std::endl;
180+
EmitSync<ButtonClickEvent>(name_, x, y);
181+
}
182+
183+
private:
184+
std::string name_;
185+
};
186+
187+
int main() {
188+
Button button("确定");
189+
190+
// 添加监听器
191+
size_t id = button.AddListener<ButtonClickEvent>([](const ButtonClickEvent& event) {
192+
std::cout << "监听到点击: " << event.button_name
193+
<< " 位置(" << event.x << ", " << event.y << ")" << std::endl;
194+
});
195+
196+
// 触发事件
197+
button.Click(100, 200);
198+
199+
// 清理
200+
button.RemoveListener(id);
201+
202+
return 0;
203+
}
204+
```
205+
206+
## 最佳实践
207+
208+
1. **使用 Lambda 函数监听器**:对于简单的事件处理逻辑,Lambda 函数更加简洁。
209+
210+
2. **管理监听器生命周期**:确保在对象销毁前移除监听器,避免悬空指针。
211+
212+
3. **异常处理**:EventEmitter 会捕获监听器中的异常,但不会传播。确保您的监听器代码健壮。
213+
214+
4. **同步 vs 异步**:
215+
- 使用 `EmitSync` 进行即时处理
216+
- 使用 `EmitAsync` 避免阻塞当前线程
217+
218+
5. **事件设计**:保持事件类简单,只包含必要的数据。
219+
220+
6. **性能考虑**:大量监听器可能影响性能,考虑按需添加/移除。
221+
222+
## 线程安全
223+
224+
EventEmitter 是线程安全的,可以在多线程环境中安全使用。异步事件会在后台线程中处理,而同步事件在当前线程中立即处理。

0 commit comments

Comments
 (0)