diff options
| author | WBoerenkamps <wrj.boerenkamps@student.avans.nl> | 2024-11-20 20:24:17 +0100 | 
|---|---|---|
| committer | WBoerenkamps <wrj.boerenkamps@student.avans.nl> | 2024-11-20 20:24:17 +0100 | 
| commit | 397da65e03ec681922aeea3881918026d36068a7 (patch) | |
| tree | dca704ae1ad3241e0c559e9037c300ccede8a437 /src | |
| parent | 9f882131f09410113d757d96e5aa0322aa5584bd (diff) | |
result of loeks temper tantrum
Diffstat (limited to 'src')
| -rw-r--r-- | src/crepe/api/EventHandler.h | 23 | ||||
| -rw-r--r-- | src/crepe/api/EventHandler.hpp | 9 | ||||
| -rw-r--r-- | src/crepe/api/EventManager.cpp | 42 | ||||
| -rw-r--r-- | src/crepe/api/EventManager.h | 158 | ||||
| -rw-r--r-- | src/crepe/api/EventManager.hpp | 38 | ||||
| -rw-r--r-- | src/crepe/api/IKeyListener.cpp | 26 | ||||
| -rw-r--r-- | src/crepe/api/IKeyListener.h | 26 | ||||
| -rw-r--r-- | src/crepe/api/IMouseListener.cpp | 47 | ||||
| -rw-r--r-- | src/crepe/api/IMouseListener.h | 34 | ||||
| -rw-r--r-- | src/example/events.cpp | 120 | ||||
| -rw-r--r-- | src/test/EventTest.cpp | 118 | 
11 files changed, 198 insertions, 443 deletions
diff --git a/src/crepe/api/EventHandler.h b/src/crepe/api/EventHandler.h index 90886aa..ef659fd 100644 --- a/src/crepe/api/EventHandler.h +++ b/src/crepe/api/EventHandler.h @@ -24,7 +24,7 @@ using EventHandler = std::function<bool(const EventType & e)>;   * \brief An abstract base class for event handler wrappers.   *    * This class provides the interface for handling events. Derived classes must implement the - * `call()` method to process events and the `get_type()` method to return the handler's type. + * `call()` method to process events   */  class IEventHandlerWrapper {  public: @@ -43,15 +43,6 @@ public:       */  	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; -  private:  	/**       * \brief The method responsible for handling the event. @@ -96,20 +87,8 @@ private:       * \return A boolean value indicating whether the event is handled.       */  	bool call(const Event & e) override; - -	/** -     * \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; -  	//! The event handler function.  	EventHandler<EventType> handler; -	//! The type name of the handler function. -	const std::string handler_type;  };  } // namespace crepe diff --git a/src/crepe/api/EventHandler.hpp b/src/crepe/api/EventHandler.hpp index a1e774d..8d8136b 100644 --- a/src/crepe/api/EventHandler.hpp +++ b/src/crepe/api/EventHandler.hpp @@ -1,4 +1,3 @@ -  #include <typeindex>  #include "EventHandler.h" @@ -8,8 +7,7 @@ namespace crepe {  // Implementation of EventHandlerWrapper constructor  template <typename EventType>  EventHandlerWrapper<EventType>::EventHandlerWrapper(const EventHandler<EventType> & handler) -	: handler(handler), -	  handler_type(handler.target_type().name()) {} +	: handler(handler){}  // Implementation of EventHandlerWrapper::call  template <typename EventType> @@ -17,10 +15,5 @@ bool EventHandlerWrapper<EventType>::call(const Event & e) {  	return this->handler(static_cast<const EventType &>(e));  } -// Implementation of EventHandlerWrapper::get_type -template <typename EventType> -std::string EventHandlerWrapper<EventType>::get_type() const { -	return this->handler_type; -}  } //namespace crepe diff --git a/src/crepe/api/EventManager.cpp b/src/crepe/api/EventManager.cpp index dbdb0c3..64d7c26 100644 --- a/src/crepe/api/EventManager.cpp +++ b/src/crepe/api/EventManager.cpp @@ -15,22 +15,18 @@ void EventManager::dispatch_events() {  		bool event_handled = false;  		auto handlers_it = this->subscribers.find(event_type); -		if (handlers_it != this->subscribers.end()) { -			std::vector<CallbackEntry> & handlers = handlers_it->second; - -			std::sort(handlers.begin(), handlers.end(), -					  [](const CallbackEntry & a, const CallbackEntry & b) { -						  return a.priority > b.priority; -					  }); - -			for (auto handler_it = handlers.begin(); handler_it != handlers.end(); -				 ++handler_it) { -				// If callback is executed and returns true, remove the event from the queue -				if ((*handler_it).callback->exec(*event)) { -					event_it = this->events_queue.erase(event_it); -					event_handled = true; -					break; -				} +		if (handlers_it == this->subscribers.end()) { +			continue; +		} +		std::vector<CallbackEntry> & handlers = handlers_it->second; + +		for (auto handler_it = handlers.begin(); handler_it != handlers.end(); +				++handler_it) { +			// If callback is executed and returns true, remove the event from the queue +			if ((*handler_it).callback->exec(*event)) { +				event_it = this->events_queue.erase(event_it); +				event_handled = true; +				break;  			}  		} @@ -44,3 +40,17 @@ void EventManager::clear() {  	this->subscribers.clear();  	this->events_queue.clear();  } + +void EventManager::unsubscribe(subscription_t event_id) { +    for (auto& [event_type, handlers] : this->subscribers) { +        for (auto it = handlers.begin(); it != handlers.end();) { +            if (it->id == event_id) { +                it = handlers.erase(it); +                return; +            } else { +                ++it; +            } +        } +    } +} + diff --git a/src/crepe/api/EventManager.h b/src/crepe/api/EventManager.h index 133d72d..93e9ca2 100644 --- a/src/crepe/api/EventManager.h +++ b/src/crepe/api/EventManager.h @@ -11,109 +11,131 @@  #include "EventHandler.h"  namespace crepe { -static constexpr int CHANNEL_ALL = -1; +//! typedef for subscription value +typedef int subscription_t; +  /**   * \class EventManager - * \brief The EventManager class is responsible for managing the subscription, triggering,  - * and queueing of events. It handles events and dispatches them to appropriate subscribers. + * \brief Manages event subscriptions, triggers, and queues, enabling decoupled event handling. + *  + * The `EventManager` acts as a centralized event system. It allows for registering callbacks + * for specific event types, triggering events synchronously, queueing events for later + * processing, and managing subscriptions via unique identifiers.   */  class EventManager {  public: +	static constexpr int CHANNEL_ALL = -1; +  	/** -     * \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. -     */ +	 * \brief Get the singleton instance of the EventManager. +	 *  +	 * This method returns the unique instance of the EventManager, creating it if it +	 * doesn't already exist. Ensures only one instance is active in the program. +	 *  +	 * \return Reference to the singleton instance of the EventManager. +	 */  	static EventManager & get_instance();  	/** -     * \brief Subscribe to an event. -     *  -     * This method allows the registration of a callback for a specific event type and channel. -     *  -     * \tparam EventType The type of the event to subscribe to. -     * \param callback The callback function to invoke when the event is triggered. -     * \param channel The channel number to subscribe to (default is 0). -     */ +	 * \brief Subscribe to a specific event type. +	 *  +	 * Registers a callback for a given event type and optional channel. Each callback +	 * is assigned a unique subscription ID that can be used for later unsubscription. +	 *  +	 * \tparam EventType The type of the event to subscribe to. +	 * \param callback The callback function to be invoked when the event is triggered. +	 * \param channel The channel number to subscribe to (default is CHANNEL_ALL, which listens to all channels). +	 * \return A unique subscription ID associated with the registered callback. +	 */  	template <typename EventType> -	void subscribe(const EventHandler<EventType> & callback, int channel = CHANNEL_ALL, -				   int priority = 0); +	subscription_t subscribe(const EventHandler<EventType> & callback, int channel = CHANNEL_ALL);  	/** -     * \brief Unsubscribe from an event. -     *  -     * This method removes a previously registered callback from an event. -     *  -     * \tparam EventType The type of the event to unsubscribe from. -     * \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 = CHANNEL_ALL); +	 * \brief Unsubscribe a previously registered callback. +	 *  +	 * Removes a callback from the subscription list based on its unique subscription ID. +	 *  +	 * \param event_id The unique subscription ID of the callback to remove. +	 */ +	void unsubscribe(subscription_t event_id);  	/** -     * \brief Trigger an event. -     *  -     * This method invokes the appropriate callback(s) for the specified event. -     *  -     * \tparam EventType The type of the event to trigger. -     * \param event The event data to pass to the callback. -     * \param channel The channel from which to trigger the event (default is 0). -     */ +	 * \brief Trigger an event immediately. +	 *  +	 * Synchronously invokes all registered callbacks for the given event type on the specified channel. +	 *  +	 * \tparam EventType The type of the event to trigger. +	 * \param event The event instance to pass to the callbacks. +	 * \param channel The channel to trigger the event on (default is CHANNEL_ALL, which triggers on all channels). +	 */  	template <typename EventType>  	void trigger_event(const EventType & event, int channel = CHANNEL_ALL);  	/** -     * \brief Queue an event for later processing. -     *  -     * This method adds an event to the event queue, which will be processed in the  -     * dispatch_events function. -     *  -     * \tparam EventType The type of the event to queue. -     * \param event The event to queue. -     * \param channel The channel number for the event (default is 0). -     */ +	 * \brief Queue an event for later processing. +	 *  +	 * Adds an event to the event queue to be processed during the next call to `dispatch_events`. +	 *  +	 * \tparam EventType The type of the event to queue. +	 * \param event The event instance to queue. +	 * \param channel The channel to associate with the event (default is CHANNEL_ALL). +	 */  	template <typename EventType> -	void queue_event(const EventType & event, int channel = CHANNEL_ALL, int priority = 0); +	void queue_event(const EventType & event, int channel = CHANNEL_ALL);  	/** -     * \brief Dispatch all queued events. -     *  -     * This method processes all events in the event queue and triggers the corresponding  -     * callbacks for each event. -     */ +	 * \brief Process all queued events. +	 *  +	 * Iterates through the event queue and triggers callbacks for each queued event. +	 * Events are removed from the queue once processed. +	 */  	void dispatch_events(); +  	/** -     * \brief clears all subscribers -     *  -     */ +	 * \brief Clear all subscriptions. +	 *  +	 * Removes all registered event handlers and clears the subscription list. +	 */  	void clear();  private:  	/** -     * \brief Default constructor for the EventManager. -     *  -     * This constructor is private to enforce the singleton pattern. -     */ +	 * \brief Default constructor for the EventManager. +	 *  +	 * Constructor is private to enforce the singleton pattern. +	 */  	EventManager() = default; + +	/** +	 * \struct QueueEntry +	 * \brief Represents an entry in the event queue. +	 */  	struct QueueEntry { -		std::unique_ptr<Event> event; -		int channel = CHANNEL_ALL; -		std::type_index type; -		int priority = 0; +		std::unique_ptr<Event> event; ///< The event instance. +		int channel = CHANNEL_ALL;    ///< The channel associated with the event. +		std::type_index type;         ///< The type of the event.  	}; + +	/** +	 * \struct CallbackEntry +	 * \brief Represents a registered event handler callback. +	 */  	struct CallbackEntry { -		std::unique_ptr<IEventHandlerWrapper> callback; -		int channel = CHANNEL_ALL; -		int priority = 0; +		std::unique_ptr<IEventHandlerWrapper> callback; ///< The callback function wrapper. +		int channel = CHANNEL_ALL;                      ///< The channel this callback listens to. +		subscription_t id = -1;                         ///< Unique subscription ID.  	}; -	//! The queue of events to be processed. + +	//! The queue of events to be processed during dispatch.  	std::vector<QueueEntry> events_queue; -	//! Registered event handlers. + +	//! A map of event type to registered callbacks.  	std::unordered_map<std::type_index, std::vector<CallbackEntry>> subscribers; + +	//! Counter to generate unique subscription IDs. +	subscription_t subscription_counter = 0;  };  } // namespace crepe +  #include "EventManager.hpp" diff --git a/src/crepe/api/EventManager.hpp b/src/crepe/api/EventManager.hpp index a04a43a..d7afa9f 100644 --- a/src/crepe/api/EventManager.hpp +++ b/src/crepe/api/EventManager.hpp @@ -3,9 +3,8 @@  namespace crepe {  template <typename EventType> -void EventManager::subscribe(const EventHandler<EventType> & callback, int channel, -							 int priority) { - +subscription_t EventManager::subscribe(const EventHandler<EventType> & callback, int channel) { +	subscription_counter++;  	std::type_index event_type = typeid(EventType);  	std::unique_ptr<EventHandlerWrapper<EventType>> handler  		= std::make_unique<EventHandlerWrapper<EventType>>(callback); @@ -13,17 +12,13 @@ void EventManager::subscribe(const EventHandler<EventType> & callback, int chann  	handlers.emplace_back(CallbackEntry{  		.callback = std::move(handler),  		.channel = channel, -		.priority = priority, +		.id = subscription_counter  	}); -	// Sort handlers by priority (highest first) -	std::sort(handlers.begin(), handlers.end(), -			  [](const CallbackEntry & a, const CallbackEntry & b) { -				  return a.priority > b.priority; -			  }); +	return subscription_counter;  }  template <typename EventType> -void EventManager::queue_event(const EventType & event, int channel, int priority) { +void EventManager::queue_event(const EventType & event, int channel) {  	static_assert(std::is_base_of<Event, EventType>::value,  				  "EventType must derive from Event");  	std::type_index event_type = typeid(EventType); @@ -32,8 +27,7 @@ void EventManager::queue_event(const EventType & event, int channel, int priorit  	this->events_queue.push_back(QueueEntry{.event = std::move(event_ptr),  											.channel = channel, -											.type = event_type, -											.priority = priority}); +											.type = event_type});  }  template <typename EventType> @@ -55,25 +49,5 @@ void EventManager::trigger_event(const EventType & event, int channel) {  	}  } -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(); - -	// Find the list of handlers for this event type -	auto handlers_it = this->subscribers.find(event_type); -	if (handlers_it != this->subscribers.end()) { -		std::vector<CallbackEntry> & handlers = handlers_it->second; - -		for (auto it = handlers.begin(); it != handlers.end();) { -			// Match based on handler type and channel -			if (it->callback->get_type() == handler_name && it->channel == channel) { -				it = handlers.erase(it); -				return; -			} -			++it; -		} -	} -}  } // namespace crepe diff --git a/src/crepe/api/IKeyListener.cpp b/src/crepe/api/IKeyListener.cpp index 6a522c1..ebbf486 100644 --- a/src/crepe/api/IKeyListener.cpp +++ b/src/crepe/api/IKeyListener.cpp @@ -3,29 +3,15 @@  using namespace crepe;  // Constructor with specified channel -IKeyListener::IKeyListener(int channel) -	: channel(channel), -	  active(true), +IKeyListener::IKeyListener(int channel) :  	  event_manager(EventManager::get_instance()) { -	this->subscribe_events(); +	press_id = event_manager.subscribe<KeyPressEvent>([this](const KeyPressEvent & event) { return this->on_key_pressed(event); }, channel); +	release_id = event_manager.subscribe<KeyReleaseEvent>([this](const KeyReleaseEvent & event) { return this->on_key_released(event); }, channel);  }  // Destructor, unsubscribe events -IKeyListener::~IKeyListener() { this->unsubscribe_events(); } - -// Subscribe to key 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); }; - -	event_manager.subscribe<KeyPressEvent>(this->key_pressed_handler, this->channel); -	event_manager.subscribe<KeyReleaseEvent>(this->key_released_handler, this->channel); +IKeyListener::~IKeyListener() {  +	event_manager.unsubscribe(press_id); +	event_manager.unsubscribe(release_id);  } -// Unsubscribe from key events -void IKeyListener::unsubscribe_events() { -	event_manager.unsubscribe<KeyPressEvent>(this->key_pressed_handler, this->channel); -	event_manager.unsubscribe<KeyReleaseEvent>(this->key_released_handler, this->channel); -} diff --git a/src/crepe/api/IKeyListener.h b/src/crepe/api/IKeyListener.h index 9402cce..4726aa7 100644 --- a/src/crepe/api/IKeyListener.h +++ b/src/crepe/api/IKeyListener.h @@ -16,7 +16,7 @@ public:       * \brief Constructs an IKeyListener with a specified channel.       * \param channel The channel ID for event handling.       */ -	IKeyListener(int channel = CHANNEL_ALL); +	IKeyListener(int channel = EventManager::CHANNEL_ALL);  	virtual ~IKeyListener();  	IKeyListener(const IKeyListener &) = delete;  	IKeyListener & operator=(const IKeyListener &) = delete; @@ -36,27 +36,11 @@ public:       * \return True if the event was handled, false otherwise.       */  	virtual bool on_key_released(const KeyReleaseEvent & event) = 0; - -protected: -	/** -     * \brief Subscribes to key events. -     */ -	void subscribe_events(); - -	/** -     * \brief Unsubscribes from key events. -     */ -	void unsubscribe_events(); -  private: -	//! Indicates whether key listening is active. -	bool active = true; -	//! Channel ID for event handling. -	int channel = 0; -	//! Key press event handler. -	EventHandler<KeyPressEvent> key_pressed_handler; -	//!< Key release event handler. -	EventHandler<KeyReleaseEvent> key_released_handler; +	//! Key press event id +	subscription_t press_id = -1; +	//!< Key release event id +	subscription_t release_id = -1;  	EventManager & event_manager;  }; diff --git a/src/crepe/api/IMouseListener.cpp b/src/crepe/api/IMouseListener.cpp index f3ceb84..a6cb163 100644 --- a/src/crepe/api/IMouseListener.cpp +++ b/src/crepe/api/IMouseListener.cpp @@ -3,35 +3,28 @@  using namespace crepe;  IMouseListener::IMouseListener(int channel) -	: event_manager(EventManager::get_instance()), -	  channel(channel) { -	this->subscribe_events(); -} +	: event_manager(EventManager::get_instance()) { +	click_id =  event_manager.subscribe<MouseClickEvent>( +		[this](const MouseClickEvent & event) { return this->on_mouse_clicked(event); }, +		channel); -IMouseListener::~IMouseListener() { this->unsubscribe_events(); } +	press_id = event_manager.subscribe<MousePressEvent>( +		[this](const MousePressEvent & event) { return this->on_mouse_pressed(event); }, +		channel); -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); }; +	release_id = event_manager.subscribe<MouseReleaseEvent>( +		[this](const MouseReleaseEvent & event) { return this->on_mouse_released(event); }, +		channel); -	// Subscribe event handlers (no need for std::move) -	event_manager.subscribe<MouseClickEvent>(mouse_click_handler, this->channel); -	event_manager.subscribe<MousePressEvent>(mouse_press_handler, this->channel); -	event_manager.subscribe<MouseReleaseEvent>(mouse_release_handler, this->channel); -	event_manager.subscribe<MouseMoveEvent>(mouse_move_handler, this->channel); +	move_id = event_manager.subscribe<MouseMoveEvent>( +		[this](const MouseMoveEvent & event) { return this->on_mouse_moved(event); }, +		channel);  } -void IMouseListener::unsubscribe_events() { -	// Unsubscribe event handlers -	event_manager.unsubscribe<MouseClickEvent>(mouse_click_handler, this->channel); -	event_manager.unsubscribe<MousePressEvent>(mouse_press_handler, this->channel); -	event_manager.unsubscribe<MouseReleaseEvent>(mouse_release_handler, this->channel); -	event_manager.unsubscribe<MouseMoveEvent>(mouse_move_handler, this->channel); -} +IMouseListener::~IMouseListener() { +	 // Unsubscribe event handlers +	event_manager.unsubscribe(click_id); +	event_manager.unsubscribe(press_id); +	event_manager.unsubscribe(release_id); +	event_manager.unsubscribe(move_id); +	} diff --git a/src/crepe/api/IMouseListener.h b/src/crepe/api/IMouseListener.h index 6bc5716..91b33e1 100644 --- a/src/crepe/api/IMouseListener.h +++ b/src/crepe/api/IMouseListener.h @@ -16,7 +16,7 @@ public:       * \brief Constructs an IMouseListener with a specified channel.       * \param channel The channel ID for event handling.       */ -	IMouseListener(int channel = CHANNEL_ALL); +	IMouseListener(int channel = EventManager::CHANNEL_ALL);  	virtual ~IMouseListener();  	IMouseListener & operator=(const IMouseListener &) = delete;  	IMouseListener(const IMouseListener &) = delete; @@ -56,30 +56,16 @@ public:       */  	virtual bool on_mouse_moved(const MouseMoveEvent & event) = 0; -protected: -	/** -     * \brief Subscribes to mouse events on the specified channel. -     */ -	void subscribe_events(); - -	/** -     * \brief Unsubscribes from mouse events on the specified channel. -     */ -	void unsubscribe_events(); -  private: -	//! Indicates whether mouse listening is active. -	bool active = true; -	//! Channel ID for event handling. -	int channel = 0; -	//! Mouse click event handler. -	EventHandler<MouseClickEvent> mouse_click_handler; -	//! Mouse press event handler. -	EventHandler<MousePressEvent> mouse_press_handler; -	//! Mouse release event handler. -	EventHandler<MouseReleaseEvent> mouse_release_handler; -	//! Mouse move event handler. -	EventHandler<MouseMoveEvent> mouse_move_handler; +	//! Mouse click event id +	subscription_t click_id = -1; +	//! Mouse press event id +	subscription_t press_id = -1; +	//! Mouse release event id +	subscription_t release_id = -1; +	//! Mouse move event id +	subscription_t move_id = -1; +	//! EventManager reference  	EventManager & event_manager;  }; diff --git a/src/example/events.cpp b/src/example/events.cpp deleted file mode 100644 index 3dee9fa..0000000 --- a/src/example/events.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include <iostream> - -#include <crepe/ComponentManager.h> -#include <crepe/system/ScriptSystem.h> - -#include <crepe/api/BehaviorScript.h> -#include <crepe/api/Config.h> -#include <crepe/api/Event.h> -#include <crepe/api/EventManager.h> -#include <crepe/api/GameObject.h> -#include <crepe/api/IKeyListener.h> -#include <crepe/api/IMouseListener.h> -#include <crepe/api/KeyCodes.h> -#include <crepe/api/Script.h> -#include <crepe/api/Transform.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) override { -		std::cout << "MouseClick function" << std::endl; -		return false; -	} -	bool on_mouse_pressed(const MousePressEvent & event) override { -		std::cout << "MousePress function" << std::endl; -		return false; -	} -	bool on_mouse_released(const MouseReleaseEvent & event) override { -		std::cout << "MouseRelease function" << std::endl; -		return false; -	} -	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: " << 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 = 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; -		// queue events to test queue -		EventManager::get_instance().queue_event<KeyPressEvent>(key_press); -		EventManager::get_instance().queue_event<MouseClickEvent>(click_event); -		TestKeyListener test_listener; -		//auto obj = GameObject(0, "name", "tag", Vector2{1.2, 3.4}, 0, 1); -		//obj.add_component<BehaviorScript>().set_script<MyScript>(); - -		//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{ -		// 		.mouse_x = 100, -		// 		.mouse_y = 100, -		// 		.button = MouseButton::LEFT_MOUSE, -		// 	}, -		// 	1); -		//EventManager::get_instance().trigger_event<MouseClickEvent>(click_event, 0); -	} -	// custom lambda event handler -	EventHandler<KeyPressEvent> event_handler = [](const KeyPressEvent & e) { -		std::cout << "key lambda test" << std::endl; -		return true; -	}; -	EventHandler<MouseClickEvent> event_handler2 = [](const MouseClickEvent & e) { -		std::cout << "mouse lambda test" << std::endl; -		return false; -	}; -	EventManager::get_instance().subscribe<KeyPressEvent>(event_handler, CHANNEL_ALL); -	EventManager::get_instance().subscribe<KeyPressEvent>(event_handler, CHANNEL_ALL); -	EventManager::get_instance().subscribe<MouseClickEvent>(event_handler2, CHANNEL_ALL); -	EventManager::get_instance().trigger_event<KeyPressEvent>( -		KeyPressEvent{.repeat = false, .key = Keycode::A}); -	//EventManager::get_instance().unsubscribe<KeyPressEvent>(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); -	// dispatching queued events -	//EventManager::get_instance().dispatch_events(); - -	EventManager::get_instance().unsubscribe<KeyPressEvent>(event_handler); -	return EXIT_SUCCESS; -} diff --git a/src/test/EventTest.cpp b/src/test/EventTest.cpp index 9dc2360..d42e742 100644 --- a/src/test/EventTest.cpp +++ b/src/test/EventTest.cpp @@ -34,6 +34,7 @@ public:  	MOCK_METHOD(bool, on_mouse_released, (const MouseReleaseEvent & event), (override));  	MOCK_METHOD(bool, on_mouse_moved, (const MouseMoveEvent & event), (override));  }; +  TEST_F(EventManagerTest, EventSubscription) {  	EventHandler<KeyPressEvent> key_handler = [](const KeyPressEvent & e) {  		std::cout << "Key Event Triggered" << std::endl; @@ -57,65 +58,47 @@ TEST_F(EventManagerTest, EventSubscription) {  			.key = Keycode::A,  		}, -		CHANNEL_ALL); +		EventManager::CHANNEL_ALL);  }  TEST_F(EventManagerTest, EventManagerTest_trigger_all_channels) {  	bool triggered = false;  	EventHandler<MouseClickEvent> mouse_handler = [&](const MouseClickEvent & e) {  		triggered = true; -		std::cout << "mouse handled" << std::endl;  		EXPECT_EQ(e.mouse_x, 100);  		EXPECT_EQ(e.mouse_y, 200);  		EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE);  		return false;  	}; -	EventManager::get_instance().subscribe<MouseClickEvent>(mouse_handler, CHANNEL_ALL); +	EventManager::get_instance().subscribe<MouseClickEvent>(mouse_handler, EventManager::CHANNEL_ALL);  	MouseClickEvent click_event{  		.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE}; -	EventManager::get_instance().trigger_event<MouseClickEvent>(click_event, CHANNEL_ALL); +	EventManager::get_instance().trigger_event<MouseClickEvent>(click_event, EventManager::CHANNEL_ALL);  	EXPECT_TRUE(triggered);  } - -TEST_F(EventManagerTest, EventManagerTest_priority_order) { -	EventManager & event_manager = EventManager::get_instance(); - -	// Vector to track call order -	std::vector<int> call_order; - -	// Handlers with different priorities -	EventHandler<MouseClickEvent> handler_priority_3 = [&](const MouseClickEvent & e) { -		call_order.push_back(3); -		return false; // Allow propagation -	}; - -	EventHandler<MouseClickEvent> handler_priority_1 = [&](const MouseClickEvent & e) { -		call_order.push_back(1); -		return false; // Allow propagation -	}; - -	EventHandler<MouseClickEvent> handler_priority_2 = [&](const MouseClickEvent & e) { -		call_order.push_back(2); -		return false; // Allow propagation +TEST_F(EventManagerTest, EventManagerTest_trigger_one_channel) { +	bool triggered = false; +	int test_channel = 1; +	EventHandler<MouseClickEvent> mouse_handler = [&](const MouseClickEvent & e) { +		triggered = true; +		EXPECT_EQ(e.mouse_x, 100); +		EXPECT_EQ(e.mouse_y, 200); +		EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); +		return false;  	}; +	EventManager::get_instance().subscribe<MouseClickEvent>(mouse_handler, test_channel); -	// Subscribe handlers with different priorities -	event_manager.subscribe<MouseClickEvent>(handler_priority_1, CHANNEL_ALL, 1); -	event_manager.subscribe<MouseClickEvent>(handler_priority_3, CHANNEL_ALL, 3); -	event_manager.subscribe<MouseClickEvent>(handler_priority_2, CHANNEL_ALL, 2); - -	// Trigger the event -	event_manager.trigger_event<MouseClickEvent>( -		MouseClickEvent{.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE}, -		CHANNEL_ALL); +	MouseClickEvent click_event{ +		.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE}; +	EventManager::get_instance().trigger_event<MouseClickEvent>(click_event, EventManager::CHANNEL_ALL); -	// Check the call order matches the expected priority order -	std::vector<int> expected_order = {3, 2, 1}; -	EXPECT_EQ(call_order, expected_order); +	EXPECT_FALSE(triggered); +	EventManager::get_instance().trigger_event<MouseClickEvent>(click_event, test_channel);  } +  TEST_F(EventManagerTest, EventManagerTest_callback_propagation) {  	EventManager & event_manager = EventManager::get_instance(); @@ -143,13 +126,13 @@ TEST_F(EventManagerTest, EventManagerTest_callback_propagation) {  	// Test event  	MouseClickEvent click_event{  		.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE}; - -	// First Scenario: True handler has higher priority -	event_manager.subscribe<MouseClickEvent>(mouse_handler_true, CHANNEL_ALL, 1); -	event_manager.subscribe<MouseClickEvent>(mouse_handler_false, CHANNEL_ALL, 0); +	event_manager.subscribe<MouseClickEvent>(mouse_handler_true, EventManager::CHANNEL_ALL); +	event_manager.subscribe<MouseClickEvent>(mouse_handler_false, EventManager::CHANNEL_ALL); +	 +	  	// Trigger event -	event_manager.trigger_event<MouseClickEvent>(click_event, CHANNEL_ALL); +	event_manager.trigger_event<MouseClickEvent>(click_event, EventManager::CHANNEL_ALL);  	// Check that only the true handler was triggered  	EXPECT_TRUE(triggered_true); @@ -159,13 +142,12 @@ TEST_F(EventManagerTest, EventManagerTest_callback_propagation) {  	triggered_true = false;  	triggered_false = false;  	event_manager.clear(); - -	// Second Scenario: False handler has higher priority -	event_manager.subscribe<MouseClickEvent>(mouse_handler_true, CHANNEL_ALL, 0); -	event_manager.subscribe<MouseClickEvent>(mouse_handler_false, CHANNEL_ALL, 1); +	event_manager.subscribe<MouseClickEvent>(mouse_handler_false, EventManager::CHANNEL_ALL); +	event_manager.subscribe<MouseClickEvent>(mouse_handler_true, EventManager::CHANNEL_ALL); +	  	// Trigger event again -	event_manager.trigger_event<MouseClickEvent>(click_event, CHANNEL_ALL); +	event_manager.trigger_event<MouseClickEvent>(click_event, EventManager::CHANNEL_ALL);  	// Check that both handlers were triggered  	EXPECT_TRUE(triggered_true); @@ -204,40 +186,6 @@ TEST_F(EventManagerTest, EventManagerTest_queue_dispatch) {  	EXPECT_TRUE(triggered2);  } -TEST_F(EventManagerTest, EventManagerTest_dispatch_priority) { -	EventManager & event_manager = EventManager::get_instance(); -	std::vector<int> call_order; -	int test_channel = 1; -	EventHandler<MouseClickEvent> mouse_handler1 = [&](const MouseClickEvent & e) { -		call_order.push_back(1); -		EXPECT_EQ(e.mouse_x, 100); -		EXPECT_EQ(e.mouse_y, 200); -		EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); -		return false; // Allows propagation -	}; -	EventHandler<MouseClickEvent> mouse_handler2 = [&](const MouseClickEvent & e) { -		call_order.push_back(2); -		EXPECT_EQ(e.mouse_x, 100); -		EXPECT_EQ(e.mouse_y, 200); -		EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); -		return false; // Allows propagation -	}; -	EventHandler<MouseClickEvent> mouse_handler3 = [&](const MouseClickEvent & e) { -		call_order.push_back(3); -		EXPECT_EQ(e.mouse_x, 100); -		EXPECT_EQ(e.mouse_y, 200); -		EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); -		return false; // Allows propagation -	}; -	event_manager.subscribe<MouseClickEvent>(mouse_handler2, CHANNEL_ALL, 2); -	event_manager.subscribe<MouseClickEvent>(mouse_handler1, CHANNEL_ALL, 1); -	event_manager.subscribe<MouseClickEvent>(mouse_handler3, CHANNEL_ALL, 3); -	event_manager.queue_event<MouseClickEvent>( -		MouseClickEvent{.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE}); -	event_manager.dispatch_events(); -	std::vector<int> expected_order = {3, 2, 1}; -	EXPECT_EQ(call_order, expected_order); -}  TEST_F(EventManagerTest, EventManagerTest_unsubscribe) {  	EventManager & event_manager = EventManager::get_instance(); @@ -263,8 +211,8 @@ TEST_F(EventManagerTest, EventManagerTest_unsubscribe) {  		return false; // Allows propagation  	};  	// Subscribe handlers -	event_manager.subscribe<MouseClickEvent>(mouse_handler1); -	event_manager.subscribe<MouseClickEvent>(mouse_handler2); +	subscription_t handler1_id = event_manager.subscribe<MouseClickEvent>(mouse_handler1); +	subscription_t handler2_id = event_manager.subscribe<MouseClickEvent>(mouse_handler2);  	// Queue events  	event_manager.queue_event<MouseClickEvent>( @@ -280,7 +228,7 @@ TEST_F(EventManagerTest, EventManagerTest_unsubscribe) {  	triggered2 = false;  	// Unsubscribe handler1 -	event_manager.unsubscribe<MouseClickEvent>(mouse_handler1); +	event_manager.unsubscribe(handler1_id);  	// Queue the same event again  	event_manager.queue_event<MouseClickEvent>( @@ -295,7 +243,7 @@ TEST_F(EventManagerTest, EventManagerTest_unsubscribe) {  	triggered2 = false;  	// Unsubscribe handler2 -	event_manager.unsubscribe<MouseClickEvent>(mouse_handler2); +	event_manager.unsubscribe(handler2_id);  	// Queue the event again  	event_manager.queue_event<MouseClickEvent>(  |