Skip to content

Commit 4962809

Browse files
committed
i forgot what i even did honestly
1 parent d85211a commit 4962809

File tree

1 file changed

+126
-76
lines changed

1 file changed

+126
-76
lines changed

loader/include/Geode/loader/EventV3.hpp

Lines changed: 126 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <atomic>
99
#include <algorithm>
1010
#include <tuple>
11+
#include <optional>
1112

1213
namespace geode::event::v3 {
1314
template <typename T>
@@ -20,88 +21,110 @@ namespace geode::event::v3 {
2021
{ a == b } -> std::convertible_to<bool>;
2122
};
2223

23-
template <class PoolType>
24-
class Pool : protected PoolType {
25-
public:
26-
using EventType = typename PoolType::EventType;
27-
using CallbackType = typename PoolType::CallbackType;
28-
24+
class Pool {
2925
private:
3026
std::mutex mutex;
3127
std::atomic_size_t recurse;
32-
std::vector<std::pair<EventType*, CallbackType>> toAdd;
33-
std::vector<std::pair<EventType*, EventType*>> toMove;
34-
std::vector<EventType*> toRemove;
28+
std::vector<std::pair<void*, void*>> toAdd;
29+
std::vector<std::pair<void*, void*>> toMove;
30+
std::vector<void*> toRemove;
3531

3632
void catchup() {
3733
std::lock_guard lock(mutex);
3834
for (auto& ev : toRemove) {
39-
this->PoolType::removeListener(ev);
35+
this->removeListener(ev);
4036
}
4137
for (auto& [ev, cb] : toAdd) {
42-
this->PoolType::addListener(ev, std::move(cb));
38+
this->addListener(ev, std::move(cb));
4339
}
4440
for (auto& [from, to] : toMove) {
45-
this->PoolType::moveListener(from, to);
41+
this->moveListener(from, to);
4642
}
4743
toRemove.clear();
4844
toAdd.clear();
4945
toMove.clear();
5046
}
5147

48+
protected:
49+
virtual ~Pool() = default;
50+
virtual void callListener(void* event, void* params) = 0;
51+
virtual void addListener(void* event, void* callable) = 0;
52+
virtual void removeListener(void* event) = 0;
53+
virtual void moveListener(void* from, void* to) = 0;
54+
5255
public:
5356
template <class... Args>
54-
void callListeners(EventType* event, Args&&... args) {
57+
void callListeners(void* event, void* params) {
5558
recurse++;
56-
auto listeners = this->getListeners(event);
57-
for (const auto& listener : listeners) {
58-
listener(std::forward<Args>(args)...);
59-
}
59+
this->callListener(event, params);
6060
recurse--;
6161

6262
if (recurse == 0) {
6363
this->catchup();
6464
}
6565
}
6666

67-
void addListener(EventType* event, CallbackType callback) {
67+
void addListenerSafe(void* event, void* callable) {
6868
std::lock_guard lock(mutex);
69-
if (recurse == 0) {
70-
this->PoolType::addListener(event, std::move(callback));
71-
} else {
72-
toAdd.emplace_back(event, std::move(callback));
69+
if (recurse >= 0) {
70+
toAdd.emplace_back(event, callable);
71+
}
72+
else {
73+
this->addListener(event, callable);
7374
}
7475
}
7576

76-
void removeListener(EventType* event) {
77+
void removeListenerSafe(void* event) {
7778
std::lock_guard lock(mutex);
78-
if (recurse == 0) {
79-
this->PoolType::removeListener(event);
80-
} else {
79+
if (recurse >= 0) {
8180
toRemove.emplace_back(event);
8281
}
82+
else {
83+
this->removeListener(event);
84+
}
8385
}
8486

85-
void moveListener(EventType* from, EventType* to) {
87+
void moveListenerSafe(void* from, void* to) {
8688
std::lock_guard lock(mutex);
87-
if (recurse == 0) {
88-
this->PoolType::moveListener(from, to);
89-
} else {
89+
if (recurse >= 0) {
9090
toMove.emplace_back(from, to);
9191
}
92+
else {
93+
this->moveListener(from, to);
94+
}
95+
}
96+
};
97+
98+
template <class... Args>
99+
class ForwardHelper {
100+
protected:
101+
using CallbackType = std::function<void(Args...)>;
102+
using ForwardTupleType = std::tuple<Args&&...>;
103+
104+
void call(void* c, void* t) {
105+
auto callback = static_cast<CallbackType*>(c);
106+
auto tuple = static_cast<ForwardTupleType*>(t);
107+
std::apply(*callback, *tuple);
108+
}
109+
110+
public:
111+
auto forward(Args&&... args) {
112+
return ForwardTupleType(std::forward<Args>(args)...);
113+
}
114+
115+
auto callback(std::invocable auto callable) {
116+
return CallbackType(callable);
92117
}
93118
};
94119

95-
template <class E, class C>
96-
class HashablePool {
120+
template <class E, class... Args>
121+
class HashablePool : public Pool, public ForwardHelper<Args...> {
97122
protected:
98123
using EventType = E;
99-
using CallbackType = std::function<C>;
100124

101125
private:
102126
std::unordered_multimap<std::size_t, CallbackType> listeners;
103127

104-
protected:
105128
auto getListeners(EventType* event) const {
106129
auto const hash = std::hash<EventType>{}(*event);
107130
auto [begin, end] = listeners.equal_range(hash);
@@ -111,29 +134,42 @@ namespace geode::event::v3 {
111134
return std::ranges::subrange(begin, end) | std::views::transform(getSecond);
112135
}
113136

114-
void addListener(EventType* event, CallbackType callback) {
137+
protected:
138+
void callListener(void* e, void* p) override {
139+
auto event = static_cast<EventType*>(e);
140+
141+
auto listeners = this->getListeners(event);
142+
for (auto const& listener : listeners) {
143+
this->call(&listener, p);
144+
}
145+
}
146+
147+
void addListener(void* e, void* c) override {
148+
auto event = static_cast<EventType*>(e);
149+
auto callback = static_cast<CallbackType*>(c);
150+
115151
auto const hash = std::hash<EventType>{}(*event);
116-
listeners.emplace(hash, std::move(callback));
152+
listeners.emplace(hash, std::move(*callback));
117153
}
118154

119-
void removeListener(EventType* event) {
155+
void removeListener(void* e) override {
156+
auto event = static_cast<EventType*>(e);
157+
120158
auto const hash = std::hash<EventType>{}(*event);
121159
listeners.erase(hash);
122160
}
123161

124-
void moveListener(EventType* from, EventType* to) {}
162+
void moveListener(void* from, void* to) override {}
125163
};
126164

127-
template <class E, class C>
128-
class EqualityComparablePool {
165+
template <class E, class... Args>
166+
class EqualityComparablePool : public Pool, public ForwardHelper<Args...> {
129167
protected:
130168
using EventType = E;
131-
using CallbackType = std::function<C>;
132169

133170
private:
134171
std::vector<std::pair<EventType*, CallbackType>> listeners;
135172

136-
protected:
137173
auto getListeners(EventType* event) const {
138174
auto isEvent = [event](auto const& pair) {
139175
return pair.first->operator==(*event);
@@ -144,17 +180,35 @@ namespace geode::event::v3 {
144180
return std::ranges::filter_view(listeners, isEvent) | std::views::transform(getSecond);
145181
}
146182

147-
void addListener(EventType* event, CallbackType callback) {
148-
listeners.emplace_back(event, std::move(callback));
183+
protected:
184+
void callListener(void* e, void* p) override {
185+
auto event = static_cast<EventType*>(e);
186+
187+
auto listeners = this->getListeners(event);
188+
for (auto const& listener : listeners) {
189+
this->call(&listener, p);
190+
}
191+
}
192+
193+
void addListener(void* e, void* c) override {
194+
auto event = static_cast<EventType*>(e);
195+
auto callback = static_cast<CallbackType*>(c);
196+
197+
listeners.emplace_back(event, std::move(*callback));
149198
}
150199

151-
void removeListener(EventType* event) {
200+
void removeListener(void* e) override {
201+
auto event = static_cast<EventType*>(e);
202+
152203
std::erase_if(listeners, [&event](auto const& pair) {
153204
return pair.first == event;
154205
});
155206
}
156207

157-
void moveListener(EventType* from, EventType* to) {
208+
void moveListener(void* f, void* t) override {
209+
auto from = static_cast<EventType*>(f);
210+
auto to = static_cast<EventType*>(t);
211+
158212
std::ranges::for_each(listeners, [&](auto& pair) {
159213
if (pair.first == from) {
160214
pair.first = to;
@@ -163,39 +217,14 @@ namespace geode::event::v3 {
163217
}
164218
};
165219

166-
template <class PoolType>
167220
class Event {
168221
public:
169-
using CallbackType = typename PoolType::CallbackType;
170-
using EventType = typename PoolType::EventType;
171-
172-
protected:
173-
static inline PoolType pool;
174-
175-
EventType* self() {
176-
return static_cast<EventType*>(this);
177-
}
222+
virtual Pool* getPool() = 0;
178223

179224
private:
180225
bool moved;
181226

182227
public:
183-
template <class... Args>
184-
void post(Args&&... args) {
185-
pool.callListeners(self(), std::forward<Args>(args)...);
186-
}
187-
188-
EventType listen(CallbackType callback) && {
189-
moved = false;
190-
pool.addListener(self(), std::move(callback));
191-
return std::move(*self());
192-
}
193-
194-
EventType& listen(CallbackType callback) & {
195-
moved = false;
196-
pool.addListener(self(), std::move(callback));
197-
return *self();
198-
}
199228

200229
Event() : moved(true) {}
201230
Event(Event const&) = delete;
@@ -219,22 +248,43 @@ namespace geode::event::v3 {
219248
using namespace geode::event::v3;
220249
}
221250

222-
class TestEvent : public Event<Pool<EqualityComparablePool<TestEvent, void(std::string_view)>>> {
251+
class TestEvent : public Event {
252+
private:
253+
static inline EqualityComparablePool<TestEvent, std::string_view> s_pool;
254+
223255
public:
224256
std::optional<size_t> key;
225257

226258
TestEvent() : key() {}
227259
TestEvent(size_t key) : key(key) {}
228260

261+
template <class... Args>
262+
void post(Args&&... args) {
263+
pool.callListeners(self(), std::forward<Args>(args)...);
264+
}
265+
266+
TestEvent listen(std::invocable auto callback) && {
267+
moved = false;
268+
pool.addListener(self(), std::move(callback));
269+
return std::move(*this);
270+
}
271+
272+
TestEvent& listen(CallbackType callback) & {
273+
moved = false;
274+
pool.addListener(self(), std::move(callback));
275+
return *this;
276+
}
277+
229278
bool operator==(TestEvent const& other) {
230279
if (!key) {
231280
return true;
232281
}
233-
if (!other.key) {
234-
return false;
235-
}
236282
return *key == *other.key;
237283
}
284+
285+
Pool* getPool() override {
286+
return &s_pool;
287+
}
238288
};
239289
}
240290

0 commit comments

Comments
 (0)