diff options
author | WBoerenkamps <wrj.boerenkamps@student.avans.nl> | 2024-11-12 15:08:37 +0100 |
---|---|---|
committer | WBoerenkamps <wrj.boerenkamps@student.avans.nl> | 2024-11-12 15:08:37 +0100 |
commit | 80e4e1eb78898879eed11648808ca6b65eecb304 (patch) | |
tree | 78d5d51ce36c32b235a4c061b5f51772fabdd8ea /src | |
parent | 48fb3f48831b1db187942592343eb4a2dc6662fc (diff) |
removed auto from code
Diffstat (limited to 'src')
-rw-r--r-- | src/crepe/api/EventHandler.h | 80 | ||||
-rw-r--r-- | src/crepe/api/EventManager.cpp | 21 | ||||
-rw-r--r-- | src/crepe/api/EventManager.h | 162 | ||||
-rw-r--r-- | src/crepe/api/IKeyListener.cpp | 20 | ||||
-rw-r--r-- | src/crepe/api/IKeyListener.h | 8 | ||||
-rw-r--r-- | src/makefile | 3 |
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 |