You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add event listening lifecycle hooks to EventEmitter
Introduces StartEventListening() and StopEventListening() virtual hooks to EventEmitter, called automatically when the first listener is added and the last is removed. This enables lazy initialization and cleanup of platform-specific event monitoring, improving resource efficiency and simplifying management for subclasses.
Managers can efficiently manage platform-specific event monitoring by overriding `StartEventListening()` and `StopEventListening()` hooks. These hooks are automatically called when the first listener is added and when the last listener is removed, respectively.
157
+
158
+
#### Purpose
159
+
160
+
This pattern allows managers to:
161
+
- **Lazy initialization** - Only start platform event monitoring when needed
162
+
- **Resource efficiency** - Stop monitoring when no listeners exist
163
+
- **Automatic management** - No manual tracking of listener count required
164
+
165
+
#### Implementation Pattern
166
+
167
+
```cpp
168
+
// tray_icon.h
169
+
class TrayIcon : public EventEmitter<TrayIconEvent>, public NativeObjectProvider {
170
+
public:
171
+
TrayIcon();
172
+
virtual ~TrayIcon();
173
+
174
+
// ... public API ...
175
+
176
+
protected:
177
+
// Override these to control platform event monitoring
// Add more listeners - StartEventListening() NOT called again
281
+
auto right_click_id = tray_icon->AddListener<TrayIconRightClickedEvent>(
282
+
[](const TrayIconRightClickedEvent& event) {
283
+
std::cout << "Tray icon right clicked" << std::endl;
284
+
}
285
+
);
286
+
287
+
// Remove one listener - StopEventListening() NOT called (still have listeners)
288
+
tray_icon->RemoveListener(right_click_id);
289
+
290
+
// Remove last listener - triggers StopEventListening()
291
+
tray_icon->RemoveListener(listener_id);
292
+
293
+
// Platform event monitoring is now STOPPED
294
+
// (saves system resources again)
295
+
```
296
+
297
+
#### Important Considerations
298
+
299
+
1. **Mutex Held**: `StartEventListening()` and `StopEventListening()` are called while holding `listeners_mutex_`. Keep the implementation fast and avoid acquiring other locks that could cause deadlocks.
300
+
301
+
2. **Default Implementation**: The default implementations are empty, so existing subclasses don't need to change unless they want to use this feature.
302
+
303
+
3. **Transitional Calls**: These methods are only called on transitions (0 → 1+ listeners and 1+ → 0 listeners), not on every add/remove operation.
304
+
305
+
4. **Destructor Cleanup**: If the emitter is destroyed while listeners exist, `StopEventListening()` is NOT called. Clean up resources in the destructor if needed.
306
+
307
+
5. **Idempotent Operations**: Implement setup/cleanup methods to be safe to call multiple times without side effects.
0 commit comments