diff options
author | WBoerenkamps <wrj.boerenkamps@student.avans.nl> | 2024-11-13 15:37:11 +0100 |
---|---|---|
committer | WBoerenkamps <wrj.boerenkamps@student.avans.nl> | 2024-11-13 15:37:11 +0100 |
commit | 408eb1fb5932a683a65db79afed6a300e18db5c6 (patch) | |
tree | e57e60a9b9421b862fedaeef59bf621627ef336d | |
parent | e4b3162d28a635af37dd7ca1f71db16e0d196864 (diff) |
added keycodes
-rw-r--r-- | .vscode/launch.json | 7 | ||||
-rw-r--r-- | .vscode/tasks.json | 28 | ||||
-rw-r--r-- | mwe/events/include/event.h | 2 | ||||
-rw-r--r-- | src/crepe/api/Event.h | 62 | ||||
-rw-r--r-- | src/crepe/api/EventHandler.h | 41 | ||||
-rw-r--r-- | src/crepe/api/EventManager.cpp | 105 | ||||
-rw-r--r-- | src/crepe/api/EventManager.h | 274 | ||||
-rw-r--r-- | src/crepe/api/IKeyListener.cpp | 51 | ||||
-rw-r--r-- | src/crepe/api/IKeyListener.h | 48 | ||||
-rw-r--r-- | src/crepe/api/IMouseListener.cpp | 82 | ||||
-rw-r--r-- | src/crepe/api/IMouseListener.h | 78 | ||||
-rw-r--r-- | src/crepe/api/KeyCodes.h | 147 | ||||
-rw-r--r-- | src/example/events.cpp | 98 |
13 files changed, 637 insertions, 386 deletions
diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..5c7247b --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,7 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [] +}
\ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..05054c5 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,28 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: g++ build active file", + "command": "/usr/bin/g++", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + "-o", + "${fileDirname}/${fileBasenameNoExtension}" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "Task generated by Debugger." + } + ], + "version": "2.0.0" +}
\ No newline at end of file diff --git a/mwe/events/include/event.h b/mwe/events/include/event.h index 16c75bf..3e70201 100644 --- a/mwe/events/include/event.h +++ b/mwe/events/include/event.h @@ -152,7 +152,7 @@ private: }; class ShutDownEvent : public Event { public: - ShutDownEvent() : Event("ShutDownEvent") {}; + ShutDownEvent() : Event("ShutDownEvent"){}; REGISTER_EVENT_TYPE(ShutDownEvent) diff --git a/src/crepe/api/Event.h b/src/crepe/api/Event.h index c0de4fc..87c6068 100644 --- a/src/crepe/api/Event.h +++ b/src/crepe/api/Event.h @@ -1,68 +1,56 @@ #pragma once #include <typeindex> -//#include "keyCodes.h" -#include <cstdint> #include <iostream> #include <string> -#include <unordered_map> -#include <variant> -using Keycode = uint16_t; -enum class MouseButton { - NONE = 0, - LEFT_MOUSE = 1, - RIGHT_MOUSE = 2, - MIDDLE_MOUSE = 3, - X1_MOUSE = 4, - X2_MOUSE = 5, - SCROLL_UP = 6, - SCROLL_DOWN = 7, -}; +#include "KeyCodes.h" + class Event { public: -bool handled = false; + bool handled = false; }; class KeyPressEvent : public Event { public: - int repeat = 0; - Keycode key = 0; + int repeat = 0; + Keycode key = Keycode::None; }; -class MouseClickEvent : public Event { -public: - int mouse_x = 0; - int mouse_y = 0; - MouseButton button; -}; class KeyReleaseEvent : public Event { public: - Keycode key = 0; + Keycode key = Keycode::None; }; class MousePressEvent : public Event { public: - int mouse_x = 0; - int mouse_y = 0; - MouseButton button; + int mouse_x = 0; + int mouse_y = 0; + MouseButton button; +}; + +class MouseClickEvent : public Event { +public: + int mouse_x = 0; + int mouse_y = 0; + MouseButton button; }; class MouseReleaseEvent : public Event { public: - int mouse_x = 0; - int mouse_y = 0; - MouseButton button; + int mouse_x = 0; + int mouse_y = 0; + MouseButton button = MouseButton::None; }; class MouseMoveEvent : public Event { public: - int mouse_x = 0; - int mouse_y = 0; + int mouse_x = 0; + int mouse_y = 0; }; -class CollisionEvent : public Event{ +class CollisionEvent : public Event { public: - //Collision collisionData; + //Collision collisionData; }; -class TextSubmitEvent : public Event{ +class TextSubmitEvent : public Event { public: - std::string text; + std::string text; }; class ShutDownEvent : public Event { public: diff --git a/src/crepe/api/EventHandler.h b/src/crepe/api/EventHandler.h index dc06806..46c6c7b 100644 --- a/src/crepe/api/EventHandler.h +++ b/src/crepe/api/EventHandler.h @@ -1,8 +1,8 @@ #pragma once +#include "Event.h" #include <functional> #include <iostream> #include <typeindex> -#include "Event.h" /** * \brief A type alias for an event handler function. @@ -24,12 +24,12 @@ using EventHandler = std::function<bool(const EventType & e)>; */ class IEventHandlerWrapper { public: - /** + /** * \brief Virtual destructor for IEventHandlerWrapper. */ - virtual ~IEventHandlerWrapper() = default; + 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. @@ -37,19 +37,19 @@ public: * \param e The event to be processed. * \return A boolean value indicating whether the event is handled. */ - bool exec(const Event & e); + 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; + 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. @@ -57,7 +57,7 @@ private: * \param e The event to be processed. * \return A boolean value indicating whether the event is handled. */ - virtual bool call(const Event & e) = 0; + virtual bool call(const Event & e) = 0; }; /** @@ -73,19 +73,18 @@ private: 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()) { - } + 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. @@ -93,20 +92,20 @@ private: * \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)); - } + 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; } + std::string get_type() const override { return m_handler_type; } //! The event handler function. - EventHandler<EventType> m_handler; + EventHandler<EventType> m_handler; //! The type name of the handler function. - const std::string m_handler_type; + const std::string m_handler_type; }; diff --git a/src/crepe/api/EventManager.cpp b/src/crepe/api/EventManager.cpp index 42bff12..72cfd74 100644 --- a/src/crepe/api/EventManager.cpp +++ b/src/crepe/api/EventManager.cpp @@ -6,46 +6,73 @@ EventManager & EventManager::get_instance() { } void EventManager::dispatch_events() { - for (std::vector<std::tuple<std::unique_ptr<Event>, int, std::type_index>>::iterator event_it = this->events_queue.begin(); event_it != this->events_queue.end();) { - std::unique_ptr<Event>& 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<std::tuple<std::unique_ptr<Event>, int, + std::type_index>>::iterator event_it + = this->events_queue.begin(); + event_it != this->events_queue.end();) { + std::unique_ptr<Event> & 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; + bool event_handled = false; - if (channel) { - std::unordered_map<std::type_index, std::unordered_map<int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>>::iterator handlers_it = subscribers_by_event_id.find(event_type); - if (handlers_it != subscribers_by_event_id.end()) { - std::unordered_map<int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>& handlers_map = handlers_it->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 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; - } - } - } - } - } else { - // Handle event for all channels - 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 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; - } - } - } - } + if (channel) { + std::unordered_map< + std::type_index, + std::unordered_map< + int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>>:: + iterator handlers_it + = subscribers_by_event_id.find(event_type); + if (handlers_it != subscribers_by_event_id.end()) { + std::unordered_map< + int, std::vector<std::unique_ptr<IEventHandlerWrapper>>> & + handlers_map + = handlers_it->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 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; + } + } + } + } + } else { + // Handle event for all channels + 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 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; + } + } + } + } - if (!event_handled) { - ++event_it; - } - } + if (!event_handled) { + ++event_it; + } + } } 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; + } + } + } + } } + diff --git a/src/crepe/api/IKeyListener.cpp b/src/crepe/api/IKeyListener.cpp index e759eca..eb8f9af 100644 --- a/src/crepe/api/IKeyListener.cpp +++ b/src/crepe/api/IKeyListener.cpp @@ -1,48 +1,49 @@ #include "IKeyListener.h" #include <iostream> -IKeyListener::IKeyListener(){ +IKeyListener::IKeyListener() { this->channel = channel; this->subscribe_events(); } -IKeyListener::IKeyListener(int channel){ +IKeyListener::IKeyListener(int channel) { this->channel = channel; this->subscribe_events(); } -IKeyListener::~IKeyListener() { - this->unsubscribe_events(); -} +IKeyListener::~IKeyListener() { this->unsubscribe_events(); } 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<KeyPressEvent>(std::move(this->key_pressed_handler), this->channel); - EventManager::get_instance().subscribe<KeyReleaseEvent>(std::move(this->key_released_handler), this->channel); + 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<KeyPressEvent>( + std::move(this->key_pressed_handler), this->channel); + EventManager::get_instance().subscribe<KeyReleaseEvent>( + std::move(this->key_released_handler), this->channel); } void IKeyListener::unsubscribe_events() { - EventManager::get_instance().unsubscribe<KeyPressEvent>(this->key_pressed_handler , channel); - EventManager::get_instance().unsubscribe<KeyReleaseEvent>(this->key_released_handler , channel); + EventManager::get_instance().unsubscribe<KeyPressEvent>( + this->key_pressed_handler, channel); + EventManager::get_instance().unsubscribe<KeyReleaseEvent>( + this->key_released_handler, channel); std::cout << std::endl; } -void IKeyListener::activate_keys() { - if(this->active){ +void IKeyListener::activate_keys() { + if (this->active) { return; } - this->subscribe_events(); + this->subscribe_events(); } -void IKeyListener::deactivate_keys() { - if(!this->active){ +void IKeyListener::deactivate_keys() { + if (!this->active) { return; } - this->unsubscribe_events(); + this->unsubscribe_events(); } -void IKeyListener::set_channel(int channel){ - this->unsubscribe_events(); +void IKeyListener::set_channel(int channel) { + this->unsubscribe_events(); this->channel = channel; - this->subscribe_events(); - + this->subscribe_events(); } diff --git a/src/crepe/api/IKeyListener.h b/src/crepe/api/IKeyListener.h index 6d7915d..839acbf 100644 --- a/src/crepe/api/IKeyListener.h +++ b/src/crepe/api/IKeyListener.h @@ -9,70 +9,70 @@ */ class IKeyListener { public: - /** + /** * \brief Constructs an IKeyListener with a specified channel. * \param channel The channel ID for event handling. */ - IKeyListener(int channel); + IKeyListener(int channel); - /** + /** * \brief Default constructor for IKeyListener. */ - IKeyListener(); + IKeyListener(); - /** + /** * \brief Destructor. */ - virtual ~IKeyListener(); + virtual ~IKeyListener(); - /** + /** * \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; + 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; + virtual bool on_key_released(const KeyReleaseEvent & event) = 0; - /** + /** * \brief Activates key listening. */ - void activate_keys(); + void activate_keys(); - /** + /** * \brief Deactivates key listening. */ - void deactivate_keys(); + void deactivate_keys(); - /** + /** * \brief Sets the channel ID for event handling. * \param channel The channel ID to set. */ - void set_channel(int channel); + void set_channel(int channel); protected: - /** + /** * \brief Subscribes to key events. */ - void subscribe_events(); + void subscribe_events(); - /** + /** * \brief Unsubscribes from key events. */ - void unsubscribe_events(); + void unsubscribe_events(); private: //! Indicates whether key listening is active. - bool active = true; + bool active = true; //! Channel ID for event handling. - int channel = 0; + int channel = 0; //! Key press event handler. - EventHandler<KeyPressEvent> key_pressed_handler; + EventHandler<KeyPressEvent> key_pressed_handler; //!< Key release event handler. - EventHandler<KeyReleaseEvent> key_released_handler; + EventHandler<KeyReleaseEvent> key_released_handler; }; diff --git a/src/crepe/api/IMouseListener.cpp b/src/crepe/api/IMouseListener.cpp index c6ea419..683632c 100644 --- a/src/crepe/api/IMouseListener.cpp +++ b/src/crepe/api/IMouseListener.cpp @@ -1,54 +1,56 @@ #include "IMouseListener.h" -IMouseListener::IMouseListener(int channel){ - this->channel = channel; -} -IMouseListener::IMouseListener(){ - this->subscribe_events(); -} -IMouseListener::~IMouseListener() { - this->unsubscribe_events(); -} +IMouseListener::IMouseListener(int channel) { this->channel = channel; } +IMouseListener::IMouseListener() { this->subscribe_events(); } +IMouseListener::~IMouseListener() { this->unsubscribe_events(); } void IMouseListener::subscribe_events() { - // Define handler lambdas and subscribe them - mouse_click_handler = [this](const MouseClickEvent& event) { - return this->on_mouse_clicked(event); - }; - mouse_press_handler = [this](const MousePressEvent& event) { - return this->on_mouse_pressed(event); - }; - mouse_release_handler = [this](const MouseReleaseEvent& event) { - return this->on_mouse_released(event); - }; - mouse_move_handler = [this](const MouseMoveEvent& event) { - return this->on_mouse_moved(event); - }; - EventManager::get_instance().subscribe<MouseClickEvent>(std::move(this->mouse_click_handler), this->channel); - EventManager::get_instance().subscribe<MousePressEvent>(std::move(this->mouse_press_handler), this->channel); - EventManager::get_instance().subscribe<MouseReleaseEvent>(std::move(this->mouse_release_handler), this->channel); - EventManager::get_instance().subscribe<MouseMoveEvent>(std::move(this->mouse_move_handler), this->channel); + // Define handler lambdas and subscribe them + mouse_click_handler = [this](const MouseClickEvent & event) { + return this->on_mouse_clicked(event); + }; + mouse_press_handler = [this](const MousePressEvent & event) { + return this->on_mouse_pressed(event); + }; + mouse_release_handler = [this](const MouseReleaseEvent & event) { + return this->on_mouse_released(event); + }; + mouse_move_handler = [this](const MouseMoveEvent & event) { + return this->on_mouse_moved(event); + }; + EventManager::get_instance().subscribe<MouseClickEvent>( + std::move(this->mouse_click_handler), this->channel); + EventManager::get_instance().subscribe<MousePressEvent>( + std::move(this->mouse_press_handler), this->channel); + EventManager::get_instance().subscribe<MouseReleaseEvent>( + std::move(this->mouse_release_handler), this->channel); + EventManager::get_instance().subscribe<MouseMoveEvent>( + std::move(this->mouse_move_handler), this->channel); } void IMouseListener::unsubscribe_events() { - EventManager::get_instance().unsubscribe<MouseClickEvent>(this->mouse_click_handler, this->channel); - EventManager::get_instance().unsubscribe<MousePressEvent>(this->mouse_press_handler, this->channel); - EventManager::get_instance().unsubscribe<MouseReleaseEvent>(this->mouse_release_handler, this->channel); - EventManager::get_instance().unsubscribe<MouseMoveEvent>(this->mouse_move_handler, this->channel); -} -void IMouseListener::activate_mouse() { - if(this->active){ + EventManager::get_instance().unsubscribe<MouseClickEvent>( + this->mouse_click_handler, this->channel); + EventManager::get_instance().unsubscribe<MousePressEvent>( + this->mouse_press_handler, this->channel); + EventManager::get_instance().unsubscribe<MouseReleaseEvent>( + this->mouse_release_handler, this->channel); + EventManager::get_instance().unsubscribe<MouseMoveEvent>( + this->mouse_move_handler, this->channel); +} +void IMouseListener::activate_mouse() { + if (this->active) { return; } - this->subscribe_events(); + this->subscribe_events(); } -void IMouseListener::deactivate_mouse() { - if(!this->active){ +void IMouseListener::deactivate_mouse() { + if (!this->active) { return; } - this->unsubscribe_events(); + this->unsubscribe_events(); } -void IMouseListener::set_channel(int channel){ - this->unsubscribe_events(); +void IMouseListener::set_channel(int channel) { + this->unsubscribe_events(); this->channel = channel; - this->subscribe_events(); + this->subscribe_events(); } diff --git a/src/crepe/api/IMouseListener.h b/src/crepe/api/IMouseListener.h index a7ad271..7e92956 100644 --- a/src/crepe/api/IMouseListener.h +++ b/src/crepe/api/IMouseListener.h @@ -10,108 +10,108 @@ */ class IMouseListener { public: - /** + /** * \brief Default constructor. */ - IMouseListener(); + IMouseListener(); - /** + /** * \brief Constructs an IMouseListener with a specified channel. * \param channel The channel ID for event handling. */ - IMouseListener(int channel); + IMouseListener(int channel); - /** + /** * \brief Destructor. */ - virtual ~IMouseListener(); + virtual ~IMouseListener(); - /** + /** * \brief Copy constructor (deleted). */ - IMouseListener(const IMouseListener&) = delete; + IMouseListener(const IMouseListener &) = delete; - /** + /** * \brief Copy assignment operator (deleted). */ - IMouseListener& operator=(const IMouseListener&) = delete; + IMouseListener & operator=(const IMouseListener &) = delete; - /** + /** * \brief Move constructor (deleted). */ - IMouseListener(IMouseListener&&) = delete; + IMouseListener(IMouseListener &&) = delete; - /** + /** * \brief Move assignment operator (deleted). */ - IMouseListener& operator=(IMouseListener&&) = delete; + 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; + 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; + 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; + 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; + virtual bool on_mouse_moved(const MouseMoveEvent & event) = 0; - /** + /** * \brief Activates mouse listening. */ - void activate_mouse(); + void activate_mouse(); - /** + /** * \brief Deactivates mouse listening. */ - void deactivate_mouse(); + void deactivate_mouse(); - /** + /** * \brief Sets the channel ID for event handling. * \param channel The channel ID to set. */ - void set_channel(int channel); + void set_channel(int channel); protected: - /** + /** * \brief Subscribes to mouse events on the specified channel. */ - void subscribe_events(); + void subscribe_events(); - /** + /** * \brief Unsubscribes from mouse events on the specified channel. */ - void unsubscribe_events(); + void unsubscribe_events(); private: //! Indicates whether mouse listening is active. - bool active = true; - //! Channel ID for event handling. - int channel = 0; + bool active = true; + //! Channel ID for event handling. + int channel = 0; //! Mouse click event handler. - EventHandler<MouseClickEvent> mouse_click_handler; + EventHandler<MouseClickEvent> mouse_click_handler; //! Mouse press event handler. - EventHandler<MousePressEvent> mouse_press_handler; + EventHandler<MousePressEvent> mouse_press_handler; //! Mouse release event handler. - EventHandler<MouseReleaseEvent> mouse_release_handler; + EventHandler<MouseReleaseEvent> mouse_release_handler; //! Mouse move event handler. - EventHandler<MouseMoveEvent> mouse_move_handler; + EventHandler<MouseMoveEvent> mouse_move_handler; }; diff --git a/src/crepe/api/KeyCodes.h b/src/crepe/api/KeyCodes.h new file mode 100644 index 0000000..53be91b --- /dev/null +++ b/src/crepe/api/KeyCodes.h @@ -0,0 +1,147 @@ +#pragma once + +enum class MouseButton { + None = 0, + Left_Mouse = 1, + Right_Mouse = 2, + Middle_Mouse = 3, + X1_Mouse = 4, + X2_Mouse = 5, + Scroll_Up = 6, + Scroll_Down = 7, +}; + +enum class Keycode : int{ + // From glfw3.h + None = 0, + Space = 32, + Apostrophe = 39, /* ' */ + Comma = 44, /* , */ + Minus = 45, /* - */ + Period = 46, /* . */ + Slash = 47, /* / */ + + D0 = 48, /* 0 */ + D1 = 49, /* 1 */ + D2 = 50, /* 2 */ + D3 = 51, /* 3 */ + D4 = 52, /* 4 */ + D5 = 53, /* 5 */ + D6 = 54, /* 6 */ + D7 = 55, /* 7 */ + D8 = 56, /* 8 */ + D9 = 57, /* 9 */ + + Semicolon = 59, /* ; */ + Equal = 61, /* = */ + + A = 65, + B = 66, + C = 67, + D = 68, + E = 69, + F = 70, + G = 71, + H = 72, + I = 73, + J = 74, + K = 75, + L = 76, + M = 77, + N = 78, + O = 79, + P = 80, + Q = 81, + R = 82, + S = 83, + T = 84, + U = 85, + V = 86, + W = 87, + X = 88, + Y = 89, + Z = 90, + + LeftBracket = 91, /* [ */ + Backslash = 92, /* \ */ + RightBracket = 93, /* ] */ + GraveAccent = 96, /* ` */ + + World1 = 161, /* non-US #1 */ + World2 = 162, /* non-US #2 */ + + /* Function keys */ + Escape = 256, + Enter = 257, + Tab = 258, + Backspace = 259, + Insert = 260, + Delete = 261, + Right = 262, + Left = 263, + Down = 264, + Up = 265, + PageUp = 266, + PageDown = 267, + Home = 268, + End = 269, + CapsLock = 280, + ScrollLock = 281, + NumLock = 282, + PrintScreen = 283, + Pause = 284, + F1 = 290, + F2 = 291, + F3 = 292, + F4 = 293, + F5 = 294, + F6 = 295, + F7 = 296, + F8 = 297, + F9 = 298, + F10 = 299, + F11 = 300, + F12 = 301, + F13 = 302, + F14 = 303, + F15 = 304, + F16 = 305, + F17 = 306, + F18 = 307, + F19 = 308, + F20 = 309, + F21 = 310, + F22 = 311, + F23 = 312, + F24 = 313, + F25 = 314, + + /* Keypad */ + KP0 = 320, + KP1 = 321, + KP2 = 322, + KP3 = 323, + KP4 = 324, + KP5 = 325, + KP6 = 326, + KP7 = 327, + KP8 = 328, + KP9 = 329, + KPDecimal = 330, + KPDivide = 331, + KPMultiply = 332, + KPSubtract = 333, + KPAdd = 334, + KPEnter = 335, + KPEqual = 336, + + LeftShift = 340, + LeftControl = 341, + LeftAlt = 342, + LeftSuper = 343, + RightShift = 344, + RightControl = 345, + RightAlt = 346, + RightSuper = 347, + Menu = 348 +}; diff --git a/src/example/events.cpp b/src/example/events.cpp index af6f294..210c42c 100644 --- a/src/example/events.cpp +++ b/src/example/events.cpp @@ -4,103 +4,107 @@ #include <crepe/system/ScriptSystem.h> #include <crepe/util/log.h> +#include <crepe/api/Event.h> +#include <crepe/api/EventManager.h> +#include <crepe/api/IKeyListener.h> +#include <crepe/api/IMouseListener.h> #include <crepe/api/BehaviorScript.h> #include <crepe/api/Config.h> #include <crepe/api/GameObject.h> #include <crepe/api/Script.h> #include <crepe/api/Transform.h> -#include "crepe/api/Event.h" -#include "crepe/api/EventManager.h" -#include "crepe/api/IKeyListener.h" -#include "crepe/api/IMouseListener.h" +#include <crepe/api/KeyCodes.h> using namespace crepe; using namespace std; -class MyScript : public Script, public IKeyListener,public IMouseListener{ +class MyScript : public Script, public IKeyListener, public IMouseListener { void update() { // Retrieve component from the same GameObject this script is on Transform & test = get_component<Transform>(); dbg_logf("Transform(%.2f, %.2f)", test.position.x, test.position.y); } - bool on_key_pressed(const KeyPressEvent & event) override{ + bool on_key_pressed(const KeyPressEvent & event) override { std::cout << "KeyPressed function" << std::endl; this->deactivate_keys(); return false; } - bool on_key_released(const KeyReleaseEvent & event) override{ + bool on_key_released(const KeyReleaseEvent & event) override { std::cout << "KeyRelease function" << std::endl; return false; } - bool on_mouse_clicked(const MouseClickEvent & event) override{ + bool on_mouse_clicked(const MouseClickEvent & event) override { std::cout << "MouseClick function" << std::endl; return false; } - bool on_mouse_pressed(const MousePressEvent & event) override { + bool on_mouse_pressed(const MousePressEvent & event) override { std::cout << "MousePress function" << std::endl; return false; } - bool on_mouse_released(const MouseReleaseEvent & event) override { + bool on_mouse_released(const MouseReleaseEvent & event) override { std::cout << "MouseRelease function" << std::endl; return false; } - bool on_mouse_moved(const MouseMoveEvent & event) override { + bool on_mouse_moved(const MouseMoveEvent & event) override { std::cout << "MouseMove function" << std::endl; return false; } - }; class TestKeyListener : public IKeyListener { public: - bool on_key_pressed(const KeyPressEvent &event) override { - std::cout << "TestKeyListener: Key Pressed - Code: " << event.key << std::endl; - return true; // Return true if the listener should remain active - } - bool on_key_released(const KeyReleaseEvent &event) override { - std::cout << "TestKeyListener: Key Released - Code: " << event.key << std::endl; - return true; - } + bool on_key_pressed(const KeyPressEvent & event) override { + std::cout << "TestKeyListener: Key Pressed - Code: " << static_cast<int>(event.key) + << std::endl; + return true; // Return true if the listener should remain active + } + bool on_key_released(const KeyReleaseEvent & event) override { + std::cout << "TestKeyListener: Key Released - Code: " << static_cast<int>(event.key) + << std::endl; + return true; + } }; int main() { // two events to trigger KeyPressEvent key_press; - key_press.key = 1; - key_press.repeat = 0; + key_press.key = Keycode::A; + key_press.repeat = 0; MouseClickEvent click_event; - click_event.button = MouseButton::LEFT_MOUSE; - click_event.mouse_x = 100; - click_event.mouse_y = 200; + click_event.button = MouseButton::Left_Mouse; + click_event.mouse_x = 100; + click_event.mouse_y = 200; // queue events to test queue - EventManager::get_instance().queue_event<KeyPressEvent>(std::move(key_press), 0); - EventManager::get_instance().queue_event<MouseClickEvent>(std::move(click_event), 0); - { - TestKeyListener testListener; - testListener.set_channel(1); - auto obj = GameObject(0, "name", "tag", Vector2{1.2, 3.4}, 0, 1); - obj.add_component<BehaviorScript>().set_script<MyScript>(); + EventManager::get_instance().queue_event<KeyPressEvent>( + std::move(key_press), 0); + EventManager::get_instance().queue_event<MouseClickEvent>( + std::move(click_event), 0); + { + TestKeyListener test_listener; + test_listener.set_channel(1); + auto obj = GameObject(0, "name", "tag", Vector2{1.2, 3.4}, 0, 1); + obj.add_component<BehaviorScript>().set_script<MyScript>(); - ScriptSystem sys; - sys.update(); + ScriptSystem sys; + sys.update(); - // Trigger the events while `testListener` is in scope - EventManager::get_instance().trigger_event<KeyPressEvent>(key_press, 1); - EventManager::get_instance().trigger_event<MouseClickEvent>(click_event, 1); - } + // Trigger the events while `testListener` is in scope + EventManager::get_instance().trigger_event<KeyPressEvent>(key_press, 1); + EventManager::get_instance().trigger_event<MouseClickEvent>(click_event, + 1); + } // custom lambda event handler - EventHandler<KeyPressEvent> event_handler = [](const KeyPressEvent& e) { - std::cout << "lambda test" << std::endl; + EventHandler<KeyPressEvent> event_handler = [](const KeyPressEvent & e) { + std::cout << "lambda test" << std::endl; return false; }; - EventManager::get_instance().subscribe<KeyPressEvent>(std::move(event_handler),0); + EventManager::get_instance().subscribe<KeyPressEvent>( + std::move(event_handler), 0); // testing trigger with testListener not in scope (unsubscribed) - EventManager::get_instance().trigger_event<KeyPressEvent>(key_press, 0); - EventManager::get_instance().trigger_event<MouseClickEvent>(click_event, 0); + EventManager::get_instance().trigger_event<KeyPressEvent>(key_press, 0); + EventManager::get_instance().trigger_event<MouseClickEvent>(click_event, 0); // dispatching queued events EventManager::get_instance().dispatch_events(); - EventManager::get_instance().unsubscribe<KeyPressEvent>(event_handler,0); - return EXIT_SUCCESS; + EventManager::get_instance().unsubscribe<KeyPressEvent>(event_handler, 0); + return EXIT_SUCCESS; } - - |