aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWBoerenkamps <wrj.boerenkamps@student.avans.nl>2024-11-12 15:08:37 +0100
committerWBoerenkamps <wrj.boerenkamps@student.avans.nl>2024-11-12 15:08:37 +0100
commit80e4e1eb78898879eed11648808ca6b65eecb304 (patch)
tree78d5d51ce36c32b235a4c061b5f51772fabdd8ea
parent48fb3f48831b1db187942592343eb4a2dc6662fc (diff)
removed auto from code
-rw-r--r--src/crepe/api/EventHandler.h80
-rw-r--r--src/crepe/api/EventManager.cpp21
-rw-r--r--src/crepe/api/EventManager.h162
-rw-r--r--src/crepe/api/IKeyListener.cpp20
-rw-r--r--src/crepe/api/IKeyListener.h8
-rw-r--r--src/makefile3
6 files changed, 240 insertions, 54 deletions
diff --git a/src/crepe/api/EventHandler.h b/src/crepe/api/EventHandler.h
index eea1c79..5b9ac0d 100644
--- a/src/crepe/api/EventHandler.h
+++ b/src/crepe/api/EventHandler.h
@@ -4,35 +4,109 @@
#include <typeindex>
#include "Event.h"
+/**
+ * \brief A type alias for an event handler function.
+ *
+ * The EventHandler is a std::function that takes an EventType reference and returns a boolean value
+ * indicating whether the event was successfully handled.
+ *
+ * \tparam EventType The type of event this handler will handle.
+ */
template <typename EventType>
using EventHandler = std::function<bool(const EventType & e)>;
+/**
+ * \class IEventHandlerWrapper
+ * \brief An abstract base class for event handler wrappers.
+ *
+ * This class provides the interface for handling events. Derived classes must implement the
+ * `call()` method to process events and the `get_type()` method to return the handler's type.
+ */
class IEventHandlerWrapper {
public:
+ /**
+ * \brief Virtual destructor for IEventHandlerWrapper.
+ */
virtual ~IEventHandlerWrapper() = default;
+ /**
+ * \brief Executes the handler with the given event.
+ *
+ * This method calls the `call()` method of the derived class, passing the event to the handler.
+ *
+ * \param e The event to be processed.
+ * \return A boolean value indicating whether the event is handled.
+ */
bool exec(const Event & e);
+ /**
+ * \brief Get the type of the event handler.
+ *
+ * This method returns the type of the event handler as a string.
+ *
+ * \return A string representing the handler's type.
+ */
virtual std::string get_type() const = 0;
private:
+ /**
+ * \brief The method responsible for handling the event.
+ *
+ * This method is implemented by derived classes to process the event.
+ *
+ * \param e The event to be processed.
+ * \return A boolean value indicating whether the event is handled.
+ */
virtual bool call(const Event & e) = 0;
};
+/**
+ * \class EventHandlerWrapper
+ * \brief A wrapper for event handler functions.
+ *
+ * This class wraps an event handler function of a specific event type. It implements the
+ * `call()` and `get_type()` methods to allow the handler to be executed and its type to be
+ * queried.
+ *
+ * \tparam EventType The type of event this handler will handle.
+ */
template <typename EventType>
class EventHandlerWrapper : public IEventHandlerWrapper {
public:
+ /**
+ * \brief Constructs an EventHandlerWrapper with a given handler.
+ *
+ * The constructor takes an event handler function and stores it in the wrapper.
+ *
+ * \param handler The event handler function.
+ */
explicit EventHandlerWrapper(const EventHandler<EventType> & handler)
: m_handler(handler), m_handler_type(m_handler.target_type().name()) {
}
private:
+ /**
+ * \brief Calls the stored event handler with the event.
+ *
+ * This method casts the event to the appropriate type and calls the handler.
+ *
+ * \param e The event to be handled.
+ * \return A boolean value indicating whether the event is handled.
+ */
bool call(const Event & e) override {
return m_handler(static_cast<const EventType &>(e));
}
+ /**
+ * \brief Returns the type of the handler.
+ *
+ * This method returns a string representing the type of the event handler.
+ *
+ * \return The handler type as a string.
+ */
std::string get_type() const override { return m_handler_type; }
-
- EventHandler<EventType> m_handler;
- const std::string m_handler_type;
+ //! The event handler function.
+ EventHandler<EventType> m_handler;
+ //! The type name of the handler function.
+ const std::string m_handler_type;
};
diff --git a/src/crepe/api/EventManager.cpp b/src/crepe/api/EventManager.cpp
index 869ec74..3d8558b 100644
--- a/src/crepe/api/EventManager.cpp
+++ b/src/crepe/api/EventManager.cpp
@@ -7,6 +7,9 @@ void EventManager::dispatch_events() {
auto& event = std::get<0>(*event_it);
int channel = std::get<1>(*event_it);
std::type_index event_type = std::get<2>(*event_it);
+
+ bool event_handled = false;
+
if (channel) {
auto handlers_it = subscribers_by_event_id.find(event_type);
if (handlers_it != subscribers_by_event_id.end()) {
@@ -15,25 +18,33 @@ void EventManager::dispatch_events() {
if (handlers != handlers_map.end()) {
auto& callbacks = handlers->second;
for (auto& handler : callbacks) {
- handler->exec(*event);
+ if (handler->exec(*event)) {
+ event_it = events_queue.erase(event_it);
+ event_handled = true;
+ break;
+ }
}
}
}
} else {
+ // Handle event for all channels
auto handlers_it = subscribers.find(event_type);
if (handlers_it != subscribers.end()) {
auto& handlers = handlers_it->second;
for (auto& handler : handlers) {
- handler->exec(*event);
+ if (handler->exec(*event)) {
+ event_it = events_queue.erase(event_it);
+ event_handled = true;
+ break;
+ }
}
}
}
- if (event->handled) {
- event_it = events_queue.erase(event_it);
- } else {
+ if (!event_handled) {
++event_it;
}
}
}
+
diff --git a/src/crepe/api/EventManager.h b/src/crepe/api/EventManager.h
index be9a947..9b69b29 100644
--- a/src/crepe/api/EventManager.h
+++ b/src/crepe/api/EventManager.h
@@ -10,48 +10,127 @@
#include "EventHandler.h"
//#include "keyCodes.h"
+/**
+ * @class EventManager
+ * @brief The EventManager class is responsible for managing the subscription, triggering,
+ * and queueing of events. It handles events and dispatches them to appropriate subscribers.
+ */
class EventManager {
public:
- EventManager(const EventManager &) = delete;
- const EventManager & operator=(const EventManager &) = delete;
- static EventManager & get_instance() {
- static EventManager instance;
- return instance;
- }
- template <typename EventType>
- void subscribe(EventHandler<EventType> && callback, int channel = 0);
- template <typename EventType>
- void unsubscribe(const EventHandler<EventType> &, int eventId);
- template <typename EventType>
- void trigger_event(const EventType & event, int channel);
- template <typename EventType>
- void queue_event(EventType&& event, int channel);
- void dispatch_events();
+ /**
+ * \brief Deleted copy constructor to prevent copying of the EventManager instance.
+ */
+ EventManager(const EventManager &) = delete;
+
+ /**
+ * @brief Deleted copy assignment operator to prevent assignment of the EventManager instance.
+ */
+ 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 instance;
+ return instance;
+ }
+
+ /**
+ * @brief Subscribe to an event.
+ *
+ * This method allows the registration of a callback for a specific event type and channel.
+ *
+ * @tparam EventType The type of the event to subscribe to.
+ * @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);
+
+ /**
+ * @brief Unsubscribe from an event.
+ *
+ * This method removes a previously registered callback from an event.
+ *
+ * @tparam EventType The type of the event to unsubscribe from.
+ * @param callback The callback function to remove from the subscription list.
+ * @param eventId The event ID to unsubscribe from.
+ */
+ template <typename EventType>
+ void unsubscribe(const EventHandler<EventType> &, int eventId);
+
+ /**
+ * @brief Trigger an event.
+ *
+ * This method invokes the appropriate callback(s) for the specified event.
+ *
+ * @tparam EventType The type of the event to trigger.
+ * @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);
+
+ /**
+ * @brief Queue an event for later processing.
+ *
+ * This method adds an event to the event queue, which will be processed in the
+ * dispatch_events function.
+ *
+ * @tparam EventType The type of the event to queue.
+ * @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);
+
+ /**
+ * @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();
private:
- EventManager() = default;
- std::vector<std::tuple<std::unique_ptr<Event>, int, std::type_index>> events_queue;
- std::unordered_map<std::type_index, std::vector<std::unique_ptr<IEventHandlerWrapper>>> subscribers;
- std::unordered_map<std::type_index, std::unordered_map<int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>> subscribers_by_event_id;
+ /**
+ * @brief Default constructor for the EventManager.
+ *
+ * This constructor is private to enforce the singleton pattern.
+ */
+ EventManager() = default;
+
+ //! 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;
+ //! 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;
};
template <typename EventType>
-void EventManager::subscribe(EventHandler<EventType> && callback, int channel){
+void EventManager::subscribe(EventHandler<EventType> && callback, int channel) {
std::type_index event_type = typeid(EventType);
- auto handler = std::make_unique<EventHandlerWrapper<EventType>>(callback);
+ std::unique_ptr<EventHandlerWrapper<EventType>> handler = std::make_unique<EventHandlerWrapper<EventType>>(callback);
if (channel) {
- auto & handlers_map = subscribers_by_event_id[event_type];
- auto handlers = handlers_map.find(channel);
+ std::unordered_map<int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>& handlers_map = 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 {
- subscribers[event_type].emplace_back(std::move(handler));
+ std::vector<std::unique_ptr<IEventHandlerWrapper>>& handlers = 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));
@@ -71,10 +150,12 @@ void EventManager::trigger_event(const EventType & event, int eventId) {
std::type_index event_type = std::type_index(typeid(EventType));
if (eventId > 0) {
- auto handlers_it = subscribers_by_event_id[event_type].find(eventId);
- if (handlers_it != subscribers_by_event_id[event_type].end()) {
- auto & callbacks = handlers_it->second;
- for (auto it = callbacks.begin(); it != callbacks.end();) {
+ std::unordered_map<int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>& handlers_map = subscribers_by_event_id[event_type];
+ std::unordered_map<int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator handlers_it = handlers_map.find(eventId);
+
+ if (handlers_it != handlers_map.end()) {
+ std::vector<std::unique_ptr<IEventHandlerWrapper>>& callbacks = handlers_it->second;
+ for (std::vector<std::unique_ptr<IEventHandlerWrapper>>::iterator it = callbacks.begin(); it != callbacks.end();) {
if ((*it)->exec(event)) {
it = callbacks.erase(it);
} else {
@@ -83,25 +164,26 @@ void EventManager::trigger_event(const EventType & event, int eventId) {
}
}
} else {
- auto & handlers = subscribers[event_type];
- for (auto & handler : handlers) {
- handler->exec(event);
+ std::vector<std::unique_ptr<IEventHandlerWrapper>>& handlers = subscribers[event_type];
+ for (std::vector<std::unique_ptr<IEventHandlerWrapper>>::iterator it = handlers.begin(); it != handlers.end(); ++it) {
+ (*it)->exec(event);
}
}
}
+
template <typename EventType>
void EventManager::unsubscribe(const EventHandler<EventType> & callback, int channel) {
std::type_index event_type(typeid(EventType));
- const std::string handler_name = callback.target_type().name();
+ std::string handler_name = callback.target_type().name();
if (channel) {
- auto subscriber_list = subscribers_by_event_id.find(event_type);
+ std::unordered_map<std::type_index, std::unordered_map<int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>>::iterator subscriber_list = subscribers_by_event_id.find(event_type);
if (subscriber_list != subscribers_by_event_id.end()) {
- auto& handlers_map = subscriber_list->second;
- auto handlers = handlers_map.find(channel);
+ 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()) {
- auto& callbacks = handlers->second;
- for (auto it = callbacks.begin(); it != callbacks.end(); ++it) {
+ 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;
@@ -110,10 +192,10 @@ void EventManager::unsubscribe(const EventHandler<EventType> & callback, int cha
}
}
} else {
- auto handlers_it = subscribers.find(event_type);
+ std::unordered_map<std::type_index, std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator handlers_it = subscribers.find(event_type);
if (handlers_it != subscribers.end()) {
- auto& handlers = handlers_it->second;
- for (auto it = handlers.begin(); it != handlers.end(); ++it) {
+ 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;
diff --git a/src/crepe/api/IKeyListener.cpp b/src/crepe/api/IKeyListener.cpp
index 663dbc7..3a06f77 100644
--- a/src/crepe/api/IKeyListener.cpp
+++ b/src/crepe/api/IKeyListener.cpp
@@ -1,8 +1,12 @@
#include "IKeyListener.h"
#include <iostream>
IKeyListener::IKeyListener(){
-
- subscribe_events(0);
+ this->channel = channel;
+ subscribe_events();
+}
+IKeyListener::IKeyListener(int channel){
+ this->channel = channel;
+ subscribe_events(channel);
}
IKeyListener::~IKeyListener() {
unsubscribe_events();
@@ -24,3 +28,15 @@ void IKeyListener::unsubscribe_events(int listenerId) {
EventManager::get_instance().unsubscribe<KeyReleaseEvent>(key_released_handler , listenerId);
std::cout << std::endl;
}
+void IKeyListener::activate_keys(int listenerId) {
+ if(this->active){
+ return;
+ }
+ subscribe_events(listenerId);
+}
+void IKeyListener::deactivate_keys() {
+ if(!this->active){
+ return;
+ }
+ unsubscribe_events();
+}
diff --git a/src/crepe/api/IKeyListener.h b/src/crepe/api/IKeyListener.h
index fc8de16..83949bf 100644
--- a/src/crepe/api/IKeyListener.h
+++ b/src/crepe/api/IKeyListener.h
@@ -4,18 +4,22 @@
#include "EventManager.h"
class IKeyListener {
public:
+ IKeyListener(int channel);
IKeyListener();
virtual ~IKeyListener();
virtual bool on_key_pressed(const KeyPressEvent & event) = 0;
virtual bool on_key_released(const KeyReleaseEvent & event) = 0;
+ void activate_keys(int listenerId = 0);
+ void deactivate_keys();
protected:
void subscribe_events(int listenerId = 0);
void unsubscribe_events(int listenerId = 0);
- void activate(int listenerId = 0) { subscribe_events(listenerId); }
- void deactivate(int listenerId = 0) { unsubscribe_events(listenerId); }
+
private:
+ bool active = true;
+ int channel = 0;
EventHandler<KeyPressEvent> key_pressed_handler;
EventHandler<KeyReleaseEvent> key_released_handler;
};
diff --git a/src/makefile b/src/makefile
index 03a2c0e..f6907f6 100644
--- a/src/makefile
+++ b/src/makefile
@@ -103,10 +103,9 @@ WOUTER += crepe/api/IKeyListener.cpp
WOUTER += crepe/api/IKeyListener.h
WOUTER += crepe/api/IMouseListener.cpp
WOUTER += crepe/api/IMouseListener.h
-FMT := $(WOUTER) #<<< CHANGE THIS TO YOUR NAME FOR STEP 2
+FMT := $(shell git ls-files '*.c' '*.cpp' '*.h' '*.hpp')
format: FORCE
clang-tidy -p build/compile_commands.json --fix-errors $(FMT)
-# FMT += $(shell git ls-files '*.c' '*.cpp' '*.h' '*.hpp')
# TODO: re-enable linter after all corrections