aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWBoerenkamps <wrj.boerenkamps@student.avans.nl>2024-11-11 10:50:40 +0100
committerWBoerenkamps <wrj.boerenkamps@student.avans.nl>2024-11-11 10:50:40 +0100
commit880a7b1fb233a67303ad5a4155dc459f79734762 (patch)
tree955faa9c02480f17cb4a674ae9a1b82dab741a63 /src
parent3a690f7d0c91b92b9cdfe62f44dba8db90142abc (diff)
big cleanup events + events are now structs
Diffstat (limited to 'src')
-rw-r--r--src/crepe/api/Event.h68
-rw-r--r--src/crepe/api/EventHandler.cpp2
-rw-r--r--src/crepe/api/EventHandler.h38
-rw-r--r--src/crepe/api/EventManager.cpp69
-rw-r--r--src/crepe/api/EventManager.h76
-rw-r--r--src/crepe/api/IKeyListener.cpp20
-rw-r--r--src/crepe/api/IKeyListener.h20
-rw-r--r--src/crepe/api/IMouseListener.cpp35
-rw-r--r--src/crepe/api/IMouseListener.h24
-rw-r--r--src/makefile12
10 files changed, 362 insertions, 2 deletions
diff --git a/src/crepe/api/Event.h b/src/crepe/api/Event.h
new file mode 100644
index 0000000..8d9b241
--- /dev/null
+++ b/src/crepe/api/Event.h
@@ -0,0 +1,68 @@
+#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,
+};
+class Event {
+public:
+};
+
+class KeyPressEvent : public Event {
+public:
+ int repeat = 0;
+ Keycode key = 0;
+};
+
+class MouseClickEvent : public Event {
+public:
+ int mouse_x = 0;
+ int mouse_y = 0;
+ MouseButton button;
+};
+class KeyReleaseEvent : public Event {
+public:
+ Keycode key = 0;
+};
+
+class MousePressEvent : 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;
+};
+class MouseMoveEvent : public Event {
+public:
+ int mouse_x = 0;
+ int mouse_y = 0;
+};
+class CollisionEvent : public Event{
+public:
+ //Collision collisionData;
+};
+class TextSubmitEvent : public Event{
+public:
+ std::string text;
+};
+class ShutDownEvent : public Event {
+public:
+};
diff --git a/src/crepe/api/EventHandler.cpp b/src/crepe/api/EventHandler.cpp
new file mode 100644
index 0000000..93a116a
--- /dev/null
+++ b/src/crepe/api/EventHandler.cpp
@@ -0,0 +1,2 @@
+#include "EventHandler.h"
+bool IEventHandlerWrapper::exec(const Event & e) { return call(e); }
diff --git a/src/crepe/api/EventHandler.h b/src/crepe/api/EventHandler.h
new file mode 100644
index 0000000..eea1c79
--- /dev/null
+++ b/src/crepe/api/EventHandler.h
@@ -0,0 +1,38 @@
+#pragma once
+#include <functional>
+#include <iostream>
+#include <typeindex>
+#include "Event.h"
+
+template <typename EventType>
+using EventHandler = std::function<bool(const EventType & e)>;
+
+class IEventHandlerWrapper {
+public:
+ virtual ~IEventHandlerWrapper() = default;
+
+ bool exec(const Event & e);
+
+ virtual std::string get_type() const = 0;
+
+private:
+ virtual bool call(const Event & e) = 0;
+};
+
+template <typename EventType>
+class EventHandlerWrapper : public IEventHandlerWrapper {
+public:
+ explicit EventHandlerWrapper(const EventHandler<EventType> & handler)
+ : m_handler(handler), m_handler_type(m_handler.target_type().name()) {
+ }
+
+private:
+ bool call(const Event & e) override {
+ return m_handler(static_cast<const EventType &>(e));
+ }
+
+ std::string get_type() const override { return m_handler_type; }
+
+ EventHandler<EventType> m_handler;
+ const std::string m_handler_type;
+};
diff --git a/src/crepe/api/EventManager.cpp b/src/crepe/api/EventManager.cpp
new file mode 100644
index 0000000..07ef1f7
--- /dev/null
+++ b/src/crepe/api/EventManager.cpp
@@ -0,0 +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::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;
+ // }
+ // }
+}
diff --git a/src/crepe/api/EventManager.h b/src/crepe/api/EventManager.h
new file mode 100644
index 0000000..8c0685a
--- /dev/null
+++ b/src/crepe/api/EventManager.h
@@ -0,0 +1,76 @@
+#pragma once
+#include <memory>
+#include <unordered_map>
+#include <vector>
+#include <functional>
+#include <iostream>
+#include <typeindex>
+#include <type_traits>
+#include "Event.h"
+#include "EventHandler.h"
+//#include "keyCodes.h"
+
+class EventManager {
+public:
+ EventManager(const EventManager &) = delete;
+ const EventManager & operator=(const EventManager &) = delete;
+ static EventManager & get_instance() {
+ static EventManager instance;
+ return instance;
+ }
+ template <typename EventType>
+ void subscribe(EventHandler<EventType> && callback, int channel = 0);
+ void unsubscribe(std::type_index eventType, const std::string & handlerName,int channel);
+ template <typename EventType>
+ void trigger_event(const EventType & event, int channel);
+ void queue_event(std::unique_ptr<Event> && event, int channel);
+ void dispatch_events();
+
+private:
+ EventManager() = default;
+ std::vector<std::pair<std::unique_ptr<Event>, int>> 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;
+};
+
+template <typename EventType>
+void EventManager::subscribe(EventHandler<EventType> && callback, int channel){
+ std::type_index event_type = typeid(EventType);
+ auto handler = std::make_unique<EventHandlerWrapper<EventType>>(callback);
+
+ if (channel) {
+ auto & handlers_map = subscribers_by_event_id[event_type];
+ auto handlers = handlers_map.find(channel);
+ if (handlers != handlers_map.end()) {
+ handlers->second.emplace_back(std::move(handler));
+ } else {
+ handlers_map[channel].emplace_back(std::move(handler));
+ }
+ } else {
+ subscribers[event_type].emplace_back(std::move(handler));
+ }
+}
+
+template <typename EventType>
+void EventManager::trigger_event(const EventType & event, int eventId) {
+ std::type_index event_type = std::type_index(typeid(EventType));
+
+ if (eventId > 0) {
+ auto handlers_it = subscribers_by_event_id[event_type].find(eventId);
+ if (handlers_it != subscribers_by_event_id[event_type].end()) {
+ auto & callbacks = handlers_it->second;
+ for (auto it = callbacks.begin(); it != callbacks.end();) {
+ if ((*it)->exec(event)) {
+ it = callbacks.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
+ } else {
+ auto & handlers = subscribers[event_type];
+ for (auto & handler : handlers) {
+ handler->exec(event);
+ }
+ }
+}
diff --git a/src/crepe/api/IKeyListener.cpp b/src/crepe/api/IKeyListener.cpp
new file mode 100644
index 0000000..b1ad5e5
--- /dev/null
+++ b/src/crepe/api/IKeyListener.cpp
@@ -0,0 +1,20 @@
+#include "IKeyListener.h"
+
+IKeyListener::~IKeyListener() { unsubscribe_events(); }
+
+void IKeyListener::subscribe_events(int listenerId) {
+ auto key_pressed_handler = [this](const KeyPressEvent & event) {
+ return this->on_key_pressed(event);
+ };
+ 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);
+}
+
+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);
+}
diff --git a/src/crepe/api/IKeyListener.h b/src/crepe/api/IKeyListener.h
new file mode 100644
index 0000000..4fd2238
--- /dev/null
+++ b/src/crepe/api/IKeyListener.h
@@ -0,0 +1,20 @@
+#pragma once
+#include "Event.h"
+#include "EventHandler.h"
+#include "EventManager.h"
+class IKeyListener {
+public:
+ virtual ~IKeyListener();
+ virtual bool on_key_pressed(const KeyPressEvent & event) = 0;
+ virtual bool on_key_released(const KeyReleaseEvent & event) = 0;
+
+protected:
+ void subscribe_events(int listenerId = 0);
+ void unsubscribe_events(int listenerId = 0);
+ void activate(int listenerId = 0) { subscribe_events(listenerId); }
+ void deactivate(int listenerId = 0) { unsubscribe_events(listenerId); }
+
+private:
+ EventHandler<KeyPressEvent> key_pressed_handler;
+ EventHandler<KeyReleaseEvent> key_released_handler;
+};
diff --git a/src/crepe/api/IMouseListener.cpp b/src/crepe/api/IMouseListener.cpp
new file mode 100644
index 0000000..043188c
--- /dev/null
+++ b/src/crepe/api/IMouseListener.cpp
@@ -0,0 +1,35 @@
+#include "IMouseListener.h"
+
+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) {
+ 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);
+ };
+
+ // 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);
+ EventManager::get_instance().subscribe<MouseMoveEvent>(std::move(mouse_move_handler), 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);
+}
diff --git a/src/crepe/api/IMouseListener.h b/src/crepe/api/IMouseListener.h
new file mode 100644
index 0000000..9222905
--- /dev/null
+++ b/src/crepe/api/IMouseListener.h
@@ -0,0 +1,24 @@
+#pragma once
+#include "Event.h"
+#include "EventHandler.h"
+#include "EventManager.h"
+
+class IMouseListener {
+public:
+ 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;
+
+protected:
+ void subscribe_events(int listenerId = 0);
+ void unsubscribe_events(int listenerId = 0);
+
+private:
+ EventHandler<MouseClickEvent> mouse_click_handler;
+ EventHandler<MousePressEvent> mouse_press_handler;
+ EventHandler<MouseReleaseEvent> mouse_release_handler;
+ EventHandler<MouseMoveEvent> mouse_move_handler;
+};
diff --git a/src/makefile b/src/makefile
index b9c44c8..03a2c0e 100644
--- a/src/makefile
+++ b/src/makefile
@@ -94,8 +94,16 @@ LOEK += example/script.cpp
LOEK += test/audio.cpp
LOEK += test/dummy.cpp
JARO += test/PhysicsTest.cpp
-
-FMT := $(JARO) #<<< CHANGE THIS TO YOUR NAME FOR STEP 2
+WOUTER += crepe/api/Event.h
+WOUTER += crepe/api/EventHandler.cpp
+WOUTER += crepe/api/EventHandler.h
+WOUTER += crepe/api/EventManager.cpp
+WOUTER += crepe/api/EventManager.h
+WOUTER += crepe/api/IKeyListener.cpp
+WOUTER += crepe/api/IKeyListener.h
+WOUTER += crepe/api/IMouseListener.cpp
+WOUTER += crepe/api/IMouseListener.h
+FMT := $(WOUTER) #<<< CHANGE THIS TO YOUR NAME FOR STEP 2
format: FORCE
clang-tidy -p build/compile_commands.json --fix-errors $(FMT)