diff options
| author | WBoerenkamps <wrj.boerenkamps@student.avans.nl> | 2024-12-07 14:19:16 +0100 | 
|---|---|---|
| committer | WBoerenkamps <wrj.boerenkamps@student.avans.nl> | 2024-12-07 14:19:16 +0100 | 
| commit | a73ff31b67faa7e6a922cfb5598f56f80bc01d62 (patch) | |
| tree | 04840dfbdbe6207100fbbc2aba04f48a46de1022 /src | |
| parent | a0070890fcdb422db85660fc44bcc709832870b8 (diff) | |
added loopTimer and eventManager to mediator and removed the singletons
Diffstat (limited to 'src')
| -rw-r--r-- | src/crepe/api/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | src/crepe/api/IKeyListener.cpp | 19 | ||||
| -rw-r--r-- | src/crepe/api/IKeyListener.h | 50 | ||||
| -rw-r--r-- | src/crepe/api/IMouseListener.cpp | 29 | ||||
| -rw-r--r-- | src/crepe/api/IMouseListener.h | 73 | ||||
| -rw-r--r-- | src/crepe/api/LoopManager.cpp | 18 | ||||
| -rw-r--r-- | src/crepe/api/LoopManager.h | 9 | ||||
| -rw-r--r-- | src/crepe/manager/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/crepe/manager/EventManager.cpp | 6 | ||||
| -rw-r--r-- | src/crepe/manager/EventManager.h | 24 | ||||
| -rw-r--r-- | src/crepe/manager/LoopTimerManager.cpp (renamed from src/crepe/api/LoopTimer.cpp) | 32 | ||||
| -rw-r--r-- | src/crepe/manager/LoopTimerManager.h (renamed from src/crepe/api/LoopTimer.h) | 18 | ||||
| -rw-r--r-- | src/crepe/manager/Mediator.h | 8 | ||||
| -rw-r--r-- | src/test/EventTest.cpp | 88 | ||||
| -rw-r--r-- | src/test/LoopManagerTest.cpp | 29 | ||||
| -rw-r--r-- | src/test/LoopTimerTest.cpp | 17 | ||||
| -rw-r--r-- | src/test/ScriptTest.h | 4 | 
17 files changed, 119 insertions, 313 deletions
| diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt index 7da9dca..60d9dc5 100644 --- a/src/crepe/api/CMakeLists.txt +++ b/src/crepe/api/CMakeLists.txt @@ -13,10 +13,7 @@ target_sources(crepe PUBLIC  	Metadata.cpp  	Camera.cpp  	Animator.cpp -	IKeyListener.cpp -	IMouseListener.cpp  	LoopManager.cpp -	LoopTimer.cpp  	Asset.cpp  	EventHandler.cpp  	Script.cpp @@ -45,9 +42,6 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES  	EventHandler.h  	EventHandler.hpp  	Event.h -	IKeyListener.h -	IMouseListener.h  	LoopManager.h -	LoopTimer.h  	Asset.h  ) diff --git a/src/crepe/api/IKeyListener.cpp b/src/crepe/api/IKeyListener.cpp deleted file mode 100644 index 8642655..0000000 --- a/src/crepe/api/IKeyListener.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "IKeyListener.h" - -using namespace crepe; - -// Constructor with specified channel -IKeyListener::IKeyListener(event_channel_t channel) -	: event_manager(EventManager::get_instance()) { -	this->press_id = event_manager.subscribe<KeyPressEvent>( -		[this](const KeyPressEvent & event) { return this->on_key_pressed(event); }, channel); -	this->release_id = event_manager.subscribe<KeyReleaseEvent>( -		[this](const KeyReleaseEvent & event) { return this->on_key_released(event); }, -		channel); -} - -// Destructor, unsubscribe events -IKeyListener::~IKeyListener() { -	event_manager.unsubscribe(this->press_id); -	event_manager.unsubscribe(this->release_id); -} diff --git a/src/crepe/api/IKeyListener.h b/src/crepe/api/IKeyListener.h deleted file mode 100644 index 6ded107..0000000 --- a/src/crepe/api/IKeyListener.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include "../manager/EventManager.h" - -#include "Event.h" -#include "EventHandler.h" - -namespace crepe { - -/** - * \class IKeyListener - * \brief Interface for keyboard event handling in the application. - */ -class IKeyListener { -public: -	/** -     * \brief Constructs an IKeyListener with a specified channel. -     * \param channel The channel ID for event handling. -     */ -	IKeyListener(event_channel_t channel = EventManager::CHANNEL_ALL); -	virtual ~IKeyListener(); -	IKeyListener(const IKeyListener &) = delete; -	IKeyListener & operator=(const IKeyListener &) = delete; -	IKeyListener & operator=(IKeyListener &&) = delete; -	IKeyListener(IKeyListener &&) = delete; - -	/** -     * \brief Pure virtual function to handle key press events. -     * \param event The key press event to handle. -     * \return True if the event was handled, false otherwise. -     */ -	virtual bool on_key_pressed(const KeyPressEvent & event) = 0; - -	/** -     * \brief Pure virtual function to handle key release events. -     * \param event The key release event to handle. -     * \return True if the event was handled, false otherwise. -     */ -	virtual bool on_key_released(const KeyReleaseEvent & event) = 0; - -private: -	//! Key press event id -	subscription_t press_id = -1; -	//! Key release event id -	subscription_t release_id = -1; -	//! EventManager reference -	EventManager & event_manager; -}; - -} // namespace crepe diff --git a/src/crepe/api/IMouseListener.cpp b/src/crepe/api/IMouseListener.cpp deleted file mode 100644 index 989aeb3..0000000 --- a/src/crepe/api/IMouseListener.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "IMouseListener.h" - -using namespace crepe; - -IMouseListener::IMouseListener(event_channel_t channel) -	: event_manager(EventManager::get_instance()) { -	this->click_id = event_manager.subscribe<MouseClickEvent>( -		[this](const MouseClickEvent & event) { return this->on_mouse_clicked(event); }, -		channel); - -	this->press_id = event_manager.subscribe<MousePressEvent>( -		[this](const MousePressEvent & event) { return this->on_mouse_pressed(event); }, -		channel); - -	this->release_id = event_manager.subscribe<MouseReleaseEvent>( -		[this](const MouseReleaseEvent & event) { return this->on_mouse_released(event); }, -		channel); - -	this->move_id = event_manager.subscribe<MouseMoveEvent>( -		[this](const MouseMoveEvent & event) { return this->on_mouse_moved(event); }, channel); -} - -IMouseListener::~IMouseListener() { -	// Unsubscribe event handlers -	event_manager.unsubscribe(this->click_id); -	event_manager.unsubscribe(this->press_id); -	event_manager.unsubscribe(this->release_id); -	event_manager.unsubscribe(this->move_id); -} diff --git a/src/crepe/api/IMouseListener.h b/src/crepe/api/IMouseListener.h deleted file mode 100644 index 9e4fdf7..0000000 --- a/src/crepe/api/IMouseListener.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include "../manager/EventManager.h" - -#include "Event.h" -#include "EventHandler.h" - -namespace crepe { - -/** - * \class IMouseListener - * \brief Interface for mouse event handling in the application. - */ -class IMouseListener { -public: -	/** -     * \brief Constructs an IMouseListener with a specified channel. -     * \param channel The channel ID for event handling. -     */ -	IMouseListener(event_channel_t channel = EventManager::CHANNEL_ALL); -	virtual ~IMouseListener(); -	IMouseListener & operator=(const IMouseListener &) = delete; -	IMouseListener(const IMouseListener &) = delete; -	IMouseListener & operator=(const IMouseListener &&) = delete; -	IMouseListener(IMouseListener &&) = delete; - -	/** -     * \brief Move assignment operator (deleted). -     */ -	IMouseListener & operator=(IMouseListener &&) = delete; - -	/** -     * \brief Handles a mouse click event. -     * \param event The mouse click event to handle. -     * \return True if the event was handled, false otherwise. -     */ -	virtual bool on_mouse_clicked(const MouseClickEvent & event) = 0; - -	/** -     * \brief Handles a mouse press event. -     * \param event The mouse press event to handle. -     * \return True if the event was handled, false otherwise. -     */ -	virtual bool on_mouse_pressed(const MousePressEvent & event) = 0; - -	/** -     * \brief Handles a mouse release event. -     * \param event The mouse release event to handle. -     * \return True if the event was handled, false otherwise. -     */ -	virtual bool on_mouse_released(const MouseReleaseEvent & event) = 0; - -	/** -     * \brief Handles a mouse move event. -     * \param event The mouse move event to handle. -     * \return True if the event was handled, false otherwise. -     */ -	virtual bool on_mouse_moved(const MouseMoveEvent & event) = 0; - -private: -	//! 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; -}; - -} //namespace crepe diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index 454afe8..69cbfaf 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -1,3 +1,4 @@ +#include <iostream>  #include "../facade/SDLContext.h"  #include "../manager/EventManager.h" @@ -20,10 +21,8 @@ LoopManager::LoopManager() {  	this->load_system<PhysicsSystem>();  	this->load_system<RenderSystem>();  	this->load_system<ScriptSystem>(); -	EventManager::get_instance().subscribe<ShutDownEvent>( +	this->event_manager.subscribe<ShutDownEvent>(  		[this](const ShutDownEvent & event) { return this->on_shutdown(event); }); -	this->loop_timer = make_unique<LoopTimer>(); -	this->mediator.loop_timer = *loop_timer;  }  void LoopManager::process_input() {  @@ -38,27 +37,28 @@ void LoopManager::start() {  void LoopManager::fixed_update() {}  void LoopManager::loop() { -	this->loop_timer->start(); +	  	while (game_running) { -		this->loop_timer->update(); +		this->loop_timer.update(); -		while (this->loop_timer->get_lag() >= this->loop_timer->get_fixed_delta_time()) { +		while (this->loop_timer.get_lag() >= this->loop_timer.get_fixed_delta_time()) {  			this->process_input(); +			event_manager.dispatch_events();  			this->fixed_update(); -			this->loop_timer->advance_fixed_update(); +			this->loop_timer.advance_fixed_update();  		}  		this->update();  		this->render(); -		this->loop_timer->enforce_frame_rate(); +		this->loop_timer.enforce_frame_rate();  	}  }  void LoopManager::setup() {  	this->game_running = true; -	this->loop_timer->start(); +	this->loop_timer.start();  }  void LoopManager::render() { diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h index 2161dff..00f5409 100644 --- a/src/crepe/api/LoopManager.h +++ b/src/crepe/api/LoopManager.h @@ -5,10 +5,11 @@  #include "../facade/SDLContext.h"  #include "../manager/ComponentManager.h"  #include "../manager/SceneManager.h" +#include "../manager/EventManager.h" +#include "../manager/LoopTimerManager.h"  #include "../system/System.h"  #include "api/Event.h" -#include "api/LoopTimer.h"  namespace crepe {  /** @@ -96,8 +97,10 @@ private:  	//! SDL context \todo no more singletons!  	SDLContext & sdl_context = SDLContext::get_instance(); -	//! loop timer instance -	std::unique_ptr<LoopTimer> loop_timer; +	//! LoopTimer instance +	LoopTimerManager loop_timer{mediator}; +	//! EventManager instance +	EventManager event_manager{mediator};  private:  	/** diff --git a/src/crepe/manager/CMakeLists.txt b/src/crepe/manager/CMakeLists.txt index 517b8a2..29d6df0 100644 --- a/src/crepe/manager/CMakeLists.txt +++ b/src/crepe/manager/CMakeLists.txt @@ -4,6 +4,7 @@ target_sources(crepe PUBLIC  	Manager.cpp  	SaveManager.cpp  	SceneManager.cpp +	LoopTimerManager.cpp  )  target_sources(crepe PUBLIC FILE_SET HEADERS FILES @@ -16,5 +17,6 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES  	SaveManager.h  	SceneManager.h  	SceneManager.hpp +	LoopTimerManager.h  ) diff --git a/src/crepe/manager/EventManager.cpp b/src/crepe/manager/EventManager.cpp index 20f0dd3..9b0fa95 100644 --- a/src/crepe/manager/EventManager.cpp +++ b/src/crepe/manager/EventManager.cpp @@ -3,11 +3,9 @@  using namespace crepe;  using namespace std; -EventManager & EventManager::get_instance() { -	static EventManager instance; -	return instance; +EventManager::EventManager(Mediator & mediator) : Manager(mediator){ +	this->mediator.event_manager = *this;  } -  void EventManager::dispatch_events() {  	for (auto & event : this->events_queue) {  		this->handle_event(event.type, event.channel, *event.event.get()); diff --git a/src/crepe/manager/EventManager.h b/src/crepe/manager/EventManager.h index d634f54..5f8b107 100644 --- a/src/crepe/manager/EventManager.h +++ b/src/crepe/manager/EventManager.h @@ -8,6 +8,8 @@  #include "../api/Event.h"  #include "../api/EventHandler.h" +#include "Manager.h" +  namespace crepe {  //! Event listener unique ID @@ -22,27 +24,16 @@ typedef size_t subscription_t;  typedef size_t event_channel_t;  /** - * \class EventManager   * \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 { +class EventManager : public Manager {  public:  	static constexpr const event_channel_t CHANNEL_ALL = -1; - -	/** -	 * \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(); - +	EventManager(Mediator & mediator);  	/**  	 * \brief Subscribe to a specific event type.  	 *  @@ -107,12 +98,7 @@ public:  	void clear();  private: -	/** -	 * \brief Default constructor for the EventManager. -	 *  -	 * Constructor is private to enforce the singleton pattern. -	 */ -	EventManager() = default; +  	/**  	 * \struct QueueEntry diff --git a/src/crepe/api/LoopTimer.cpp b/src/crepe/manager/LoopTimerManager.cpp index 8fb7ce8..8156c6d 100644 --- a/src/crepe/api/LoopTimer.cpp +++ b/src/crepe/manager/LoopTimerManager.cpp @@ -4,13 +4,16 @@  #include "../facade/SDLContext.h"  #include "../util/Log.h" -#include "LoopTimer.h" +#include "LoopTimerManager.h"  using namespace crepe; -LoopTimer::LoopTimer() { dbg_trace(); } +LoopTimerManager::LoopTimerManager(Mediator & mediator) : Manager(mediator) {  +	this->mediator.loop_timer = *this; +	dbg_trace();  +	} -void LoopTimer::start() { +void LoopTimerManager::start() {  	this->last_frame_time = std::chrono::steady_clock::now();  	this->elapsed_time = std::chrono::milliseconds(0); @@ -20,7 +23,7 @@ void LoopTimer::start() {  	this->delta_time = std::chrono::milliseconds(0);  } -void LoopTimer::update() { +void LoopTimerManager::update() {  	auto current_frame_time = std::chrono::steady_clock::now();  	// Convert to duration in seconds for delta time  	this->delta_time = std::chrono::duration_cast<std::chrono::duration<double>>( @@ -31,31 +34,30 @@ void LoopTimer::update() {  	}  	this->actual_fps = 1.0 / this->delta_time.count(); -	this->delta_time *= this->game_scale;  	this->elapsed_time += this->delta_time;  	this->last_frame_time = current_frame_time;  } -double LoopTimer::get_delta_time() const { return this->delta_time.count(); } +double LoopTimerManager::get_delta_time() const { return this->delta_time.count() * this->game_scale; } -double LoopTimer::get_current_time() const { return this->elapsed_time.count(); } +double LoopTimerManager::get_current_time() const { return this->elapsed_time.count(); } -void LoopTimer::advance_fixed_update() { this->elapsed_fixed_time += this->fixed_delta_time; } +void LoopTimerManager::advance_fixed_update() { this->elapsed_fixed_time += this->fixed_delta_time; } -double LoopTimer::get_fixed_delta_time() const { return this->fixed_delta_time.count(); } +double LoopTimerManager::get_fixed_delta_time() const { return this->fixed_delta_time.count(); } -void LoopTimer::set_target_fps(int fps) { +void LoopTimerManager::set_target_fps(int fps) {  	this->target_fps = fps;  	// target time per frame in seconds  	this->frame_target_time = std::chrono::duration<double>(1.0) / this->target_fps;  } -int LoopTimer::get_fps() const { return this->actual_fps; } +int LoopTimerManager::get_fps() const { return this->actual_fps; } -void LoopTimer::set_game_scale(double value) { this->game_scale = value; } +void LoopTimerManager::set_time_scale(double value) { this->game_scale = value; } -double LoopTimer::get_game_scale() const { return this->game_scale; } -void LoopTimer::enforce_frame_rate() { +double LoopTimerManager::get_time_scale() const { return this->game_scale; } +void LoopTimerManager::enforce_frame_rate() {  	auto current_frame_time = std::chrono::steady_clock::now();  	auto frame_duration = current_frame_time - this->last_frame_time; @@ -70,6 +72,6 @@ void LoopTimer::enforce_frame_rate() {  	}  } -double LoopTimer::get_lag() const { +double LoopTimerManager::get_lag() const {  	return (this->elapsed_time - this->elapsed_fixed_time).count();  } diff --git a/src/crepe/api/LoopTimer.h b/src/crepe/manager/LoopTimerManager.h index c4294d7..dba0f66 100644 --- a/src/crepe/api/LoopTimer.h +++ b/src/crepe/manager/LoopTimerManager.h @@ -1,12 +1,12 @@  #pragma once  #include <chrono> - +#include "../manager/Manager.h"  namespace crepe { -class LoopTimer { +class LoopTimerManager : public Manager {  public: -	LoopTimer(); +	LoopTimerManager(Mediator & mediator);  	/**  	 * \brief Get the current delta time for the current frame.  	 * @@ -39,19 +39,19 @@ public:  	int get_fps() const;  	/** -	 * \brief Get the current game scale. +	 * \brief Get the current time scale.  	 * -	 * \return The current game scale, where 0 = paused, 1 = normal speed, and values > 1 speed +	 * \return The current time scale, where 0 = paused, 1 = normal speed, and values > 1 speed  	 * up the game.  	 */ -	double get_game_scale() const; +	double get_time_scale() const;  	/** -	 * \brief Set the game scale. +	 * \brief Set the time scale.  	 * -	 * \param game_scale The desired game scale (0 = pause, 1 = normal speed, > 1 = speed up). +	 * \param game_scale The desired time scale (0 = pause, 1 = normal speed, > 1 = speed up).  	 */ -	void set_game_scale(double game_scale); +	void set_time_scale(double game_scale);  private:  	friend class LoopManager; diff --git a/src/crepe/manager/Mediator.h b/src/crepe/manager/Mediator.h index cd96614..c72af8e 100644 --- a/src/crepe/manager/Mediator.h +++ b/src/crepe/manager/Mediator.h @@ -3,14 +3,14 @@  #include "../util/OptionalRef.h"  // TODO: remove these singletons: -#include "EventManager.h"  #include "SaveManager.h"  namespace crepe {  class ComponentManager;  class SceneManager; -class LoopTimer; +class LoopTimerManager; +class EventManager;  /**   * Struct to pass references to classes that would otherwise need to be singletons down to   * other classes within the engine hierarchy. Made to prevent constant changes to subclasses to @@ -27,8 +27,8 @@ struct Mediator {  	OptionalRef<ComponentManager> component_manager;  	OptionalRef<SceneManager> scene_manager;  	OptionalRef<SaveManager> save_manager = SaveManager::get_instance(); -	OptionalRef<EventManager> event_manager = EventManager::get_instance(); -	OptionalRef<LoopTimer> loop_timer; +	OptionalRef<EventManager> event_manager; +	OptionalRef<LoopTimerManager> loop_timer;  };  } // namespace crepe diff --git a/src/test/EventTest.cpp b/src/test/EventTest.cpp index dccd554..8479998 100644 --- a/src/test/EventTest.cpp +++ b/src/test/EventTest.cpp @@ -1,56 +1,41 @@  #include <gmock/gmock.h>  #include <gtest/gtest.h> -  #include <crepe/api/Event.h> -#include <crepe/api/IKeyListener.h> -#include <crepe/api/IMouseListener.h>  #include <crepe/manager/EventManager.h> - +#include <crepe/manager/Mediator.h>  using namespace std;  using namespace std::chrono_literals;  using namespace crepe;  class EventManagerTest : public ::testing::Test {  protected: +	Mediator mediator; +	EventManager event_mgr{mediator};  	void SetUp() override {  		// Clear any existing subscriptions or events before each test -		EventManager::get_instance().clear(); +		event_mgr.clear();  	}  	void TearDown() override {  		// Ensure cleanup after each test -		EventManager::get_instance().clear(); +		event_mgr.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)); -}; - -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)); -}; -  TEST_F(EventManagerTest, EventSubscription) {  	EventHandler<KeyPressEvent> key_handler = [](const KeyPressEvent & e) { return true; };  	// Subscribe to KeyPressEvent -	EventManager::get_instance().subscribe<KeyPressEvent>(key_handler, 1); +	event_mgr.subscribe<KeyPressEvent>(key_handler, 1);  	// Verify subscription (not directly verifiable; test by triggering event) -	EventManager::get_instance().trigger_event<KeyPressEvent>( +	event_mgr.trigger_event<KeyPressEvent>(  		KeyPressEvent{  			.repeat = true,  			.key = Keycode::A,  		},  		1); -	EventManager::get_instance().trigger_event<KeyPressEvent>( +	event_mgr.trigger_event<KeyPressEvent>(  		KeyPressEvent{  			.repeat = true,  			.key = Keycode::A, @@ -68,12 +53,12 @@ TEST_F(EventManagerTest, EventManagerTest_trigger_all_channels) {  		EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE);  		return false;  	}; -	EventManager::get_instance().subscribe<MouseClickEvent>(mouse_handler, +	event_mgr.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, +	event_mgr.trigger_event<MouseClickEvent>(click_event,  																EventManager::CHANNEL_ALL);  	EXPECT_TRUE(triggered); @@ -88,19 +73,18 @@ TEST_F(EventManagerTest, EventManagerTest_trigger_one_channel) {  		EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE);  		return false;  	}; -	EventManager::get_instance().subscribe<MouseClickEvent>(mouse_handler, test_channel); +	event_mgr.subscribe<MouseClickEvent>(mouse_handler, test_channel);  	MouseClickEvent click_event{  		.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE}; -	EventManager::get_instance().trigger_event<MouseClickEvent>(click_event, +	event_mgr.trigger_event<MouseClickEvent>(click_event,  																EventManager::CHANNEL_ALL);  	EXPECT_FALSE(triggered); -	EventManager::get_instance().trigger_event<MouseClickEvent>(click_event, test_channel); +	event_mgr.trigger_event<MouseClickEvent>(click_event, test_channel);  }  TEST_F(EventManagerTest, EventManagerTest_callback_propagation) { -	EventManager & event_manager = EventManager::get_instance();  	// Flags to track handler calls  	bool triggered_true = false; @@ -126,11 +110,11 @@ TEST_F(EventManagerTest, EventManagerTest_callback_propagation) {  	// Test event  	MouseClickEvent click_event{  		.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE}; -	event_manager.subscribe<MouseClickEvent>(mouse_handler_true, EventManager::CHANNEL_ALL); -	event_manager.subscribe<MouseClickEvent>(mouse_handler_false, EventManager::CHANNEL_ALL); +	event_mgr.subscribe<MouseClickEvent>(mouse_handler_true, EventManager::CHANNEL_ALL); +	event_mgr.subscribe<MouseClickEvent>(mouse_handler_false, EventManager::CHANNEL_ALL);  	// Trigger event -	event_manager.trigger_event<MouseClickEvent>(click_event, EventManager::CHANNEL_ALL); +	event_mgr.trigger_event<MouseClickEvent>(click_event, EventManager::CHANNEL_ALL);  	// Check that only the true handler was triggered  	EXPECT_TRUE(triggered_true); @@ -139,12 +123,12 @@ TEST_F(EventManagerTest, EventManagerTest_callback_propagation) {  	// Reset and clear  	triggered_true = false;  	triggered_false = false; -	event_manager.clear(); -	event_manager.subscribe<MouseClickEvent>(mouse_handler_false, EventManager::CHANNEL_ALL); -	event_manager.subscribe<MouseClickEvent>(mouse_handler_true, EventManager::CHANNEL_ALL); +	event_mgr.clear(); +	event_mgr.subscribe<MouseClickEvent>(mouse_handler_false, EventManager::CHANNEL_ALL); +	event_mgr.subscribe<MouseClickEvent>(mouse_handler_true, EventManager::CHANNEL_ALL);  	// Trigger event again -	event_manager.trigger_event<MouseClickEvent>(click_event, EventManager::CHANNEL_ALL); +	event_mgr.trigger_event<MouseClickEvent>(click_event, EventManager::CHANNEL_ALL);  	// Check that both handlers were triggered  	EXPECT_TRUE(triggered_true); @@ -152,7 +136,6 @@ TEST_F(EventManagerTest, EventManagerTest_callback_propagation) {  }  TEST_F(EventManagerTest, EventManagerTest_queue_dispatch) { -	EventManager & event_manager = EventManager::get_instance();  	bool triggered1 = false;  	bool triggered2 = false;  	int test_channel = 1; @@ -170,21 +153,20 @@ TEST_F(EventManagerTest, EventManagerTest_queue_dispatch) {  		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_mgr.subscribe<MouseClickEvent>(mouse_handler1); +	event_mgr.subscribe<MouseClickEvent>(mouse_handler2, test_channel); -	event_manager.queue_event<MouseClickEvent>( +	event_mgr.queue_event<MouseClickEvent>(  		MouseClickEvent{.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE}); -	event_manager.queue_event<MouseClickEvent>( +	event_mgr.queue_event<MouseClickEvent>(  		MouseClickEvent{.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE},  		test_channel); -	event_manager.dispatch_events(); +	event_mgr.dispatch_events();  	EXPECT_TRUE(triggered1);  	EXPECT_TRUE(triggered2);  }  TEST_F(EventManagerTest, EventManagerTest_unsubscribe) { -	EventManager & event_manager = EventManager::get_instance();  	// Flags to track if handlers are triggered  	bool triggered1 = false; @@ -207,15 +189,15 @@ TEST_F(EventManagerTest, EventManagerTest_unsubscribe) {  		return false; // Allows propagation  	};  	// Subscribe handlers -	subscription_t handler1_id = event_manager.subscribe<MouseClickEvent>(mouse_handler1); -	subscription_t handler2_id = event_manager.subscribe<MouseClickEvent>(mouse_handler2); +	subscription_t handler1_id = event_mgr.subscribe<MouseClickEvent>(mouse_handler1); +	subscription_t handler2_id = event_mgr.subscribe<MouseClickEvent>(mouse_handler2);  	// Queue events -	event_manager.queue_event<MouseClickEvent>( +	event_mgr.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(); +	event_mgr.dispatch_events();  	EXPECT_TRUE(triggered1); // Handler 1 should be triggered  	EXPECT_TRUE(triggered2); // Handler 2 should be triggered @@ -224,14 +206,14 @@ TEST_F(EventManagerTest, EventManagerTest_unsubscribe) {  	triggered2 = false;  	// Unsubscribe handler1 -	event_manager.unsubscribe(handler1_id); +	event_mgr.unsubscribe(handler1_id);  	// Queue the same event again -	event_manager.queue_event<MouseClickEvent>( +	event_mgr.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(); +	event_mgr.dispatch_events();  	EXPECT_FALSE(triggered1); // Handler 1 should NOT be triggered  	EXPECT_TRUE(triggered2); // Handler 2 should be triggered @@ -239,14 +221,14 @@ TEST_F(EventManagerTest, EventManagerTest_unsubscribe) {  	triggered2 = false;  	// Unsubscribe handler2 -	event_manager.unsubscribe(handler2_id); +	event_mgr.unsubscribe(handler2_id);  	// Queue the event again -	event_manager.queue_event<MouseClickEvent>( +	event_mgr.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(); +	event_mgr.dispatch_events();  	EXPECT_FALSE(triggered1); // Handler 1 should NOT be triggered  	EXPECT_FALSE(triggered2); // Handler 2 should NOT be triggered  } diff --git a/src/test/LoopManagerTest.cpp b/src/test/LoopManagerTest.cpp index 503eb1f..57f7a2e 100644 --- a/src/test/LoopManagerTest.cpp +++ b/src/test/LoopManagerTest.cpp @@ -2,13 +2,11 @@  #include <gtest/gtest.h>  #include <gmock/gmock.h>  #include <thread> -#include <iostream>  #define private public  #define protected public -#include "api/LoopManager.h" -#include "api/LoopTimer.h" -#include "manager/EventManager.h" -#include "api/Event.h" +#include <crepe/api/LoopManager.h> +#include <crepe/manager/LoopTimerManager.h> +#include <crepe/manager/EventManager.h>  using namespace std::chrono;  using namespace crepe; @@ -24,19 +22,18 @@ protected:      TestGameLoop test_loop;  	// LoopManager test_loop;      void SetUp() override { -        test_loop.loop_timer->set_target_fps(10);      }  };  TEST_F(LoopManagerTest, FixedUpdate) {      // Arrange -    test_loop.loop_timer->set_target_fps(60); +    test_loop.loop_timer.set_target_fps(60);      // Set expectations for the mock calls      EXPECT_CALL(test_loop, render).Times(::testing::Exactly(60));   	EXPECT_CALL(test_loop, update).Times(::testing::Exactly(60)); -    EXPECT_CALL(test_loop, fixed_update).Times(::testing::AtLeast(50)); +    EXPECT_CALL(test_loop, fixed_update).Times(::testing::Exactly(50));      // Start the loop in a separate thread      std::thread loop_thread([&]() { test_loop.start(); }); @@ -46,12 +43,26 @@ TEST_F(LoopManagerTest, FixedUpdate) {      // Stop the game loop      test_loop.game_running = false; -      // Wait for the loop thread to finish      loop_thread.join();      // Test finished  } +TEST_F(LoopManagerTest, ShutDown) { +    // Arrange +    test_loop.loop_timer.set_target_fps(60); +	EXPECT_CALL(test_loop, render).Times(::testing::AtLeast(1));  +	EXPECT_CALL(test_loop, update).Times(::testing::AtLeast(1)); +    EXPECT_CALL(test_loop, fixed_update).Times(::testing::AtLeast(1)); +    // Start the loop in a separate thread +    std::thread loop_thread([&]() { test_loop.start(); }); +    std::this_thread::sleep_for(std::chrono::milliseconds(1)); +	test_loop.event_manager.trigger_event<ShutDownEvent>(ShutDownEvent{}); +    // Wait for the loop thread to finish +    loop_thread.join(); + +    // Test finished +} diff --git a/src/test/LoopTimerTest.cpp b/src/test/LoopTimerTest.cpp index 7652093..09b4e00 100644 --- a/src/test/LoopTimerTest.cpp +++ b/src/test/LoopTimerTest.cpp @@ -1,16 +1,17 @@  #include <chrono> -#include <gtest/gtest.h>  #include <thread> +#include <gtest/gtest.h>  #define private public  #define protected public -#include "api/LoopTimer.h" - +#include <crepe/manager/LoopTimerManager.h> +#include <crepe/manager/Mediator.h>  using namespace std::chrono;  using namespace crepe;  class LoopTimerTest : public ::testing::Test {  protected: -	LoopTimer loop_timer; +	Mediator mediator; +	LoopTimerManager loop_timer{mediator};  	void SetUp() override { loop_timer.start(); }  }; @@ -25,8 +26,7 @@ TEST_F(LoopTimerTest, EnforcesTargetFrameRate) {  	auto elapsed_ms = duration_cast<milliseconds>(elapsed_time).count();  	// For 60 FPS, the target frame time is around 16.67ms -	ASSERT_GE(elapsed_ms, 16); // Make sure it's at least 16 ms (could be slightly more) -	ASSERT_LE(elapsed_ms, 18); // Ensure it's not too much longer +	ASSERT_NEAR(elapsed_ms,16.7,1);  }  TEST_F(LoopTimerTest, SetTargetFps) {  	// Set the target FPS to 120 @@ -48,11 +48,10 @@ TEST_F(LoopTimerTest, DeltaTimeCalculation) {  	// Check the delta time  	double delta_time = loop_timer.get_delta_time(); -	auto elapsed_time = duration_cast<milliseconds>(end_time - start_time).count(); +	auto elapsed_time = duration_cast<seconds>(end_time - start_time).count();  	// Assert that delta_time is close to the elapsed time -	ASSERT_GE(delta_time, elapsed_time / 1000.0); -	ASSERT_LE(delta_time, (elapsed_time + 2) / 1000.0); +	ASSERT_NEAR(delta_time, elapsed_time, 1);  }  TEST_F(LoopTimerTest, getCurrentTime) { diff --git a/src/test/ScriptTest.h b/src/test/ScriptTest.h index 1bbfdd3..ee68c23 100644 --- a/src/test/ScriptTest.h +++ b/src/test/ScriptTest.h @@ -7,7 +7,7 @@  #include <crepe/api/Script.h>  #include <crepe/manager/ComponentManager.h>  #include <crepe/system/ScriptSystem.h> - +#include <crepe/manager/EventManager.h>  class ScriptTest : public testing::Test {  protected:  	crepe::Mediator mediator; @@ -15,7 +15,7 @@ protected:  public:  	crepe::ComponentManager component_manager{mediator};  	crepe::ScriptSystem system{mediator}; - +	crepe::EventManager event_mgr{mediator};  	class MyScript : public crepe::Script {  		// NOTE: explicitly stating `public:` is not required on actual scripts |