CheeseEngine
A 2D Game Engine
Loading...
Searching...
No Matches
EventBus.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <cstdint>
5#include <functional>
6#include <memory>
7#include <type_traits>
8#include <typeindex>
9#include <unordered_map>
10#include <vector>
11
15using HandlerId = uint32_t;
16
21public:
22 virtual ~IEventQueue() = default;
23
29 virtual void Dispatch() = 0;
30
36 virtual void RemoveHandler(HandlerId id) = 0;
37};
38
43template <typename T>
44class EventQueue : public IEventQueue {
45public:
46 std::vector<T> queue;
47 std::vector<std::pair<HandlerId, std::function<void(const T&)>>>
49
57 void Dispatch() override {
58 if (queue.empty())
59 return;
60
61 auto currentEvents = std::move(queue);
62 queue.clear();
63
64 for (const auto& event : currentEvents) {
65 for (const auto& handlerPair : handlers) {
66 handlerPair.second(event);
67 }
68 }
69 }
70
76 void RemoveHandler(HandlerId id) override {
77 // std::remove_if moves elements to be deleted to the end, then erase removes them
78 auto it = std::remove_if(handlers.begin(), handlers.end(),
79 [id](const auto& pair) { return pair.first == id; });
80
81 if (it != handlers.end()) {
82 handlers.erase(it, handlers.end());
83 }
84 }
85};
86
90class EventBus {
91private:
92 std::unordered_map<std::type_index, std::unique_ptr<IEventQueue>>
95
96public:
103 }
104
110 template <typename T>
111 void Publish(T&& event) {
112 using CleanType = std::decay_t<T>;
113 auto typeIdx = std::type_index(typeid(CleanType));
114
115 if (queues.find(typeIdx) == queues.end()) {
116 queues[typeIdx] = std::make_unique<EventQueue<CleanType>>();
117 }
118
119 auto* q = static_cast<EventQueue<CleanType>*>(queues[typeIdx].get());
120 q->queue.push_back(std::forward<T>(event));
121 }
122
128 template <typename T>
129 HandlerId Subscribe(std::function<void(const T&)> callback) {
130 using CleanType = std::decay_t<T>;
131 auto typeIdx = std::type_index(typeid(CleanType));
132
133 if (queues.find(typeIdx) == queues.end()) {
134 queues[typeIdx] = std::make_unique<EventQueue<CleanType>>();
135 }
136
137 auto* q = static_cast<EventQueue<CleanType>*>(queues[typeIdx].get());
138
139 HandlerId id = ++nextId;
140 q->handlers.push_back({id, callback});
141
142 return id;
143 }
144
153 for (auto& [type, q] : queues) {
154 q->RemoveHandler(id);
155 }
156 }
157
164 for (auto& [type, q] : queues) {
165 q->Dispatch();
166 }
167 }
168};
uint32_t HandlerId
A unique identifier for a registered callback.
Definition EventBus.hpp:15
Central event dispatcher connecting isolated engine systems.
Definition EventBus.hpp:90
void DispatchEvents()
Initiates sequential dispatch of all accumulated events across all queues.
Definition EventBus.hpp:163
std::unordered_map< std::type_index, std::unique_ptr< IEventQueue > > queues
Map of event types to their queues.
Definition EventBus.hpp:93
void Publish(T &&event)
Adds an event to the corresponding type queue for future dispatch.
Definition EventBus.hpp:111
HandlerId Subscribe(std::function< void(const T &)> callback)
Registers a new subscriber callback for a specific event type.
Definition EventBus.hpp:129
HandlerId nextId
Counter for generating unique handler IDs.
Definition EventBus.hpp:94
void Unsubscribe(HandlerId id)
Removes a handler from the event bus across all queues.
Definition EventBus.hpp:152
EventBus()
Initializes the EventBus and resets the handler ID counter.
Definition EventBus.hpp:102
Typed event queue for a specific event type T.
Definition EventBus.hpp:44
void Dispatch() override
Moves events to a local buffer, clears the original queue, and notifies subscribers.
Definition EventBus.hpp:57
std::vector< T > queue
Accumulated events for the current frame.
Definition EventBus.hpp:46
void RemoveHandler(HandlerId id) override
Erases a callback from the handlers list if the ID matches.
Definition EventBus.hpp:76
std::vector< std::pair< HandlerId, std::function< void(const T &)> > > handlers
Registered callbacks paired with their IDs.
Definition EventBus.hpp:48
Abstract event queue interface for type erasure.
Definition EventBus.hpp:20
virtual void Dispatch()=0
Calls all subscribers and clears the current queue.
virtual ~IEventQueue()=default
virtual void RemoveHandler(HandlerId id)=0
Removes a handler by its unique ID.