diff options
-rw-r--r-- | src/crepe/api/LoopManager.cpp | 12 | ||||
-rw-r--r-- | src/crepe/api/LoopManager.h | 5 | ||||
-rw-r--r-- | src/crepe/api/LoopTimer.cpp | 27 | ||||
-rw-r--r-- | src/crepe/api/LoopTimer.h | 6 | ||||
-rw-r--r-- | src/test/LoopManagerTest.cpp | 46 | ||||
-rw-r--r-- | src/test/LoopTimerTest.cpp | 87 |
6 files changed, 87 insertions, 96 deletions
diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index 040cb93..5879d79 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -1,12 +1,12 @@ #include "../facade/SDLContext.h" +#include "../manager/EventManager.h" #include "../system/AnimatorSystem.h" #include "../system/CollisionSystem.h" #include "../system/ParticleSystem.h" #include "../system/PhysicsSystem.h" #include "../system/RenderSystem.h" #include "../system/ScriptSystem.h" -#include "../manager/EventManager.h" #include "LoopManager.h" @@ -20,9 +20,8 @@ LoopManager::LoopManager() { this->load_system<PhysicsSystem>(); this->load_system<RenderSystem>(); this->load_system<ScriptSystem>(); - EventManager::get_instance().subscribe<ShutDownEvent>([this](const ShutDownEvent& event) { - return this->on_shutdown(event); - }); + EventManager::get_instance().subscribe<ShutDownEvent>( + [this](const ShutDownEvent & event) { return this->on_shutdown(event); }); this->loop_timer = make_unique<LoopTimer>(); this->mediator.loop_timer = *loop_timer; } @@ -41,7 +40,7 @@ void LoopManager::loop() { while (game_running) { this->loop_timer->update(); - + while (this->loop_timer->get_lag() >= this->loop_timer->get_fixed_delta_time()) { this->process_input(); this->fixed_update(); @@ -55,7 +54,6 @@ void LoopManager::loop() { } void LoopManager::setup() { - this->game_running = true; this->loop_timer->start(); @@ -67,7 +65,7 @@ void LoopManager::render() { this->get_system<RenderSystem>().update(); } -bool LoopManager::on_shutdown(const ShutDownEvent & e){ +bool LoopManager::on_shutdown(const ShutDownEvent & e) { this->game_running = false; return false; } diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h index c50f5aa..6a212eb 100644 --- a/src/crepe/api/LoopManager.h +++ b/src/crepe/api/LoopManager.h @@ -5,10 +5,8 @@ #include "../facade/SDLContext.h" #include "../manager/ComponentManager.h" #include "../manager/SceneManager.h" -#include "../manager/SceneManager.h" #include "../system/System.h" - #include "api/Event.h" #include "api/LoopTimer.h" @@ -28,7 +26,6 @@ public: * Developers need to call this function to run the game. */ void start(); - /** * \brief Add a new concrete scene to the scene manager @@ -101,8 +98,8 @@ private: SDLContext & sdl_context = SDLContext::get_instance(); //! loop timer instance std::unique_ptr<LoopTimer> loop_timer; + private: - /** * \brief Callback function for ShutDownEvent * diff --git a/src/crepe/api/LoopTimer.cpp b/src/crepe/api/LoopTimer.cpp index eedb5ee..8fb7ce8 100644 --- a/src/crepe/api/LoopTimer.cpp +++ b/src/crepe/api/LoopTimer.cpp @@ -10,13 +10,13 @@ using namespace crepe; LoopTimer::LoopTimer() { dbg_trace(); } - void LoopTimer::start() { this->last_frame_time = std::chrono::steady_clock::now(); - + this->elapsed_time = std::chrono::milliseconds(0); // by starting the elapsed_fixed_time at (0 - fixed_delta_time) in milliseconds it calls a fixed update at the start of the loop. - this->elapsed_fixed_time = -std::chrono::duration_cast<std::chrono::milliseconds>(fixed_delta_time); + this->elapsed_fixed_time + = -std::chrono::duration_cast<std::chrono::milliseconds>(fixed_delta_time); this->delta_time = std::chrono::milliseconds(0); } @@ -30,7 +30,7 @@ void LoopTimer::update() { this->delta_time = this->maximum_delta_time; } 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; @@ -56,17 +56,18 @@ void LoopTimer::set_game_scale(double value) { this->game_scale = value; } double LoopTimer::get_game_scale() const { return this->game_scale; } void LoopTimer::enforce_frame_rate() { - auto current_frame_time = std::chrono::steady_clock::now(); - auto frame_duration = current_frame_time - this->last_frame_time; + auto current_frame_time = std::chrono::steady_clock::now(); + auto frame_duration = current_frame_time - this->last_frame_time; - // Check if frame duration is less than the target frame time - if (frame_duration < this->frame_target_time) { - auto delay_time = std::chrono::duration_cast<std::chrono::microseconds>(this->frame_target_time - frame_duration); + // Check if frame duration is less than the target frame time + if (frame_duration < this->frame_target_time) { + auto delay_time = std::chrono::duration_cast<std::chrono::microseconds>( + this->frame_target_time - frame_duration); - if (delay_time.count() > 0) { - std::this_thread::sleep_for(delay_time); - } - } + if (delay_time.count() > 0) { + std::this_thread::sleep_for(delay_time); + } + } } double LoopTimer::get_lag() const { diff --git a/src/crepe/api/LoopTimer.h b/src/crepe/api/LoopTimer.h index e348628..c4294d7 100644 --- a/src/crepe/api/LoopTimer.h +++ b/src/crepe/api/LoopTimer.h @@ -90,8 +90,6 @@ private: */ double get_lag() const; - - /** * \brief Update the timer to the current frame. * @@ -120,7 +118,8 @@ private: //! Delta time for the current frame in seconds std::chrono::duration<double> delta_time{0.0}; //! Target time per frame in seconds - std::chrono::duration<double> frame_target_time = std::chrono::duration<double>(1.0) / target_fps; + std::chrono::duration<double> frame_target_time + = std::chrono::duration<double>(1.0) / target_fps; //! Fixed delta time for fixed updates in seconds std::chrono::duration<double> fixed_delta_time = std::chrono::duration<double>(1.0) / 50.0; //! Total elapsed game time in seconds @@ -129,7 +128,6 @@ private: std::chrono::duration<double> elapsed_fixed_time{0.0}; //! Time of the last frame std::chrono::steady_clock::time_point last_frame_time; - }; } // namespace crepe diff --git a/src/test/LoopManagerTest.cpp b/src/test/LoopManagerTest.cpp index 7937649..5897906 100644 --- a/src/test/LoopManagerTest.cpp +++ b/src/test/LoopManagerTest.cpp @@ -1,43 +1,45 @@ -#include <gtest/gtest.h> #include <chrono> +#include <gtest/gtest.h> #include <thread> #define private public #define protected public -#include "api/LoopTimer.h" #include "api/LoopManager.h" +#include "api/LoopTimer.h" using namespace std::chrono; using namespace crepe; class LoopManagerTest : public ::testing::Test { protected: - LoopManager loop_manager; + LoopManager loop_manager; - void SetUp() override { - // Setting up loop manager and start the loop - loop_manager.loop_timer->set_target_fps(60); - } + void SetUp() override { + // Setting up loop manager and start the loop + loop_manager.loop_timer->set_target_fps(60); + } }; //Test to check if exactly 5 fixed updates are done every second (50Hz) TEST_F(LoopManagerTest, FixedUpdate) { - loop_manager.loop_timer->fixed_delta_time = std::chrono::milliseconds(20); + loop_manager.loop_timer->fixed_delta_time = std::chrono::milliseconds(20); loop_manager.loop_timer->set_target_fps(50); - int fixed_update_count = 0; + 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(); + // 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)) { + // 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); + // 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); } diff --git a/src/test/LoopTimerTest.cpp b/src/test/LoopTimerTest.cpp index 6e3f118..9068c72 100644 --- a/src/test/LoopTimerTest.cpp +++ b/src/test/LoopTimerTest.cpp @@ -1,5 +1,5 @@ -#include <gtest/gtest.h> #include <chrono> +#include <gtest/gtest.h> #include <thread> #define private public #define protected public @@ -10,72 +10,67 @@ using namespace crepe; class LoopTimerTest : public ::testing::Test { protected: - LoopTimer loop_timer; + LoopTimer loop_timer; - void SetUp() override { - loop_timer.start(); - } + void SetUp() override { loop_timer.start(); } }; TEST_F(LoopTimerTest, EnforcesTargetFrameRate) { - // Set the target FPS to 60 (which gives a target time per frame of ~16.67 ms) - loop_timer.set_target_fps(60); + // Set the target FPS to 60 (which gives a target time per frame of ~16.67 ms) + loop_timer.set_target_fps(60); - auto start_time = steady_clock::now(); - loop_timer.enforce_frame_rate(); + auto start_time = steady_clock::now(); + loop_timer.enforce_frame_rate(); - auto elapsed_time = steady_clock::now() - start_time; - auto elapsed_ms = duration_cast<milliseconds>(elapsed_time).count(); + auto elapsed_time = steady_clock::now() - start_time; + 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 + // 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 } TEST_F(LoopTimerTest, SetTargetFps) { - // Set the target FPS to 120 - loop_timer.set_target_fps(120); - - // Calculate the expected frame time (~8.33ms per frame) - auto expected_frame_time = std::chrono::duration<double>(1.0 / 120.0); + // Set the target FPS to 120 + loop_timer.set_target_fps(120); - ASSERT_NEAR(loop_timer.frame_target_time.count(), expected_frame_time.count(), 0.001); + // Calculate the expected frame time (~8.33ms per frame) + auto expected_frame_time = std::chrono::duration<double>(1.0 / 120.0); + + ASSERT_NEAR(loop_timer.frame_target_time.count(), expected_frame_time.count(), 0.001); } TEST_F(LoopTimerTest, DeltaTimeCalculation) { - // Set the target FPS to 60 (16.67 ms per frame) - loop_timer.set_target_fps(60); + // Set the target FPS to 60 (16.67 ms per frame) + loop_timer.set_target_fps(60); + + auto start_time = steady_clock::now(); + loop_timer.update(); + auto end_time = steady_clock::now(); - auto start_time = steady_clock::now(); - loop_timer.update(); - auto end_time = steady_clock::now(); + // Check the delta time + double delta_time = loop_timer.get_delta_time(); - // 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<milliseconds>(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 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); } TEST_F(LoopTimerTest, getCurrentTime) { - // Set the target FPS to 60 (16.67 ms per frame) - loop_timer.set_target_fps(60); + // Set the target FPS to 60 (16.67 ms per frame) + loop_timer.set_target_fps(60); - auto start_time = steady_clock::now(); + auto start_time = steady_clock::now(); - // Sleep for 500 milliseconds - std::this_thread::sleep_for(std::chrono::milliseconds(100)); + // Sleep for 500 milliseconds + std::this_thread::sleep_for(std::chrono::milliseconds(100)); - loop_timer.update(); + loop_timer.update(); - auto end_time = steady_clock::now(); + auto end_time = steady_clock::now(); - // Get the elapsed time in seconds as a double - auto elapsed_time = duration_cast<std::chrono::duration<double>>(end_time - start_time).count(); + // Get the elapsed time in seconds as a double + auto elapsed_time + = duration_cast<std::chrono::duration<double>>(end_time - start_time).count(); - ASSERT_NEAR(loop_timer.get_current_time(), elapsed_time, 0.001); - - + ASSERT_NEAR(loop_timer.get_current_time(), elapsed_time, 0.001); } - - |