From ab0c50d5b719863ab9e9821e6720bba450e174ce Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Wed, 13 Nov 2024 12:19:58 +0100 Subject: added activate/deactive to listeners and doxygen comments --- src/crepe/api/EventManager.cpp | 36 ++++++------- src/crepe/api/EventManager.h | 88 ++++++++++++++++-------------- src/crepe/api/IKeyListener.cpp | 27 +++++----- src/crepe/api/IKeyListener.h | 77 +++++++++++++++++++++----- src/crepe/api/IMouseListener.cpp | 42 ++++++++++----- src/crepe/api/IMouseListener.h | 114 +++++++++++++++++++++++++++++++++++---- src/example/events.cpp | 3 -- 7 files changed, 276 insertions(+), 111 deletions(-) diff --git a/src/crepe/api/EventManager.cpp b/src/crepe/api/EventManager.cpp index 3d8558b..872c6eb 100644 --- a/src/crepe/api/EventManager.cpp +++ b/src/crepe/api/EventManager.cpp @@ -1,24 +1,22 @@ #include "EventManager.h" - - void EventManager::dispatch_events() { - for (auto event_it = events_queue.begin(); event_it != events_queue.end();) { - auto& event = std::get<0>(*event_it); - int channel = std::get<1>(*event_it); - std::type_index event_type = std::get<2>(*event_it); + for (std::vector, int, std::type_index>>::iterator event_it = this->events_queue.begin(); event_it != this->events_queue.end();) { + std::unique_ptr& 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); + std::unordered_map>>>::iterator handlers_it = subscribers_by_event_id.find(event_type); if (handlers_it != subscribers_by_event_id.end()) { - auto& handlers_map = handlers_it->second; - auto handlers = handlers_map.find(channel); + std::unordered_map>>& handlers_map = handlers_it->second; + std::unordered_map>>::iterator handlers = handlers_map.find(channel); if (handlers != handlers_map.end()) { - auto& callbacks = handlers->second; - for (auto& handler : callbacks) { - if (handler->exec(*event)) { + std::vector>& callbacks = handlers->second; + for (std::vector>::iterator handler_it = callbacks.begin(); handler_it != callbacks.end(); ++handler_it) { + if ((*handler_it)->exec(*event)) { event_it = events_queue.erase(event_it); event_handled = true; break; @@ -28,12 +26,12 @@ void EventManager::dispatch_events() { } } 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) { - if (handler->exec(*event)) { - event_it = events_queue.erase(event_it); + std::unordered_map>>::iterator handlers_it = this->subscribers.find(event_type); + if (handlers_it != this->subscribers.end()) { + std::vector>& handlers = handlers_it->second; + for (std::vector>::iterator handler_it = handlers.begin(); handler_it != handlers.end(); ++handler_it) { + if ((*handler_it)->exec(*event)) { + event_it = this->events_queue.erase(event_it); event_handled = true; break; } @@ -46,5 +44,3 @@ void EventManager::dispatch_events() { } } } - - diff --git a/src/crepe/api/EventManager.h b/src/crepe/api/EventManager.h index 9b69b29..d3a14da 100644 --- a/src/crepe/api/EventManager.h +++ b/src/crepe/api/EventManager.h @@ -1,18 +1,18 @@ #pragma once + #include #include #include #include -#include #include #include + #include "Event.h" #include "EventHandler.h" -//#include "keyCodes.h" /** - * @class EventManager - * @brief The EventManager class is responsible for managing the subscription, triggering, + * \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 { @@ -23,16 +23,16 @@ public: EventManager(const EventManager &) = delete; /** - * @brief Deleted copy assignment operator to prevent assignment of the EventManager instance. + * \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. + * \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. + * \return Reference to the EventManager instance. */ static EventManager & get_instance() { static EventManager instance; @@ -40,56 +40,56 @@ public: } /** - * @brief Subscribe to an event. + * \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). + * \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 void subscribe(EventHandler && callback, int channel = 0); /** - * @brief Unsubscribe from an event. + * \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. + * \tparam EventType The type of the event to unsubscribe from. + * \param callback The callback function to remove from the subscription list. + * \param channel The event ID to unsubscribe from. */ template - void unsubscribe(const EventHandler &, int eventId); + void unsubscribe(const EventHandler &, int channel); /** - * @brief Trigger an event. + * \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). + * \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 void trigger_event(const EventType & event, int channel); /** - * @brief Queue an event for later processing. + * \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). + * \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 void queue_event(EventType&& event, int channel); /** - * @brief Dispatch all queued events. + * \brief Dispatch all queued events. * * This method processes all events in the event queue and triggers the corresponding * callbacks for each event. @@ -98,7 +98,7 @@ public: private: /** - * @brief Default constructor for the EventManager. + * \brief Default constructor for the EventManager. * * This constructor is private to enforce the singleton pattern. */ @@ -118,7 +118,7 @@ void EventManager::subscribe(EventHandler && callback, int channel) { std::unique_ptr> handler = std::make_unique>(callback); if (channel) { - std::unordered_map>>& handlers_map = subscribers_by_event_id[event_type]; + std::unordered_map>>& handlers_map = this->subscribers_by_event_id[event_type]; std::unordered_map>>::iterator handlers = handlers_map.find(channel); if (handlers != handlers_map.end()) { handlers->second.emplace_back(std::move(handler)); @@ -126,7 +126,7 @@ void EventManager::subscribe(EventHandler && callback, int channel) { handlers_map[channel].emplace_back(std::move(handler)); } } else { - std::vector>& handlers = subscribers[event_type]; + std::vector>& handlers = this->subscribers[event_type]; handlers.emplace_back(std::move(handler)); } } @@ -142,22 +142,23 @@ void EventManager::queue_event(EventType&& event, int channel) { channel, event_type ); - events_queue.push_back(std::move(tuple)); + this->events_queue.push_back(std::move(tuple)); } template -void EventManager::trigger_event(const EventType & event, int eventId) { +void EventManager::trigger_event(const EventType & event, int channel) { std::type_index event_type = std::type_index(typeid(EventType)); - if (eventId > 0) { + if (channel > 0) { std::unordered_map>>& handlers_map = subscribers_by_event_id[event_type]; - std::unordered_map>>::iterator handlers_it = handlers_map.find(eventId); + std::unordered_map>>::iterator handlers_it = handlers_map.find(channel); if (handlers_it != handlers_map.end()) { - std::vector>& callbacks = handlers_it->second; - for (std::vector>::iterator it = callbacks.begin(); it != callbacks.end();) { + std::vector>& handlers = handlers_it->second; + for (std::vector>::iterator it = handlers.begin(); it != handlers.end();) { + // erases callback if callback function returns true if ((*it)->exec(event)) { - it = callbacks.erase(it); + it = handlers.erase(it); } else { ++it; } @@ -165,8 +166,13 @@ void EventManager::trigger_event(const EventType & event, int eventId) { } } else { std::vector>& handlers = subscribers[event_type]; - for (std::vector>::iterator it = handlers.begin(); it != handlers.end(); ++it) { - (*it)->exec(event); + for (std::vector>::iterator it = handlers.begin(); it != handlers.end();) { + // erases callback if callback function returns true + if ((*it)->exec(event)) { + it = handlers.erase(it); + } else { + ++it; + } } } } @@ -177,8 +183,8 @@ void EventManager::unsubscribe(const EventHandler & callback, int cha std::string handler_name = callback.target_type().name(); if (channel) { - std::unordered_map>>>::iterator subscriber_list = subscribers_by_event_id.find(event_type); - if (subscriber_list != subscribers_by_event_id.end()) { + std::unordered_map>>>::iterator subscriber_list = this->subscribers_by_event_id.find(event_type); + if (subscriber_list != this->subscribers_by_event_id.end()) { std::unordered_map>>& handlers_map = subscriber_list->second; std::unordered_map>>::iterator handlers = handlers_map.find(channel); if (handlers != handlers_map.end()) { @@ -192,8 +198,8 @@ void EventManager::unsubscribe(const EventHandler & callback, int cha } } } else { - std::unordered_map>>::iterator handlers_it = subscribers.find(event_type); - if (handlers_it != subscribers.end()) { + std::unordered_map>>::iterator handlers_it = this->subscribers.find(event_type); + if (handlers_it != this->subscribers.end()) { std::vector>& handlers = handlers_it->second; for (std::vector>::iterator it = handlers.begin(); it != handlers.end(); ++it) { if ((*it)->get_type() == handler_name) { diff --git a/src/crepe/api/IKeyListener.cpp b/src/crepe/api/IKeyListener.cpp index 3a06f77..17d8735 100644 --- a/src/crepe/api/IKeyListener.cpp +++ b/src/crepe/api/IKeyListener.cpp @@ -2,41 +2,44 @@ #include IKeyListener::IKeyListener(){ this->channel = channel; - subscribe_events(); + this->subscribe_events(); } IKeyListener::IKeyListener(int channel){ this->channel = channel; - subscribe_events(channel); + this->subscribe_events(); } IKeyListener::~IKeyListener() { - unsubscribe_events(); + this->unsubscribe_events(); } -void IKeyListener::subscribe_events(int listenerId) { +void IKeyListener::subscribe_events() { key_pressed_handler = [this](const KeyPressEvent & event) { return this->on_key_pressed(event); }; key_released_handler = [this](const KeyReleaseEvent & event) { return this->on_key_released(event); }; - EventManager::get_instance().subscribe(std::move(key_pressed_handler), listenerId); - EventManager::get_instance().subscribe(std::move(key_released_handler), listenerId); + EventManager::get_instance().subscribe(std::move(this->key_pressed_handler), this->channel); + EventManager::get_instance().subscribe(std::move(this->key_released_handler), this->channel); } -void IKeyListener::unsubscribe_events(int listenerId) { - EventManager::get_instance().unsubscribe(key_pressed_handler , listenerId); - EventManager::get_instance().unsubscribe(key_released_handler , listenerId); +void IKeyListener::unsubscribe_events() { + EventManager::get_instance().unsubscribe(this->key_pressed_handler , channel); + EventManager::get_instance().unsubscribe(this->key_released_handler , channel); std::cout << std::endl; } -void IKeyListener::activate_keys(int listenerId) { +void IKeyListener::activate_keys() { if(this->active){ return; } - subscribe_events(listenerId); + this->subscribe_events(); } void IKeyListener::deactivate_keys() { if(!this->active){ return; } - unsubscribe_events(); + this->unsubscribe_events(); +} +void IKeyListener::set_channel(int channel){ + this->channel = channel; } diff --git a/src/crepe/api/IKeyListener.h b/src/crepe/api/IKeyListener.h index 83949bf..6d7915d 100644 --- a/src/crepe/api/IKeyListener.h +++ b/src/crepe/api/IKeyListener.h @@ -2,24 +2,77 @@ #include "Event.h" #include "EventHandler.h" #include "EventManager.h" + +/** + * \class IKeyListener + * \brief Interface for keyboard event handling in the application. + */ class IKeyListener { public: - IKeyListener(int channel); - IKeyListener(); + /** + * \brief Constructs an IKeyListener with a specified channel. + * \param channel The channel ID for event handling. + */ + IKeyListener(int channel); + + /** + * \brief Default constructor for IKeyListener. + */ + IKeyListener(); + + /** + * \brief Destructor. + */ 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); + + /** + * \brief Pure virtual function to handle key press events. + * \param event The key press event to handle. + * \return True if the event was handled, false otherwise. + */ + virtual bool on_key_pressed(const KeyPressEvent& event) = 0; + + /** + * \brief Pure virtual function to handle key release events. + * \param event The key release event to handle. + * \return True if the event was handled, false otherwise. + */ + virtual bool on_key_released(const KeyReleaseEvent& event) = 0; + + /** + * \brief Activates key listening. + */ + void activate_keys(); + + /** + * \brief Deactivates key listening. + */ void deactivate_keys(); + /** + * \brief Sets the channel ID for event handling. + * \param channel The channel ID to set. + */ + void set_channel(int channel); + protected: - void subscribe_events(int listenerId = 0); - void unsubscribe_events(int listenerId = 0); - + /** + * \brief Subscribes to key events. + */ + void subscribe_events(); + + /** + * \brief Unsubscribes from key events. + */ + void unsubscribe_events(); private: - bool active = true; - int channel = 0; - EventHandler key_pressed_handler; - EventHandler key_released_handler; + //! Indicates whether key listening is active. + bool active = true; + //! Channel ID for event handling. + int channel = 0; + //! Key press event handler. + EventHandler key_pressed_handler; + //!< Key release event handler. + EventHandler key_released_handler; }; diff --git a/src/crepe/api/IMouseListener.cpp b/src/crepe/api/IMouseListener.cpp index bb59664..68061be 100644 --- a/src/crepe/api/IMouseListener.cpp +++ b/src/crepe/api/IMouseListener.cpp @@ -1,12 +1,15 @@ #include "IMouseListener.h" +IMouseListener::IMouseListener(int channel){ + this->channel = channel; +} IMouseListener::IMouseListener(){ - subscribe_events(); + this->subscribe_events(); } IMouseListener::~IMouseListener() { - unsubscribe_events(); + this->unsubscribe_events(); } -void IMouseListener::subscribe_events(int listenerId) { +void IMouseListener::subscribe_events() { // Define handler lambdas and subscribe them mouse_click_handler = [this](const MouseClickEvent& event) { return this->on_mouse_clicked(event); @@ -20,15 +23,30 @@ void IMouseListener::subscribe_events(int listenerId) { mouse_move_handler = [this](const MouseMoveEvent& event) { return this->on_mouse_moved(event); }; - EventManager::get_instance().subscribe(std::move(mouse_click_handler), listenerId); - EventManager::get_instance().subscribe(std::move(mouse_press_handler), listenerId); - EventManager::get_instance().subscribe(std::move(mouse_release_handler), listenerId); - EventManager::get_instance().subscribe(std::move(mouse_move_handler), listenerId); + EventManager::get_instance().subscribe(std::move(this->mouse_click_handler), this->channel); + EventManager::get_instance().subscribe(std::move(this->mouse_press_handler), this->channel); + EventManager::get_instance().subscribe(std::move(this->mouse_release_handler), this->channel); + EventManager::get_instance().subscribe(std::move(this->mouse_move_handler), this->channel); } -void IMouseListener::unsubscribe_events(int listenerId) { - EventManager::get_instance().unsubscribe(mouse_click_handler, listenerId); - EventManager::get_instance().unsubscribe(mouse_press_handler, listenerId); - EventManager::get_instance().unsubscribe(mouse_release_handler, listenerId); - EventManager::get_instance().unsubscribe(mouse_move_handler, listenerId); +void IMouseListener::unsubscribe_events() { + EventManager::get_instance().unsubscribe(this->mouse_click_handler, this->channel); + EventManager::get_instance().unsubscribe(this->mouse_press_handler, this->channel); + EventManager::get_instance().unsubscribe(this->mouse_release_handler, this->channel); + EventManager::get_instance().unsubscribe(this->mouse_move_handler, this->channel); +} +void IMouseListener::activate_keys() { + if(this->active){ + return; + } + this->subscribe_events(); +} +void IMouseListener::deactivate_keys() { + if(!this->active){ + return; + } + this->unsubscribe_events(); +} +void IMouseListener::set_channel(int channel){ + this->channel = channel; } diff --git a/src/crepe/api/IMouseListener.h b/src/crepe/api/IMouseListener.h index 1078257..4493e7f 100644 --- a/src/crepe/api/IMouseListener.h +++ b/src/crepe/api/IMouseListener.h @@ -1,25 +1,117 @@ #pragma once + #include "Event.h" #include "EventHandler.h" #include "EventManager.h" +/** + * \class IMouseListener + * \brief Interface for mouse event handling in the application. + */ class IMouseListener { public: - IMouseListener(); + /** + * \brief Default constructor. + */ + IMouseListener(); + + /** + * \brief Constructs an IMouseListener with a specified channel. + * \param channel The channel ID for event handling. + */ + IMouseListener(int channel); + + /** + * \brief Destructor. + */ virtual ~IMouseListener(); - virtual bool on_mouse_clicked(const MouseClickEvent & event) = 0; - virtual bool on_mouse_pressed(const MousePressEvent & event) = 0; - virtual bool on_mouse_released(const MouseReleaseEvent & event) = 0; - virtual bool on_mouse_moved(const MouseMoveEvent & event) = 0; + /** + * \brief Copy constructor (deleted). + */ + IMouseListener(const IMouseListener&) = delete; + + /** + * \brief Copy assignment operator (deleted). + */ + IMouseListener& operator=(const IMouseListener&) = delete; + + /** + * \brief Move constructor (deleted). + */ + IMouseListener(IMouseListener&&) = delete; + + /** + * \brief Move assignment operator (deleted). + */ + IMouseListener& operator=(IMouseListener&&) = delete; + + /** + * \brief Handles a mouse click event. + * \param event The mouse click event to handle. + * \return True if the event was handled, false otherwise. + */ + virtual bool on_mouse_clicked(const MouseClickEvent& event) = 0; + + /** + * \brief Handles a mouse press event. + * \param event The mouse press event to handle. + * \return True if the event was handled, false otherwise. + */ + virtual bool on_mouse_pressed(const MousePressEvent& event) = 0; + + /** + * \brief Handles a mouse release event. + * \param event The mouse release event to handle. + * \return True if the event was handled, false otherwise. + */ + virtual bool on_mouse_released(const MouseReleaseEvent& event) = 0; + + /** + * \brief Handles a mouse move event. + * \param event The mouse move event to handle. + * \return True if the event was handled, false otherwise. + */ + virtual bool on_mouse_moved(const MouseMoveEvent& event) = 0; + + /** + * \brief Activates mouse listening. + */ + void activate_keys(); + + /** + * \brief Deactivates mouse listening. + */ + void deactivate_keys(); + + /** + * \brief Sets the channel ID for event handling. + * \param channel The channel ID to set. + */ + void set_channel(int channel); protected: - void subscribe_events(int listenerId = 0); - void unsubscribe_events(int listenerId = 0); + /** + * \brief Subscribes to mouse events on the specified channel. + */ + void subscribe_events(); + + /** + * \brief Unsubscribes from mouse events on the specified channel. + */ + void unsubscribe_events(); private: - EventHandler mouse_click_handler; - EventHandler mouse_press_handler; - EventHandler mouse_release_handler; - EventHandler mouse_move_handler; + //! Indicates whether mouse listening is active. + bool active = true; + //! Channel ID for event handling. + int channel = 0; + //! Mouse click event handler. + EventHandler mouse_click_handler; + //! Mouse press event handler. + EventHandler mouse_press_handler; + //! Mouse release event handler. + EventHandler mouse_release_handler; + //! Mouse move event handler. + EventHandler mouse_move_handler; }; diff --git a/src/example/events.cpp b/src/example/events.cpp index 1f757e1..1a29d80 100644 --- a/src/example/events.cpp +++ b/src/example/events.cpp @@ -73,14 +73,11 @@ int main() { EventManager::get_instance().queue_event(std::move(key_press), 0); EventManager::get_instance().queue_event(std::move(click_event), 0); { - // Instantiate TestKeyListener, which subscribes to key events TestKeyListener testListener; - // Create game object with Transform and BehaviorScript components auto obj = GameObject(0, "name", "tag", Vector2{1.2, 3.4}, 0, 1); obj.add_component().set_script(); - // Get ScriptSystem singleton instance (this would normally be done from the game loop) ScriptSystem sys; sys.update(); -- cgit v1.2.3