diff options
Diffstat (limited to 'src/crepe/api')
| -rw-r--r-- | src/crepe/api/Event.h | 68 | ||||
| -rw-r--r-- | src/crepe/api/EventHandler.cpp | 2 | ||||
| -rw-r--r-- | src/crepe/api/EventHandler.h | 38 | ||||
| -rw-r--r-- | src/crepe/api/EventManager.cpp | 69 | ||||
| -rw-r--r-- | src/crepe/api/EventManager.h | 76 | ||||
| -rw-r--r-- | src/crepe/api/IKeyListener.cpp | 20 | ||||
| -rw-r--r-- | src/crepe/api/IKeyListener.h | 20 | ||||
| -rw-r--r-- | src/crepe/api/IMouseListener.cpp | 35 | ||||
| -rw-r--r-- | src/crepe/api/IMouseListener.h | 24 | 
9 files changed, 352 insertions, 0 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; +}; |