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
Copy file name to clipboardExpand all lines: tutorials/migrate-v5.md
+117Lines changed: 117 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,11 +9,128 @@ set(CMAKE_CXX_STANDARD 20)
9
9
10
10
to say `23` instead of `20`.
11
11
12
+
## Changes to `Event`
13
+
14
+
The entire event system has been reworked. There are now multiple event classes for different purposes, and filters are far more performant, though a lot less dynamic. \
15
+
Events now also have priority ordering, for defining the order in which listeners are handled.
16
+
17
+
### Usage migration
18
+
19
+
```cpp
20
+
// BEFORE:
21
+
// # Sending an event
22
+
PlayerHealthEvent("joe123", 65).post();
23
+
24
+
// # Listening to an event
25
+
// leaking the EventListener
26
+
new EventListener<EventFilter<PlayerHealthEvent>>(+[](PlayerHealthEvent* ev) {
27
+
if (ev->getName() == "alice_") {
28
+
log::info("Alice's health is now {}", ev->getHealth());
29
+
}
30
+
return ListenerResult::Propagate;
31
+
});
32
+
```
33
+
34
+
```cpp
35
+
// AFTER:
36
+
// # Sending an event
37
+
PlayerHealthEvent("joe123").send(65);
38
+
39
+
// # Listening to an event
40
+
// listener is a geode::comm::ListenerHandle
41
+
auto listener = PlayerHealthEvent("alice_").listen([](int health) {
42
+
log::info("Alice's health is now {}", health);
43
+
return ListenerResult::Propagate;
44
+
// return false; would also be equivalent
45
+
});
46
+
// destroying the listener will prevent our callback from being called,
// if the lambda returns void then its treated the same as propagate
53
+
}, Priority::VeryEarly);
54
+
```
55
+
56
+
### Migration for Event subclasses
57
+
58
+
```cpp
59
+
// BEFORE:
60
+
classPlayerHealthEvent : publicEvent {
61
+
public:
62
+
PlayerHealthEvent(std::string name, int health);
63
+
64
+
std::string m_name;
65
+
int m_health;
66
+
};
67
+
```
68
+
69
+
```cpp
70
+
// AFTER: the std::string is a filter argument for the player's name
71
+
class PlayerHealthEvent : public Event<PlayerHealthEvent, bool(int health), std::string> {
72
+
public:
73
+
using Event::Event;
74
+
};
75
+
```
76
+
77
+
### Migration for `DispatchEvent`
78
+
79
+
Renamed to `geode::Dispatch`, but `DispatchEvent` is kept as an alias for easier migration. Its a thread-safe event with one filter arg for the id:
80
+
81
+
```cpp
82
+
template <class... Args>
83
+
class Dispatch : public ThreadSafeEvent<Dispatch<Args...>, bool(Args...), std::string> {
84
+
// [...]
85
+
};
86
+
87
+
template<class... Args>
88
+
using DispatchEvent = Dispatch<Args...>;
89
+
```
90
+
91
+
Usage is the same as a regular event usage
92
+
93
+
### Thread safety
94
+
95
+
Thread safety is now opt-in for events, meaning that if you want to send/listen to an event from different threads you should use the `ThreadSafe` variants.
96
+
97
+
```
98
+
Event -> ThreadSafeEvent
99
+
GlobalEvent -> ThreadSafeGlobalEvent
100
+
```
101
+
102
+
Note that this has nothing to do with GD's main thread, event listeners will always get triggered on the same thread that sent the event.
103
+
104
+
### `GlobalEvent`
105
+
106
+
If you have an Event with a filter, it's not possible to have a listener for any filter args. In those cases, you should use `GlobalEvent`.
`geode::Popup` is no longer templated, and instead accepts its own arguments in `Popup::init` (which also replaces `initAnchored`). It now uses the pattern similar to any other node. For example the following code:
0 commit comments