diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/crepe/api/Event.h | 1 | ||||
-rw-r--r-- | src/crepe/api/EventHandler.h | 1 | ||||
-rw-r--r-- | src/crepe/api/EventManager.cpp | 96 | ||||
-rw-r--r-- | src/crepe/api/EventManager.h | 21 | ||||
-rw-r--r-- | src/crepe/api/IKeyListener.cpp | 16 | ||||
-rw-r--r-- | src/crepe/api/IMouseListener.cpp | 8 | ||||
-rw-r--r-- | src/example/events.cpp | 51 |
7 files changed, 86 insertions, 108 deletions
diff --git a/src/crepe/api/Event.h b/src/crepe/api/Event.h index 8d9b241..c0de4fc 100644 --- a/src/crepe/api/Event.h +++ b/src/crepe/api/Event.h @@ -19,6 +19,7 @@ enum class MouseButton { }; class Event { public: +bool handled = false; }; class KeyPressEvent : public Event { diff --git a/src/crepe/api/EventHandler.h b/src/crepe/api/EventHandler.h index 0da6d7d..eea1c79 100644 --- a/src/crepe/api/EventHandler.h +++ b/src/crepe/api/EventHandler.h @@ -24,7 +24,6 @@ class EventHandlerWrapper : public IEventHandlerWrapper { public: explicit EventHandlerWrapper(const EventHandler<EventType> & handler) : m_handler(handler), m_handler_type(m_handler.target_type().name()) { - std::cout << "subscribe name: " << m_handler_type << std::endl; } private: diff --git a/src/crepe/api/EventManager.cpp b/src/crepe/api/EventManager.cpp index 7a8be53..869ec74 100644 --- a/src/crepe/api/EventManager.cpp +++ b/src/crepe/api/EventManager.cpp @@ -1,69 +1,39 @@ #include "EventManager.h" -// void EventManager::unsubscribe(std::type_index eventType, const std::string & handlerName, -// int eventId) { -// if (eventId) { -// std::unordered_map< -// std::type_index, std::unordered_map< -// int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>>::iterator subscriber_list = subscribers_by_event_id.find(eventType); -// if (subscriber_list != 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(eventId); -// 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()->get_type() == handlerName) { -// it = callbacks.erase(it); -// return; -// } -// } -// } -// } -// } else { -// std::unordered_map< -// std::type_index, std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator -// handlers_it -// = subscribers.find(eventType); -// if (handlers_it != 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()->get_type() == handlerName) { -// it = handlers.erase(it); -// return; -// } -// } -// } -// } -// } -void EventManager::queue_event(std::unique_ptr<Event> && event_, int eventId) { - events_queue.emplace_back(std::move(event_), eventId); -} void EventManager::dispatch_events() { - for (std::vector<std::pair<std::unique_ptr<Event>, int>>::iterator event_it - = events_queue.begin(); - event_it != events_queue.end();) { - bool handled = false; - if (!handled) { - trigger_event<Event>(*event_it->first.get(), event_it->second); - event_it = events_queue.erase(event_it); - } else { - ++event_it; - } - } + 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); + if (channel) { + auto 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); + if (handlers != handlers_map.end()) { + auto& callbacks = handlers->second; + for (auto& handler : callbacks) { + handler->exec(*event); + } + } + } + } else { + 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 (event->handled) { + event_it = events_queue.erase(event_it); + } else { + ++event_it; + } + } } + diff --git a/src/crepe/api/EventManager.h b/src/crepe/api/EventManager.h index 91120fd..be9a947 100644 --- a/src/crepe/api/EventManager.h +++ b/src/crepe/api/EventManager.h @@ -24,12 +24,13 @@ public: void unsubscribe(const EventHandler<EventType> &, int eventId); template <typename EventType> void trigger_event(const EventType & event, int channel); - void queue_event(std::unique_ptr<Event> && event, int channel); + template <typename EventType> + void queue_event(EventType&& event, int channel); void dispatch_events(); private: EventManager() = default; - std::vector<std::pair<std::unique_ptr<Event>, int>> events_queue; + 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; }; @@ -51,6 +52,19 @@ void EventManager::subscribe(EventHandler<EventType> && callback, int channel){ subscribers[event_type].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 + ); + events_queue.push_back(std::move(tuple)); +} template <typename EventType> void EventManager::trigger_event(const EventType & event, int eventId) { @@ -79,7 +93,6 @@ 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::cout << "unsubcribe name: " << handler_name << std::endl; if (channel) { auto subscriber_list = subscribers_by_event_id.find(event_type); @@ -90,7 +103,6 @@ void EventManager::unsubscribe(const EventHandler<EventType> & callback, int cha auto& callbacks = handlers->second; for (auto it = callbacks.begin(); it != callbacks.end(); ++it) { if ((*it)->get_type() == handler_name) { - std::cout << "successfully erased an event" << std::endl; it = callbacks.erase(it); return; } @@ -103,7 +115,6 @@ void EventManager::unsubscribe(const EventHandler<EventType> & callback, int cha auto& handlers = handlers_it->second; for (auto it = handlers.begin(); it != handlers.end(); ++it) { if ((*it)->get_type() == handler_name) { - std::cout << "successfully erased an event" << std::endl; it = handlers.erase(it); return; } diff --git a/src/crepe/api/IKeyListener.cpp b/src/crepe/api/IKeyListener.cpp index f35dc20..663dbc7 100644 --- a/src/crepe/api/IKeyListener.cpp +++ b/src/crepe/api/IKeyListener.cpp @@ -5,27 +5,21 @@ IKeyListener::IKeyListener(){ subscribe_events(0); } IKeyListener::~IKeyListener() { - std::cout << "destructor call" << std::endl; unsubscribe_events(); - } +} void IKeyListener::subscribe_events(int listenerId) { - auto key_pressed_handler = [this](const KeyPressEvent & event) { + key_pressed_handler = [this](const KeyPressEvent & event) { return this->on_key_pressed(event); }; - auto key_released_handler = [this](const KeyReleaseEvent & event) { + key_released_handler = [this](const KeyReleaseEvent & event) { return this->on_key_released(event); }; - std::cout << "IKeyListener subscribe: " << std::endl; - EventManager::get_instance().subscribe<KeyPressEvent>(key_pressed_handler, listenerId); - EventManager::get_instance().subscribe<KeyReleaseEvent>(key_released_handler, listenerId); - std::cout << std::endl; + EventManager::get_instance().subscribe<KeyPressEvent>(std::move(key_pressed_handler), listenerId); + EventManager::get_instance().subscribe<KeyReleaseEvent>(std::move(key_released_handler), listenerId); } void IKeyListener::unsubscribe_events(int listenerId) { - std::cout << "IKeyListener unsubscribe: " << std::endl; - std::cout << "key_pressed_handler name: " << key_pressed_handler.target_type().name() << std::endl; - std::cout << "key_released_handler name: " << key_released_handler.target_type().name() << std::endl; EventManager::get_instance().unsubscribe<KeyPressEvent>(key_pressed_handler , listenerId); EventManager::get_instance().unsubscribe<KeyReleaseEvent>(key_released_handler , listenerId); std::cout << std::endl; diff --git a/src/crepe/api/IMouseListener.cpp b/src/crepe/api/IMouseListener.cpp index 515d801..bb59664 100644 --- a/src/crepe/api/IMouseListener.cpp +++ b/src/crepe/api/IMouseListener.cpp @@ -8,16 +8,16 @@ IMouseListener::~IMouseListener() { void IMouseListener::subscribe_events(int listenerId) { // Define handler lambdas and subscribe them - auto mouse_click_handler = [this](const MouseClickEvent& event) { + mouse_click_handler = [this](const MouseClickEvent& event) { return this->on_mouse_clicked(event); }; - auto mouse_press_handler = [this](const MousePressEvent& event) { + mouse_press_handler = [this](const MousePressEvent& event) { return this->on_mouse_pressed(event); }; - auto mouse_release_handler = [this](const MouseReleaseEvent& event) { + mouse_release_handler = [this](const MouseReleaseEvent& event) { return this->on_mouse_released(event); }; - auto mouse_move_handler = [this](const MouseMoveEvent& event) { + mouse_move_handler = [this](const MouseMoveEvent& event) { return this->on_mouse_moved(event); }; EventManager::get_instance().subscribe<MouseClickEvent>(std::move(mouse_click_handler), listenerId); diff --git a/src/example/events.cpp b/src/example/events.cpp index 53eb97f..1f757e1 100644 --- a/src/example/events.cpp +++ b/src/example/events.cpp @@ -31,19 +31,19 @@ class MyScript : public Script, public IKeyListener,public IMouseListener{ std::cout << "KeyRelease function" << std::endl; return false; } - bool on_mouse_clicked(const MouseClickEvent & event){ + bool on_mouse_clicked(const MouseClickEvent & event) override{ std::cout << "MouseClick function" << std::endl; return false; } - bool on_mouse_pressed(const MousePressEvent & event){ + bool on_mouse_pressed(const MousePressEvent & event) override { std::cout << "MousePress function" << std::endl; return false; } - bool on_mouse_released(const MouseReleaseEvent & event){ + bool on_mouse_released(const MouseReleaseEvent & event) override { std::cout << "MouseRelease function" << std::endl; return false; } - bool on_mouse_moved(const MouseMoveEvent & event){ + bool on_mouse_moved(const MouseMoveEvent & event) override { std::cout << "MouseMove function" << std::endl; return false; } @@ -61,6 +61,17 @@ public: } }; int main() { + // two events to trigger + KeyPressEvent key_press; + key_press.key = 1; + key_press.repeat = 0; + MouseClickEvent click_event; + 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); { // Instantiate TestKeyListener, which subscribes to key events TestKeyListener testListener; @@ -73,32 +84,24 @@ int main() { ScriptSystem sys; sys.update(); - // Trigger some events - KeyPressEvent key_press; - key_press.key = 1; - key_press.repeat = 0; - - MouseClickEvent click_event; - click_event.button = MouseButton::LEFT_MOUSE; - click_event.mouse_x = 100; - click_event.mouse_y = 200; - std::cout << "testing custom listener:" << std::endl; // Trigger the events while `testListener` is in scope EventManager::get_instance().trigger_event<KeyPressEvent>(key_press, 0); EventManager::get_instance().trigger_event<MouseClickEvent>(click_event, 0); - } // End of scope - triggers destruction of obj, MyScript, and `testListener`, unsubscribing from events - // After `testListener` is destroyed, triggering events again should have no output if unsubscription worked - KeyPressEvent key_press; - key_press.key = 1; - key_press.repeat = 0; - EventManager::get_instance().trigger_event<KeyPressEvent>(key_press, 0); + } + // custom lambda event handler + 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); + // - MouseClickEvent click_event; - click_event.button = MouseButton::LEFT_MOUSE; - click_event.mouse_x = 100; - click_event.mouse_y = 200; + EventManager::get_instance().trigger_event<KeyPressEvent>(key_press, 0); + EventManager::get_instance().trigger_event<MouseClickEvent>(click_event, 0); + EventManager::get_instance().dispatch_events(); + EventManager::get_instance().unsubscribe<KeyPressEvent>(event_handler,0); return EXIT_SUCCESS; } |