aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWBoerenkamps <wrj.boerenkamps@student.avans.nl>2024-11-11 16:12:09 +0100
committerWBoerenkamps <wrj.boerenkamps@student.avans.nl>2024-11-11 16:12:09 +0100
commit80c74b90a3e44e25a4fa9fdd25bf0aa9efbaf6fd (patch)
tree1ac04e3434c8e775318b6f8519c6674bb2a3298d /src
parent880a7b1fb233a67303ad5a4155dc459f79734762 (diff)
interfaces working but unsubscribe broken
Diffstat (limited to 'src')
-rw-r--r--src/crepe/api/CMakeLists.txt9
-rw-r--r--src/crepe/api/EventHandler.h1
-rw-r--r--src/crepe/api/EventManager.cpp120
-rw-r--r--src/crepe/api/EventManager.h39
-rw-r--r--src/crepe/api/IKeyListener.cpp26
-rw-r--r--src/crepe/api/IKeyListener.h1
-rw-r--r--src/crepe/api/IMouseListener.cpp25
-rw-r--r--src/crepe/api/IMouseListener.h1
-rw-r--r--src/example/CMakeLists.txt2
-rw-r--r--src/example/events.cpp105
10 files changed, 247 insertions, 82 deletions
diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt
index 87cbb09..4e8f8a0 100644
--- a/src/crepe/api/CMakeLists.txt
+++ b/src/crepe/api/CMakeLists.txt
@@ -18,6 +18,10 @@ target_sources(crepe PUBLIC
Vector2.cpp
Camera.cpp
Animator.cpp
+ EventManager.cpp
+ EventHandler.cpp
+ IKeyListener.cpp
+ IMouseListener.cpp
)
target_sources(crepe PUBLIC FILE_SET HEADERS FILES
@@ -42,4 +46,9 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES
SceneManager.hpp
Camera.h
Animator.h
+ EventManager.h
+ EventHandler.h
+ Event.h
+ IKeyListener.h
+ IMouseListener.h
)
diff --git a/src/crepe/api/EventHandler.h b/src/crepe/api/EventHandler.h
index eea1c79..0da6d7d 100644
--- a/src/crepe/api/EventHandler.h
+++ b/src/crepe/api/EventHandler.h
@@ -24,6 +24,7 @@ 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 07ef1f7..7a8be53 100644
--- a/src/crepe/api/EventManager.cpp
+++ b/src/crepe/api/EventManager.cpp
@@ -1,69 +1,69 @@
#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()->getType() == 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()->getType() == handlerName) {
- // it = handlers.erase(it);
- // return;
- // }
- // }
- // }
- // }
-}
+// 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 eventIt
- // = eventsQueue.begin();
- // eventIt != eventsQueue.end();) {
- // bool handled = false;
- // if (!handled) {
- // triggerEvent(*eventIt->first.get(), eventIt->second);
- // eventIt = eventsQueue.erase(eventIt);
- // } else {
- // ++eventIt;
- // }
- // }
+ 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;
+ }
+ }
}
diff --git a/src/crepe/api/EventManager.h b/src/crepe/api/EventManager.h
index 8c0685a..88a386a 100644
--- a/src/crepe/api/EventManager.h
+++ b/src/crepe/api/EventManager.h
@@ -20,7 +20,8 @@ public:
}
template <typename EventType>
void subscribe(EventHandler<EventType> && callback, int channel = 0);
- void unsubscribe(std::type_index eventType, const std::string & handlerName,int channel);
+ template <typename EventType>
+ 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);
@@ -74,3 +75,39 @@ void EventManager::trigger_event(const EventType & event, int eventId) {
}
}
}
+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());
+ std::cout << "unsubcribe name: " << handler_name << std::endl;
+
+ if (channel) {
+ auto 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);
+ if (handlers != handlers_map.end()) {
+ 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;
+ }
+ }
+ }
+ }
+ } else {
+ auto 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) {
+ 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 b1ad5e5..f35dc20 100644
--- a/src/crepe/api/IKeyListener.cpp
+++ b/src/crepe/api/IKeyListener.cpp
@@ -1,6 +1,13 @@
#include "IKeyListener.h"
-
-IKeyListener::~IKeyListener() { unsubscribe_events(); }
+#include <iostream>
+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) {
@@ -9,12 +16,17 @@ void IKeyListener::subscribe_events(int listenerId) {
auto key_released_handler = [this](const KeyReleaseEvent & event) {
return this->on_key_released(event);
};
-
- EventManager::get_instance().subscribe<KeyPressEvent>(std::move(key_pressed_handler), listenerId);
- EventManager::get_instance().subscribe<KeyReleaseEvent>(std::move(key_released_handler), listenerId);
+ 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;
}
void IKeyListener::unsubscribe_events(int listenerId) {
- EventManager::get_instance().unsubscribe(std::type_index(typeid(KeyPressEvent)), "on_key_pressed", listenerId);
- EventManager::get_instance().unsubscribe(std::type_index(typeid(KeyReleaseEvent)), "on_key_released", 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/IKeyListener.h b/src/crepe/api/IKeyListener.h
index 4fd2238..fc8de16 100644
--- a/src/crepe/api/IKeyListener.h
+++ b/src/crepe/api/IKeyListener.h
@@ -4,6 +4,7 @@
#include "EventManager.h"
class IKeyListener {
public:
+ IKeyListener();
virtual ~IKeyListener();
virtual bool on_key_pressed(const KeyPressEvent & event) = 0;
virtual bool on_key_released(const KeyReleaseEvent & event) = 0;
diff --git a/src/crepe/api/IMouseListener.cpp b/src/crepe/api/IMouseListener.cpp
index 043188c..515d801 100644
--- a/src/crepe/api/IMouseListener.cpp
+++ b/src/crepe/api/IMouseListener.cpp
@@ -1,25 +1,25 @@
#include "IMouseListener.h"
-
+IMouseListener::IMouseListener(){
+ subscribe_events();
+}
IMouseListener::~IMouseListener() {
unsubscribe_events();
}
void IMouseListener::subscribe_events(int listenerId) {
- // Wrap member functions in lambdas to ensure correct function signatures
- mouse_click_handler = [this](const MouseClickEvent & event) {
+ // Define handler lambdas and subscribe them
+ auto mouse_click_handler = [this](const MouseClickEvent& event) {
return this->on_mouse_clicked(event);
};
- mouse_press_handler = [this](const MousePressEvent & event) {
+ auto mouse_press_handler = [this](const MousePressEvent& event) {
return this->on_mouse_pressed(event);
};
- mouse_release_handler = [this](const MouseReleaseEvent & event) {
+ auto mouse_release_handler = [this](const MouseReleaseEvent& event) {
return this->on_mouse_released(event);
};
- mouse_move_handler = [this](const MouseMoveEvent & event) {
+ auto mouse_move_handler = [this](const MouseMoveEvent& event) {
return this->on_mouse_moved(event);
};
-
- // Use EventManager for subscribing
EventManager::get_instance().subscribe<MouseClickEvent>(std::move(mouse_click_handler), listenerId);
EventManager::get_instance().subscribe<MousePressEvent>(std::move(mouse_press_handler), listenerId);
EventManager::get_instance().subscribe<MouseReleaseEvent>(std::move(mouse_release_handler), listenerId);
@@ -27,9 +27,8 @@ void IMouseListener::subscribe_events(int listenerId) {
}
void IMouseListener::unsubscribe_events(int listenerId) {
- // Use EventManager for unsubscribing with correct event type names
- EventManager::get_instance().unsubscribe(std::type_index(typeid(MouseClickEvent)), "onMouseClicked", listenerId);
- EventManager::get_instance().unsubscribe(std::type_index(typeid(MousePressEvent)), "onMousePressed", listenerId);
- EventManager::get_instance().unsubscribe(std::type_index(typeid(MouseReleaseEvent)), "onMouseReleased", listenerId);
- EventManager::get_instance().unsubscribe(std::type_index(typeid(MouseMoveEvent)), "onMouseMoved", listenerId);
+ EventManager::get_instance().unsubscribe<MouseClickEvent>(mouse_click_handler, listenerId);
+ EventManager::get_instance().unsubscribe<MousePressEvent>(mouse_press_handler, listenerId);
+ EventManager::get_instance().unsubscribe<MouseReleaseEvent>(mouse_release_handler, listenerId);
+ EventManager::get_instance().unsubscribe<MouseMoveEvent>(mouse_move_handler, listenerId);
}
diff --git a/src/crepe/api/IMouseListener.h b/src/crepe/api/IMouseListener.h
index 9222905..1078257 100644
--- a/src/crepe/api/IMouseListener.h
+++ b/src/crepe/api/IMouseListener.h
@@ -5,6 +5,7 @@
class IMouseListener {
public:
+ IMouseListener();
virtual ~IMouseListener();
virtual bool on_mouse_clicked(const MouseClickEvent & event) = 0;
diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt
index 36f9d4d..da6ceba 100644
--- a/src/example/CMakeLists.txt
+++ b/src/example/CMakeLists.txt
@@ -28,4 +28,4 @@ add_example(proxy)
add_example(db)
add_example(ecs)
add_example(scene_manager)
-
+add_example(events)
diff --git a/src/example/events.cpp b/src/example/events.cpp
new file mode 100644
index 0000000..53eb97f
--- /dev/null
+++ b/src/example/events.cpp
@@ -0,0 +1,105 @@
+#include <iostream>
+
+#include <crepe/ComponentManager.h>
+#include <crepe/system/ScriptSystem.h>
+#include <crepe/util/log.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"
+using namespace crepe;
+using namespace std;
+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{
+ std::cout << "KeyPressed function" << std::endl;
+ return false;
+ }
+ bool on_key_released(const KeyReleaseEvent & event) override{
+ std::cout << "KeyRelease function" << std::endl;
+ return false;
+ }
+ bool on_mouse_clicked(const MouseClickEvent & event){
+ std::cout << "MouseClick function" << std::endl;
+ return false;
+ }
+ bool on_mouse_pressed(const MousePressEvent & event){
+ std::cout << "MousePress function" << std::endl;
+ return false;
+ }
+ bool on_mouse_released(const MouseReleaseEvent & event){
+ std::cout << "MouseRelease function" << std::endl;
+ return false;
+ }
+ bool on_mouse_moved(const MouseMoveEvent & event){
+ 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;
+ }
+};
+int main() {
+ {
+ // 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<BehaviorScript>().set_script<MyScript>();
+
+ // Get ScriptSystem singleton instance (this would normally be done from the game loop)
+ 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);
+
+ MouseClickEvent click_event;
+ click_event.button = MouseButton::LEFT_MOUSE;
+ click_event.mouse_x = 100;
+ click_event.mouse_y = 200;
+ EventManager::get_instance().trigger_event<MouseClickEvent>(click_event, 0);
+
+ return EXIT_SUCCESS;
+}
+
+