Minecraft Community Edition 0.1.0
Loading...
Searching...
No Matches
QEventBus.hpp
Go to the documentation of this file.
1#pragma once
2#include <EASTL/functional.h>
3#include <EASTL/unordered_map.h>
4#include <EASTL/vector.h>
5#include <EASTL/queue.h>
6#include <EASTL/unique_ptr.h>
7#include <typeindex>
8#include <mutex>
9#include "IEvent.hpp"
10
15
16namespace mce {
17
33 eastl::function<void()> unsubscribe;
34
41 };
42
58 class QEventBus {
59 public:
60 QEventBus(const std::string_view& eventNamespace);
61
68 template<typename EventType>
69 using Handler = eastl::function<void(const EventType&)>;
70
81 template<typename EventType>
83
93 template<typename EventType>
94 void subscribe(Handler<EventType> handler);
95
105 template<typename EventType>
106 void post(EventType&& event);
107
114 void process();
115
122 void runAsync();
123
131 void stop();
132
133 size_t getQueueSize() const;
140 ~QEventBus();
141
142 const std::string_view& getNamespace() const;
143 private:
152 void dispatch(const IEvent& e);
153
154
155 struct TypeIndexHash {
156 size_t operator()(const std::type_index& t) const noexcept {
157 return t.hash_code();
158 }
159 };
160
161 struct TypeIndexEqual {
162 bool operator()(const std::type_index& a, const std::type_index& b) const noexcept {
163 return a == b;
164 }
165 };
174 eastl::unordered_map<
175 std::type_index,
176 eastl::vector<eastl::function<void(const IEvent&)>>,
177 TypeIndexHash,
178 TypeIndexEqual
179 > handlers;
187 eastl::queue<eastl::unique_ptr<IEvent>> queue;
188
192 std::mutex mutex;
193
197 std::mutex queueMutex;
198
202 std::condition_variable conditionalVariable;
203
207 std::atomic_bool bIsRunning = false;
208
212 std::thread thread;
213
214 const std::string_view eventNamespace;
215 };
216 template<typename EventType>
218 std::lock_guard<std::mutex> lock(QEventBus::mutex);
219
220 auto& handlers = QEventBus::handlers[typeid(EventType)];
221
222 handlers.emplace_back([handler](const IEvent& e) {
223 handler(static_cast<const EventType&>(e));
224 });
225
226 auto it = eastl::prev(handlers.end());
227 std::type_index typeIdx = std::type_index(typeid(EventType));
228
229 return SubscriptionToken{ [this, typeIdx, it]() {
230 std::lock_guard<std::mutex> lock(QEventBus::mutex);
231 auto mapIt = QEventBus::handlers.find(typeIdx);
232 if (mapIt != QEventBus::handlers.end()) {
233 auto& vec = mapIt->second;
234
235 vec.erase(it);
236
237 if (vec.empty()) {
238 QEventBus::handlers.erase(mapIt);
239 }
240 }
241 }
242 };
243 }
244
245 template<typename EventType>
247 std::lock_guard<std::mutex> lock(QEventBus::mutex);
248
249 // Simply store the handler � no token or RAII logic.
250 auto& handlers = QEventBus::handlers[typeid(EventType)];
251 handlers.emplace_back([handler](const IEvent& e) {
252 handler(static_cast<const EventType&>(e));
253 });
254 }
255
256 template<typename EventType>
257 inline void QEventBus::post(EventType&& event) {
258 // Create an owned copy / move of the event on the heap
259 using Decayed = std::decay_t<EventType>;
260 auto ptr = eastl::make_unique<Decayed>(eastl::forward<EventType>(event));
261 {
262 std::lock_guard<std::mutex> lock(QEventBus::queueMutex);
263 QEventBus::queue.push(eastl::move(ptr));
264 }
265 QEventBus::conditionalVariable.notify_one();
266 }
267}
~QEventBus()
Destructor.
Definition QEventBus.cpp:47
void stop()
Stop asynchronous processing and join the worker thread.
Definition QEventBus.cpp:37
void post(EventType &&event)
Post an event instance to the bus for later processing.
Definition QEventBus.hpp:257
void runAsync()
Start asynchronous processing of queued events.
Definition QEventBus.cpp:18
void process()
Process and dispatch all currently queued events.
Definition QEventBus.cpp:5
eastl::function< void(const EventType &)> Handler
Alias for an event handler function.
Definition QEventBus.hpp:69
SubscriptionToken subscribeRAII(Handler< EventType > handler)
Subscribe a handler to EventType and receive a RAII token.
Definition QEventBus.hpp:217
void subscribe(Handler< EventType > handler)
Subscribe a handler to EventType without RAII token.
Definition QEventBus.hpp:246
Definition IEvent.hpp:14
Token object that controls the lifetime of an event subscription.
Definition QEventBus.hpp:27
eastl::function< void()> unsubscribe
Callable invoked to perform the unsubscribe action.
Definition QEventBus.hpp:33
~SubscriptionToken()
Destructor.
Definition QEventBus.hpp:40