diff options
| -rw-r--r-- | mwe/events/include/event.h | 2 | ||||
| -rw-r--r-- | src/crepe/api/EventManager.cpp | 60 | ||||
| -rw-r--r-- | src/crepe/api/EventManager.h | 19 | ||||
| -rw-r--r-- | src/crepe/api/EventManager.hpp | 87 | ||||
| -rw-r--r-- | src/crepe/api/IKeyListener.cpp | 8 | ||||
| -rw-r--r-- | src/crepe/api/IKeyListener.h | 1 | ||||
| -rw-r--r-- | src/crepe/api/IMouseListener.cpp | 3 | ||||
| -rw-r--r-- | src/crepe/api/IMouseListener.h | 1 | ||||
| -rw-r--r-- | src/example/events.cpp | 10 | ||||
| -rw-r--r-- | src/test/EventTest.cpp | 530 | 
10 files changed, 344 insertions, 377 deletions
diff --git a/mwe/events/include/event.h b/mwe/events/include/event.h index ee1bf52..e1b220b 100644 --- a/mwe/events/include/event.h +++ b/mwe/events/include/event.h @@ -148,7 +148,7 @@ private:  };  class ShutDownEvent : public Event {  public: -	ShutDownEvent() : Event("ShutDownEvent") {}; +	ShutDownEvent() : Event("ShutDownEvent"){};  	REGISTER_EVENT_TYPE(ShutDownEvent) diff --git a/src/crepe/api/EventManager.cpp b/src/crepe/api/EventManager.cpp index 4f88e97..dbdb0c3 100644 --- a/src/crepe/api/EventManager.cpp +++ b/src/crepe/api/EventManager.cpp @@ -8,37 +8,39 @@ EventManager & EventManager::get_instance() {  }  void EventManager::dispatch_events() { -    for (auto event_it = this->events_queue.begin(); event_it != this->events_queue.end();) { -        std::unique_ptr<Event>& event = (*event_it).event; -        int channel = (*event_it).channel; -        std::type_index event_type = (*event_it).type; - -        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 (!event_handled) { -            ++event_it; -        } -    } +	for (auto event_it = this->events_queue.begin(); event_it != this->events_queue.end();) { +		std::unique_ptr<Event> & event = (*event_it).event; +		int channel = (*event_it).channel; +		std::type_index event_type = (*event_it).type; + +		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 (!event_handled) { +			++event_it; +		} +	}  } -void EventManager::clear(){ +void EventManager::clear() {  	this->subscribers.clear();  	this->events_queue.clear();  } diff --git a/src/crepe/api/EventManager.h b/src/crepe/api/EventManager.h index eccb0bf..133d72d 100644 --- a/src/crepe/api/EventManager.h +++ b/src/crepe/api/EventManager.h @@ -19,7 +19,6 @@ static constexpr int CHANNEL_ALL = -1;   */  class EventManager {  public: -  	/**       * \brief Get the singleton instance of the EventManager.       *  @@ -39,7 +38,8 @@ public:       * \param channel The channel number to subscribe to (default is 0).       */  	template <typename EventType> -	void subscribe(const EventHandler<EventType> & callback, int channel = CHANNEL_ALL, int priority = 0); +	void subscribe(const EventHandler<EventType> & callback, int channel = CHANNEL_ALL, +				   int priority = 0);  	/**       * \brief Unsubscribe from an event. @@ -76,7 +76,7 @@ public:       * \param channel The channel number for the event (default is 0).       */  	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, int priority = 0);  	/**       * \brief Dispatch all queued events. @@ -90,8 +90,8 @@ public:       *        */  	void clear(); +  private: -	  	/**       * \brief Default constructor for the EventManager.       *  @@ -99,21 +99,20 @@ private:       */  	EventManager() = default;  	struct QueueEntry { -        	std::unique_ptr<Event> event; +		std::unique_ptr<Event> event;  		int channel = CHANNEL_ALL;  		std::type_index type;  		int priority = 0; -    	}; +	};  	struct CallbackEntry { -        	std::unique_ptr<IEventHandlerWrapper> callback; +		std::unique_ptr<IEventHandlerWrapper> callback;  		int channel = CHANNEL_ALL;  		int priority = 0; -    	}; +	};  	//! The queue of events to be processed.  	std::vector<QueueEntry> events_queue;  	//! Registered event handlers. -	std::unordered_map<std::type_index,std::vector<CallbackEntry>> subscribers; -	 +	std::unordered_map<std::type_index, std::vector<CallbackEntry>> subscribers;  };  } // namespace crepe diff --git a/src/crepe/api/EventManager.hpp b/src/crepe/api/EventManager.hpp index 481017d..a04a43a 100644 --- a/src/crepe/api/EventManager.hpp +++ b/src/crepe/api/EventManager.hpp @@ -3,7 +3,8 @@  namespace crepe {  template <typename EventType> -void EventManager::subscribe(const EventHandler<EventType> & callback, int channel, int priority) { +void EventManager::subscribe(const EventHandler<EventType> & callback, int channel, +							 int priority) {  	std::type_index event_type = typeid(EventType);  	std::unique_ptr<EventHandlerWrapper<EventType>> handler @@ -14,69 +15,65 @@ void EventManager::subscribe(const EventHandler<EventType> & callback, int chann  		.channel = channel,  		.priority = priority,  	}); -	 // Sort handlers by priority (highest first) -    std::sort(handlers.begin(), handlers.end(), [](const CallbackEntry &a, const CallbackEntry &b) { -        return a.priority > b.priority; -    }); +	// Sort handlers by priority (highest first) +	std::sort(handlers.begin(), handlers.end(), +			  [](const CallbackEntry & a, const CallbackEntry & b) { +				  return a.priority > b.priority; +			  });  }  template <typename EventType> -void EventManager::queue_event(const EventType & event, int channel,int priority) { -	static_assert(std::is_base_of<Event, EventType>::value, "EventType must derive from Event"); +void EventManager::queue_event(const EventType & event, int channel, int priority) { +	static_assert(std::is_base_of<Event, EventType>::value, +				  "EventType must derive from Event");  	std::type_index event_type = typeid(EventType);  	auto event_ptr = std::make_unique<EventType>(event); -	this->events_queue.push_back( -		QueueEntry{ -			.event = std::move(event_ptr), -			.channel = channel, -			.type = event_type, -			.priority = priority -		} -	); +	this->events_queue.push_back(QueueEntry{.event = std::move(event_ptr), +											.channel = channel, +											.type = event_type, +											.priority = priority});  }  template <typename EventType>  void EventManager::trigger_event(const EventType & event, int channel) { -    std::type_index event_type = typeid(EventType); +	std::type_index event_type = typeid(EventType); -    auto handlers_it = this->subscribers.find(event_type); -    if (handlers_it != this->subscribers.end()) { -        const std::vector<CallbackEntry> &handlers = handlers_it->second; +	auto handlers_it = this->subscribers.find(event_type); +	if (handlers_it != this->subscribers.end()) { +		const std::vector<CallbackEntry> & handlers = handlers_it->second; -        for (const CallbackEntry &handler : handlers) { -            if (handler.channel != channel && handler.channel != CHANNEL_ALL) { -                continue; -            } -            if (handler.callback->exec(event)) { -                break; -            } -        } -    } +		for (const CallbackEntry & handler : handlers) { +			if (handler.channel != channel && handler.channel != CHANNEL_ALL) { +				continue; +			} +			if (handler.callback->exec(event)) { +				break; +			} +		} +	}  } -  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::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; +	// 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; -        } -    } +		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 5e7d9bb..6a522c1 100644 --- a/src/crepe/api/IKeyListener.cpp +++ b/src/crepe/api/IKeyListener.cpp @@ -2,7 +2,6 @@  using namespace crepe; -  // Constructor with specified channel  IKeyListener::IKeyListener(int channel)  	: channel(channel), @@ -21,10 +20,8 @@ void IKeyListener::subscribe_events() {  	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); +	event_manager.subscribe<KeyPressEvent>(this->key_pressed_handler, this->channel); +	event_manager.subscribe<KeyReleaseEvent>(this->key_released_handler, this->channel);  }  // Unsubscribe from key events @@ -32,4 +29,3 @@ 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 70243b4..9402cce 100644 --- a/src/crepe/api/IKeyListener.h +++ b/src/crepe/api/IKeyListener.h @@ -36,6 +36,7 @@ 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. diff --git a/src/crepe/api/IMouseListener.cpp b/src/crepe/api/IMouseListener.cpp index 6fd6c4b..f3ceb84 100644 --- a/src/crepe/api/IMouseListener.cpp +++ b/src/crepe/api/IMouseListener.cpp @@ -24,8 +24,7 @@ void IMouseListener::subscribe_events() {  	// 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<MouseReleaseEvent>(mouse_release_handler, this->channel);  	event_manager.subscribe<MouseMoveEvent>(mouse_move_handler, this->channel);  } diff --git a/src/crepe/api/IMouseListener.h b/src/crepe/api/IMouseListener.h index 1195a4e..6bc5716 100644 --- a/src/crepe/api/IMouseListener.h +++ b/src/crepe/api/IMouseListener.h @@ -55,6 +55,7 @@ public:       * \return True if the event was handled, false otherwise.       */  	virtual bool on_mouse_moved(const MouseMoveEvent & event) = 0; +  protected:  	/**       * \brief Subscribes to mouse events on the specified channel. diff --git a/src/example/events.cpp b/src/example/events.cpp index 402a857..3dee9fa 100644 --- a/src/example/events.cpp +++ b/src/example/events.cpp @@ -63,9 +63,9 @@ public:  	}  };  int main() { -	 +  	{ -			// two events to trigger +		// two events to trigger  		KeyPressEvent key_press;  		key_press.key = Keycode::A;  		key_press.repeat = 0; @@ -106,10 +106,8 @@ int main() {  	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().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); diff --git a/src/test/EventTest.cpp b/src/test/EventTest.cpp index 3a78590..9dc2360 100644 --- a/src/test/EventTest.cpp +++ b/src/test/EventTest.cpp @@ -1,334 +1,308 @@ -#include "api/EventManager.h"  #include "api/Event.h" +#include "api/EventManager.h"  #include "api/IKeyListener.h"  #include "api/IMouseListener.h" -#include <gtest/gtest.h> -#include <gtest/gtest.h>  #include <gmock/gmock.h> +#include <gtest/gtest.h>  using namespace std;  using namespace std::chrono_literals;  using namespace crepe; -  class EventManagerTest : public ::testing::Test {  protected: -    void SetUp() override { -        // Clear any existing subscriptions or events before each test -        EventManager::get_instance().clear(); -    } - -    void TearDown() override { -        // Ensure cleanup after each test -        EventManager::get_instance().clear(); -    } +	void SetUp() override { +		// Clear any existing subscriptions or events before each test +		EventManager::get_instance().clear(); +	} + +	void TearDown() override { +		// Ensure cleanup after each test +		EventManager::get_instance().clear(); +	}  };  class MockKeyListener : public IKeyListener {  public: -    MOCK_METHOD(bool, on_key_pressed, (const KeyPressEvent& event), (override)); -    MOCK_METHOD(bool, on_key_released, (const KeyReleaseEvent& event), (override)); +	MOCK_METHOD(bool, on_key_pressed, (const KeyPressEvent & event), (override)); +	MOCK_METHOD(bool, on_key_released, (const KeyReleaseEvent & event), (override));  };  class MockMouseListener : public IMouseListener {  public: -    MOCK_METHOD(bool, on_mouse_clicked, (const MouseClickEvent& event), (override)); -    MOCK_METHOD(bool, on_mouse_pressed, (const MousePressEvent& event), (override)); -    MOCK_METHOD(bool, on_mouse_released, (const MouseReleaseEvent& event), (override)); -    MOCK_METHOD(bool, on_mouse_moved, (const MouseMoveEvent& event), (override)); +	MOCK_METHOD(bool, on_mouse_clicked, (const MouseClickEvent & event), (override)); +	MOCK_METHOD(bool, on_mouse_pressed, (const MousePressEvent & event), (override)); +	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; -        return true; -    }; - -    // Subscribe to KeyPressEvent -    EventManager::get_instance().subscribe<KeyPressEvent>(key_handler, 1); - -    // Verify subscription (not directly verifiable; test by triggering event) -     -    EventManager::get_instance().trigger_event<KeyPressEvent>(KeyPressEvent{ -		.repeat = true, -		.key = Keycode::A, -	}, 1); -	EventManager::get_instance().trigger_event<KeyPressEvent>(KeyPressEvent{ -		.repeat = true, -		.key = Keycode::A, -		 -	}, CHANNEL_ALL); -	 +	EventHandler<KeyPressEvent> key_handler = [](const KeyPressEvent & e) { +		std::cout << "Key Event Triggered" << std::endl; +		return true; +	}; + +	// Subscribe to KeyPressEvent +	EventManager::get_instance().subscribe<KeyPressEvent>(key_handler, 1); + +	// Verify subscription (not directly verifiable; test by triggering event) + +	EventManager::get_instance().trigger_event<KeyPressEvent>( +		KeyPressEvent{ +			.repeat = true, +			.key = Keycode::A, +		}, +		1); +	EventManager::get_instance().trigger_event<KeyPressEvent>( +		KeyPressEvent{ +			.repeat = true, +			.key = Keycode::A, + +		}, +		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); - -    MouseClickEvent click_event{ -		.mouse_x = 100, -		.mouse_y = 200, -		.button = MouseButton::LEFT_MOUSE +	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); + +	MouseClickEvent click_event{ +		.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE};  	EventManager::get_instance().trigger_event<MouseClickEvent>(click_event, CHANNEL_ALL); -    EXPECT_TRUE(triggered); +	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 -    }; - -    // 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); +	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 +	}; -    // Trigger the event -    event_manager.trigger_event<MouseClickEvent>(MouseClickEvent{ -        .mouse_x = 100, -        .mouse_y = 200, -        .button = MouseButton::LEFT_MOUSE -    }, CHANNEL_ALL); +	EventHandler<MouseClickEvent> handler_priority_2 = [&](const MouseClickEvent & e) { +		call_order.push_back(2); +		return false; // Allow propagation +	}; + +	// 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); -    // Check the call order matches the expected priority order -    std::vector<int> expected_order = {3, 2, 1}; -    EXPECT_EQ(call_order, expected_order); +	// Trigger the event +	event_manager.trigger_event<MouseClickEvent>( +		MouseClickEvent{.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE}, +		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);  }  TEST_F(EventManagerTest, EventManagerTest_callback_propagation) { -    EventManager& event_manager = EventManager::get_instance(); - -    // Flags to track handler calls -    bool triggered_true = false; -    bool triggered_false = false; - -    // Handlers -    EventHandler<MouseClickEvent> mouse_handler_true = [&](const MouseClickEvent& e) { -        triggered_true = true; -        EXPECT_EQ(e.mouse_x, 100); -        EXPECT_EQ(e.mouse_y, 200); -        EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); -        return true;  // Stops propagation -    }; - -    EventHandler<MouseClickEvent> mouse_handler_false = [&](const MouseClickEvent& e) { -        triggered_false = true; -        EXPECT_EQ(e.mouse_x, 100); -        EXPECT_EQ(e.mouse_y, 200); -        EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); -        return false;  // Allows 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); - -    // Trigger event -    event_manager.trigger_event<MouseClickEvent>(click_event, CHANNEL_ALL); - -    // Check that only the true handler was triggered -    EXPECT_TRUE(triggered_true); -    EXPECT_FALSE(triggered_false); - -    // Reset and clear -    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); - -    // Trigger event again -    event_manager.trigger_event<MouseClickEvent>(click_event, CHANNEL_ALL); - -    // Check that both handlers were triggered -    EXPECT_TRUE(triggered_true); -    EXPECT_TRUE(triggered_false); +	EventManager & event_manager = EventManager::get_instance(); + +	// Flags to track handler calls +	bool triggered_true = false; +	bool triggered_false = false; + +	// Handlers +	EventHandler<MouseClickEvent> mouse_handler_true = [&](const MouseClickEvent & e) { +		triggered_true = true; +		EXPECT_EQ(e.mouse_x, 100); +		EXPECT_EQ(e.mouse_y, 200); +		EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); +		return true; // Stops propagation +	}; + +	EventHandler<MouseClickEvent> mouse_handler_false = [&](const MouseClickEvent & e) { +		triggered_false = true; +		EXPECT_EQ(e.mouse_x, 100); +		EXPECT_EQ(e.mouse_y, 200); +		EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); +		return false; // Allows 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); + +	// Trigger event +	event_manager.trigger_event<MouseClickEvent>(click_event, CHANNEL_ALL); + +	// Check that only the true handler was triggered +	EXPECT_TRUE(triggered_true); +	EXPECT_FALSE(triggered_false); + +	// Reset and clear +	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); + +	// Trigger event again +	event_manager.trigger_event<MouseClickEvent>(click_event, CHANNEL_ALL); + +	// Check that both handlers were triggered +	EXPECT_TRUE(triggered_true); +	EXPECT_TRUE(triggered_false);  }  TEST_F(EventManagerTest, EventManagerTest_queue_dispatch) { -	EventManager& event_manager = EventManager::get_instance(); +	EventManager & event_manager = EventManager::get_instance();  	bool triggered1 = false;  	bool triggered2 = false;  	int test_channel = 1; -	EventHandler<MouseClickEvent> mouse_handler1 = [&](const MouseClickEvent& e) { -        triggered1 = true; -        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) { -        triggered2 = true; -        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_handler1 = [&](const MouseClickEvent & e) { +		triggered1 = true; +		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) { +		triggered2 = true; +		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_handler1); -	event_manager.subscribe<MouseClickEvent>(mouse_handler2,test_channel); -	 -	event_manager.queue_event<MouseClickEvent>(MouseClickEvent{ -		.mouse_x = 100, -		.mouse_y = 200, -		.button = MouseButton::LEFT_MOUSE -	}); -	event_manager.queue_event<MouseClickEvent>(MouseClickEvent{ -		.mouse_x = 100, -		.mouse_y = 200, -		.button = MouseButton::LEFT_MOUSE -	},test_channel); +	event_manager.subscribe<MouseClickEvent>(mouse_handler2, test_channel); + +	event_manager.queue_event<MouseClickEvent>( +		MouseClickEvent{.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE}); +	event_manager.queue_event<MouseClickEvent>( +		MouseClickEvent{.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE}, +		test_channel);  	event_manager.dispatch_events();  	EXPECT_TRUE(triggered1);  	EXPECT_TRUE(triggered2);  }  TEST_F(EventManagerTest, EventManagerTest_dispatch_priority) { -	EventManager& event_manager = EventManager::get_instance(); +	EventManager & event_manager = EventManager::get_instance();  	std::vector<int> call_order;  	int test_channel = 1; -	EventHandler<MouseClickEvent> mouse_handler1 = [&](const MouseClickEvent& e) { +	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 -	}); +		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); +	EXPECT_EQ(call_order, expected_order);  }  TEST_F(EventManagerTest, EventManagerTest_unsubscribe) { -    EventManager& event_manager = EventManager::get_instance(); -     -    // Flags to track if handlers are triggered -    bool triggered1 = false; -    bool triggered2 = false; -     -    // Define EventHandlers -    EventHandler<MouseClickEvent> mouse_handler1 = [&](const MouseClickEvent& e) { -        triggered1 = true; -        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) { -        triggered2 = true; -        EXPECT_EQ(e.mouse_x, 100); -        EXPECT_EQ(e.mouse_y, 200); -        EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); -        return false;  // Allows propagation -    }; -    // Subscribe handlers -    event_manager.subscribe<MouseClickEvent>(mouse_handler1); -    event_manager.subscribe<MouseClickEvent>(mouse_handler2); -     -    // Queue events -    event_manager.queue_event<MouseClickEvent>(MouseClickEvent{ -        .mouse_x = 100, -        .mouse_y = 200, -        .button = MouseButton::LEFT_MOUSE -    }); -     -    // Dispatch events - both handlers should be triggered -    event_manager.dispatch_events(); -    EXPECT_TRUE(triggered1);  // Handler 1 should be triggered -    EXPECT_TRUE(triggered2);  // Handler 2 should be triggered -     -    // Reset flags -    triggered1 = false; -    triggered2 = false; -     -    // Unsubscribe handler1 -    event_manager.unsubscribe<MouseClickEvent>(mouse_handler1); -     -    // Queue the same event again -    event_manager.queue_event<MouseClickEvent>(MouseClickEvent{ -        .mouse_x = 100, -        .mouse_y = 200, -        .button = MouseButton::LEFT_MOUSE -    }); -     -    // Dispatch events - only handler 2 should be triggered, handler 1 should NOT -    event_manager.dispatch_events(); -    EXPECT_FALSE(triggered1);  // Handler 1 should NOT be triggered -    EXPECT_TRUE(triggered2);   // Handler 2 should be triggered -     -    // Reset flags -    triggered2 = false; -     -    // Unsubscribe handler2 -    event_manager.unsubscribe<MouseClickEvent>(mouse_handler2); -     -    // Queue the event again -    event_manager.queue_event<MouseClickEvent>(MouseClickEvent{ -        .mouse_x = 100, -        .mouse_y = 200, -        .button = MouseButton::LEFT_MOUSE -    }); -     -    // Dispatch events - no handler should be triggered -    event_manager.dispatch_events(); -    EXPECT_FALSE(triggered1);  // Handler 1 should NOT be triggered -    EXPECT_FALSE(triggered2);  // Handler 2 should NOT be triggered -} +	EventManager & event_manager = EventManager::get_instance(); + +	// Flags to track if handlers are triggered +	bool triggered1 = false; +	bool triggered2 = false; + +	// Define EventHandlers +	EventHandler<MouseClickEvent> mouse_handler1 = [&](const MouseClickEvent & e) { +		triggered1 = true; +		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) { +		triggered2 = true; +		EXPECT_EQ(e.mouse_x, 100); +		EXPECT_EQ(e.mouse_y, 200); +		EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); +		return false; // Allows propagation +	}; +	// Subscribe handlers +	event_manager.subscribe<MouseClickEvent>(mouse_handler1); +	event_manager.subscribe<MouseClickEvent>(mouse_handler2); + +	// Queue events +	event_manager.queue_event<MouseClickEvent>( +		MouseClickEvent{.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE}); + +	// Dispatch events - both handlers should be triggered +	event_manager.dispatch_events(); +	EXPECT_TRUE(triggered1); // Handler 1 should be triggered +	EXPECT_TRUE(triggered2); // Handler 2 should be triggered + +	// Reset flags +	triggered1 = false; +	triggered2 = false; + +	// Unsubscribe handler1 +	event_manager.unsubscribe<MouseClickEvent>(mouse_handler1); + +	// Queue the same event again +	event_manager.queue_event<MouseClickEvent>( +		MouseClickEvent{.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE}); + +	// Dispatch events - only handler 2 should be triggered, handler 1 should NOT +	event_manager.dispatch_events(); +	EXPECT_FALSE(triggered1); // Handler 1 should NOT be triggered +	EXPECT_TRUE(triggered2); // Handler 2 should be triggered + +	// Reset flags +	triggered2 = false; + +	// Unsubscribe handler2 +	event_manager.unsubscribe<MouseClickEvent>(mouse_handler2); + +	// Queue the event again +	event_manager.queue_event<MouseClickEvent>( +		MouseClickEvent{.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE}); + +	// Dispatch events - no handler should be triggered +	event_manager.dispatch_events(); +	EXPECT_FALSE(triggered1); // Handler 1 should NOT be triggered +	EXPECT_FALSE(triggered2); // Handler 2 should NOT be triggered +}  |