diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/crepe/api/LoopManager.h | 4 | ||||
| -rw-r--r-- | src/crepe/system/InputSystem.h | 84 | ||||
| -rw-r--r-- | src/test/LoopManagerTest.cpp | 56 | 
3 files changed, 115 insertions, 29 deletions
| diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h index 6a212eb..7097ee1 100644 --- a/src/crepe/api/LoopManager.h +++ b/src/crepe/api/LoopManager.h @@ -61,7 +61,7 @@ private:  	 *  	 * Updates the game state based on the elapsed time since the last frame.  	 */ -	void update(); +	virtual void update();  	/**  	 * \brief Late update which is called after update(). @@ -75,7 +75,7 @@ private:  	 *  	 * This function updates physics and game logic based on LoopTimer's fixed_delta_time.  	 */ -	void fixed_update(); +	virtual void fixed_update();  	/**  	 * \brief Function for executing render-related systems.  	 * diff --git a/src/crepe/system/InputSystem.h b/src/crepe/system/InputSystem.h new file mode 100644 index 0000000..0c42bd6 --- /dev/null +++ b/src/crepe/system/InputSystem.h @@ -0,0 +1,84 @@ +#pragma once + +#include "../facade/SDLContext.h" +#include "../types.h" +#include "../util/OptionalRef.h" + +#include "System.h" + +namespace crepe { + +class Camera; +class Button; +class Transform; + +/** + * \brief Handles the processing of input events created by SDLContext + * + * This system processes events such as mouse clicks, mouse movement, and keyboard + * actions. It is responsible for detecting interactions with UI buttons and + * passing the corresponding events to the registered listeners. + */ +class InputSystem : public System { +public: +	using System::System; + +	/** +     * \brief Updates the system, processing all input events. +     * This method processes all events and triggers corresponding actions. +     */ +	void update() override; + +private: +	//! Stores the last position of the mouse when the button was pressed. +	ivec2 last_mouse_down_position; + +	//! Stores the last mouse button pressed. +	MouseButton last_mouse_button = MouseButton::NONE; + +	//! The maximum allowable distance between mouse down and mouse up to register as a click. +	const int click_tolerance = 5; + +	/** +	* \brief Handles the mouse click event. +	* \param mouse_button The mouse button involved in the click. +	* \param world_mouse_x The X coordinate of the mouse in world space. +	* \param world_mouse_y The Y coordinate of the mouse in world space. +	* +	* This method processes the mouse click event and triggers the corresponding button action. +	*/ +	void handle_click(const MouseButton & mouse_button, const int world_mouse_x, +					  const int world_mouse_y); + +	/** +	* \brief Handles the mouse movement event. +	* \param event_data The event data containing information about the mouse movement. +	* \param world_mouse_x The X coordinate of the mouse in world space. +	* \param world_mouse_y The Y coordinate of the mouse in world space. +	* +	* This method processes the mouse movement event and updates the button hover state. +	*/ +	void handle_move(const SDLContext::EventData & event_data, const int world_mouse_x, +					 const int world_mouse_y); + +	/** +	* \brief Checks if the mouse position is inside the bounds of the button. +	* \param world_mouse_x The X coordinate of the mouse in world space. +	* \param world_mouse_y The Y coordinate of the mouse in world space. +	* \param button The button to check. +	* \param transform The transform component of the button. +	* \return True if the mouse is inside the button, false otherwise. +	*/ +	bool is_mouse_inside_button(const int world_mouse_x, const int world_mouse_y, +								const Button & button, const Transform & transform); + +	/** +	* \brief Handles the button press event, calling the on_click callback if necessary. +	* \param button The button being pressed. +	* +	* This method triggers the on_click action for the button when it is pressed. +	*/ +	void handle_button_press(Button & button); +}; + +} // namespace crepe diff --git a/src/test/LoopManagerTest.cpp b/src/test/LoopManagerTest.cpp index 5897906..f2ca8db 100644 --- a/src/test/LoopManagerTest.cpp +++ b/src/test/LoopManagerTest.cpp @@ -1,6 +1,8 @@  #include <chrono>  #include <gtest/gtest.h> +#include <gmock/gmock.h>  #include <thread> +  #define private public  #define protected public  #include "api/LoopManager.h" @@ -11,35 +13,35 @@ using namespace crepe;  class LoopManagerTest : public ::testing::Test {  protected: -	LoopManager loop_manager; +    class TestGameLoop : public crepe::LoopManager { +    public: +        MOCK_METHOD(void, fixed_update, (), (override)); +        MOCK_METHOD(void, update, (), (override)); +    }; + +    TestGameLoop test_loop; -	void SetUp() override { -		// Setting up loop manager and start the loop -		loop_manager.loop_timer->set_target_fps(60); -	} +    void SetUp() override { +        test_loop.loop_timer->set_target_fps(60); // Example target FPS +    }  }; -//Test to check if exactly 5 fixed updates are done every second (50Hz) +// Test to check if exactly 50 fixed updates occur in 1 second (50Hz)  TEST_F(LoopManagerTest, FixedUpdate) { -	loop_manager.loop_timer->fixed_delta_time = std::chrono::milliseconds(20); -	loop_manager.loop_timer->set_target_fps(50); -	int fixed_update_count = 0; -	loop_manager.loop_timer->start(); -	// We want to simulate the game loop for about 1 second -	auto start_time = steady_clock::now(); - -	// Simulate the game loop for 1 second -	while (duration_cast<milliseconds>(steady_clock::now() - start_time) -		   < std::chrono::milliseconds(1000)) { -		loop_manager.loop_timer->update(); -		// Simulate processing fixed updates while there's lag to advance -		while (loop_manager.loop_timer->get_lag() -			   >= loop_manager.loop_timer->get_fixed_delta_time()) { -			fixed_update_count++; -			loop_manager.loop_timer->advance_fixed_update(); -		} - -		loop_manager.loop_timer->enforce_frame_rate(); -	} -	ASSERT_EQ(fixed_update_count, 50); +    // Arrange +    using ::testing::AtLeast; +    using ::testing::Exactly; + +    test_loop.loop_timer->fixed_delta_time = std::chrono::milliseconds(20); +	test_loop.start(); +    // Expect the `fixed_update` method to be called exactly 50 times +    EXPECT_CALL(test_loop, fixed_update()).Times(Exactly(50)); + +    auto start_time = steady_clock::now(); + +    // Act: Simulate the game loop for 1 second +    while (duration_cast<milliseconds>(steady_clock::now() - start_time) < std::chrono::milliseconds(1000)) { + +    } +	test_loop.game_running = false;  } |