aboutsummaryrefslogtreecommitdiff
path: root/src/crepe/api/EventManager.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/crepe/api/EventManager.h')
-rw-r--r--src/crepe/api/EventManager.h274
1 files changed, 161 insertions, 113 deletions
diff --git a/src/crepe/api/EventManager.h b/src/crepe/api/EventManager.h
index b963ce3..26539ce 100644
--- a/src/crepe/api/EventManager.h
+++ b/src/crepe/api/EventManager.h
@@ -1,11 +1,11 @@
#pragma once
+#include <functional>
#include <memory>
+#include <type_traits>
+#include <typeindex>
#include <unordered_map>
#include <vector>
-#include <functional>
-#include <typeindex>
-#include <type_traits>
#include "Event.h"
#include "EventHandler.h"
@@ -17,26 +17,26 @@
*/
class EventManager {
public:
- /**
+ /**
* \brief Deleted copy constructor to prevent copying of the EventManager instance.
*/
- EventManager(const EventManager &) = delete;
+ EventManager(const EventManager &) = delete;
- /**
+ /**
* \brief Deleted copy assignment operator to prevent assignment of the EventManager instance.
*/
- const EventManager & operator=(const EventManager &) = delete;
+ const EventManager & operator=(const EventManager &) = delete;
- /**
+ /**
* \brief Get the singleton instance of the EventManager.
*
* This method returns the unique instance of the EventManager, creating it on the first call.
*
* \return Reference to the EventManager instance.
*/
- static EventManager & get_instance();
+ static EventManager & get_instance();
- /**
+ /**
* \brief Subscribe to an event.
*
* This method allows the registration of a callback for a specific event type and channel.
@@ -45,10 +45,10 @@ public:
* \param callback The callback function to invoke when the event is triggered.
* \param channel The channel number to subscribe to (default is 0).
*/
- template <typename EventType>
- void subscribe(EventHandler<EventType> && callback, int channel = 0);
+ template <typename EventType>
+ void subscribe(EventHandler<EventType> && callback, int channel = 0);
- /**
+ /**
* \brief Unsubscribe from an event.
*
* This method removes a previously registered callback from an event.
@@ -57,10 +57,10 @@ public:
* \param callback The callback function to remove from the subscription list.
* \param channel The event ID to unsubscribe from.
*/
- template <typename EventType>
- void unsubscribe(const EventHandler<EventType> &, int channel);
+ template <typename EventType>
+ void unsubscribe(const EventHandler<EventType> &, int channel);
- /**
+ /**
* \brief Trigger an event.
*
* This method invokes the appropriate callback(s) for the specified event.
@@ -69,10 +69,10 @@ public:
* \param event The event data to pass to the callback.
* \param channel The channel from which to trigger the event (default is 0).
*/
- template <typename EventType>
- void trigger_event(const EventType & event, int channel);
+ template <typename EventType>
+ void trigger_event(const EventType & event, int channel);
- /**
+ /**
* \brief Queue an event for later processing.
*
* This method adds an event to the event queue, which will be processed in the
@@ -82,128 +82,176 @@ public:
* \param event The event to queue.
* \param channel The channel number for the event (default is 0).
*/
- template <typename EventType>
- void queue_event(EventType&& event, int channel);
+ template <typename EventType>
+ void queue_event(EventType && event, int channel);
- /**
+ /**
* \brief Dispatch all queued events.
*
* This method processes all events in the event queue and triggers the corresponding
* callbacks for each event.
*/
- void dispatch_events();
+ void dispatch_events();
private:
- /**
+ /**
* \brief Default constructor for the EventManager.
*
* This constructor is private to enforce the singleton pattern.
*/
- EventManager() = default;
+ EventManager() = default;
- //! The queue of events to be processed.
- std::vector<std::tuple<std::unique_ptr<Event>, int, std::type_index>> events_queue;
+ //! The queue of events to be processed.
+ std::vector<std::tuple<std::unique_ptr<Event>, int, std::type_index>>
+ events_queue;
//! Registered event handlers.
- std::unordered_map<std::type_index, std::vector<std::unique_ptr<IEventHandlerWrapper>>> subscribers;
+ std::unordered_map<std::type_index,
+ std::vector<std::unique_ptr<IEventHandlerWrapper>>>
+ subscribers;
//! Event handlers indexed by event ID.
- std::unordered_map<std::type_index, std::unordered_map<int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>> subscribers_by_event_id;
+ std::unordered_map<
+ std::type_index,
+ std::unordered_map<int,
+ std::vector<std::unique_ptr<IEventHandlerWrapper>>>>
+ subscribers_by_event_id;
};
-
template <typename EventType>
void EventManager::subscribe(EventHandler<EventType> && callback, int channel) {
- std::type_index event_type = typeid(EventType);
- std::unique_ptr<EventHandlerWrapper<EventType>> handler = std::make_unique<EventHandlerWrapper<EventType>>(callback);
-
- if (channel) {
- std::unordered_map<int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>& handlers_map = this->subscribers_by_event_id[event_type];
- std::unordered_map<int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator handlers = handlers_map.find(channel);
- if (handlers != handlers_map.end()) {
- handlers->second.emplace_back(std::move(handler));
- } else {
- handlers_map[channel].emplace_back(std::move(handler));
- }
- } else {
- std::vector<std::unique_ptr<IEventHandlerWrapper>>& handlers = this->subscribers[event_type];
- handlers.emplace_back(std::move(handler));
- }
+ std::type_index event_type = typeid(EventType);
+ std::unique_ptr<EventHandlerWrapper<EventType>> handler
+ = std::make_unique<EventHandlerWrapper<EventType>>(callback);
+
+ if (channel) {
+ std::unordered_map<int,
+ std::vector<std::unique_ptr<IEventHandlerWrapper>>> &
+ handlers_map
+ = this->subscribers_by_event_id[event_type];
+ std::unordered_map<
+ int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator
+ handlers
+ = handlers_map.find(channel);
+ if (handlers != handlers_map.end()) {
+ handlers->second.emplace_back(std::move(handler));
+ } else {
+ handlers_map[channel].emplace_back(std::move(handler));
+ }
+ } else {
+ std::vector<std::unique_ptr<IEventHandlerWrapper>> & handlers
+ = this->subscribers[event_type];
+ handlers.emplace_back(std::move(handler));
+ }
}
template <typename EventType>
-void EventManager::queue_event(EventType&& event, int channel) {
- std::type_index event_type = std::type_index(typeid(EventType));
-
- std::unique_ptr<EventType> event_ptr = std::make_unique<EventType>(std::forward<EventType>(event));
-
- std::tuple<std::unique_ptr<Event>, int, std::type_index> tuple(
- std::move(event_ptr),
- channel,
- event_type
- );
- this->events_queue.push_back(std::move(tuple));
+void EventManager::queue_event(EventType && event, int channel) {
+ std::type_index event_type = std::type_index(typeid(EventType));
+
+ std::unique_ptr<EventType> event_ptr
+ = std::make_unique<EventType>(std::forward<EventType>(event));
+
+ std::tuple<std::unique_ptr<Event>, int, std::type_index> tuple(
+ std::move(event_ptr), channel, event_type);
+ this->events_queue.push_back(std::move(tuple));
}
template <typename EventType>
void EventManager::trigger_event(const EventType & event, int channel) {
- std::type_index event_type = std::type_index(typeid(EventType));
-
- if (channel > 0) {
- std::unordered_map<int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>& handlers_map = this->subscribers_by_event_id[event_type];
- std::unordered_map<int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator handlers_it = handlers_map.find(channel);
-
- if (handlers_it != handlers_map.end()) {
- std::vector<std::unique_ptr<IEventHandlerWrapper>>& handlers = handlers_it->second;
- for (std::vector<std::unique_ptr<IEventHandlerWrapper>>::iterator it = handlers.begin(); it != handlers.end();) {
+ std::type_index event_type = std::type_index(typeid(EventType));
+
+ if (channel > 0) {
+ std::unordered_map<int,
+ std::vector<std::unique_ptr<IEventHandlerWrapper>>> &
+ handlers_map
+ = this->subscribers_by_event_id[event_type];
+ std::unordered_map<
+ int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator
+ handlers_it
+ = handlers_map.find(channel);
+
+ if (handlers_it != handlers_map.end()) {
+ std::vector<std::unique_ptr<IEventHandlerWrapper>> & handlers
+ = handlers_it->second;
+ for (std::vector<std::unique_ptr<IEventHandlerWrapper>>::iterator it
+ = handlers.begin();
+ it != handlers.end();) {
// erases callback if callback function returns true
- if ((*it)->exec(event)) {
- it = handlers.erase(it);
- } else {
- ++it;
- }
- }
- }
- } else {
- std::vector<std::unique_ptr<IEventHandlerWrapper>>& handlers = this->subscribers[event_type];
- for (std::vector<std::unique_ptr<IEventHandlerWrapper>>::iterator it = handlers.begin(); it != handlers.end();) {
+ if ((*it)->exec(event)) {
+ it = handlers.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
+ } else {
+ std::vector<std::unique_ptr<IEventHandlerWrapper>> & handlers
+ = this->subscribers[event_type];
+ for (std::vector<std::unique_ptr<IEventHandlerWrapper>>::iterator it
+ = handlers.begin();
+ it != handlers.end();) {
// erases callback if callback function returns true
- if ((*it)->exec(event)) {
- it = handlers.erase(it);
- } else {
- ++it;
- }
- }
- }
+ if ((*it)->exec(event)) {
+ it = handlers.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
}
template <typename EventType>
-void EventManager::unsubscribe(const EventHandler<EventType> & callback, int channel) {
- std::type_index event_type(typeid(EventType));
- std::string handler_name = callback.target_type().name();
-
- if (channel) {
- std::unordered_map<std::type_index, std::unordered_map<int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>>::iterator subscriber_list = this->subscribers_by_event_id.find(event_type);
- if (subscriber_list != this->subscribers_by_event_id.end()) {
- std::unordered_map<int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>& handlers_map = subscriber_list->second;
- std::unordered_map<int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator handlers = handlers_map.find(channel);
- if (handlers != handlers_map.end()) {
- std::vector<std::unique_ptr<IEventHandlerWrapper>>& callbacks = handlers->second;
- for (std::vector<std::unique_ptr<IEventHandlerWrapper>>::iterator it = callbacks.begin(); it != callbacks.end(); ++it) {
- if ((*it)->get_type() == handler_name) {
- it = callbacks.erase(it);
- return;
- }
- }
- }
- }
- } else {
- std::unordered_map<std::type_index, std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator handlers_it = this->subscribers.find(event_type);
- if (handlers_it != this->subscribers.end()) {
- std::vector<std::unique_ptr<IEventHandlerWrapper>>& handlers = handlers_it->second;
- for (std::vector<std::unique_ptr<IEventHandlerWrapper>>::iterator it = handlers.begin(); it != handlers.end(); ++it) {
- if ((*it)->get_type() == handler_name) {
- it = handlers.erase(it);
- return;
- }
- }
- }
- }
+void EventManager::unsubscribe(const EventHandler<EventType> & callback,
+ int channel) {
+ std::type_index event_type(typeid(EventType));
+ std::string handler_name = callback.target_type().name();
+
+ if (channel) {
+ std::unordered_map<
+ std::type_index,
+ std::unordered_map<
+ int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>>::
+ iterator subscriber_list
+ = this->subscribers_by_event_id.find(event_type);
+ if (subscriber_list != this->subscribers_by_event_id.end()) {
+ std::unordered_map<
+ int, std::vector<std::unique_ptr<IEventHandlerWrapper>>> &
+ handlers_map
+ = subscriber_list->second;
+ std::unordered_map<
+ int,
+ std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator
+ handlers
+ = handlers_map.find(channel);
+ if (handlers != handlers_map.end()) {
+ std::vector<std::unique_ptr<IEventHandlerWrapper>> & callbacks
+ = handlers->second;
+ for (std::vector<
+ std::unique_ptr<IEventHandlerWrapper>>::iterator it
+ = callbacks.begin();
+ it != callbacks.end(); ++it) {
+ if ((*it)->get_type() == handler_name) {
+ it = callbacks.erase(it);
+ return;
+ }
+ }
+ }
+ }
+ } else {
+ std::unordered_map<std::type_index,
+ std::vector<std::unique_ptr<IEventHandlerWrapper>>>::
+ iterator handlers_it
+ = this->subscribers.find(event_type);
+ if (handlers_it != this->subscribers.end()) {
+ std::vector<std::unique_ptr<IEventHandlerWrapper>> & handlers
+ = handlers_it->second;
+ for (std::vector<std::unique_ptr<IEventHandlerWrapper>>::iterator it
+ = handlers.begin();
+ it != handlers.end(); ++it) {
+ if ((*it)->get_type() == handler_name) {
+ it = handlers.erase(it);
+ return;
+ }
+ }
+ }
+ }
}
+