LCOV - code coverage report
Current view: top level - src/core - FixedTimestepLoop.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 92.3 % 26 24
Test Date: 2026-04-10 19:03:25 Functions: 100.0 % 2 2

            Line data    Source code
       1              : /*
       2              :  * Copyright (C) 2025 aeml
       3              :  *
       4              :  * This program is free software: you can redistribute it and/or modify
       5              :  * it under the terms of the GNU General Public License as published by
       6              :  * the Free Software Foundation, either version 3 of the License, or
       7              :  * (at your option) any later version.
       8              :  *
       9              :  * This program is distributed in the hope that it will be useful,
      10              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12              :  * GNU General Public License for more details.
      13              :  *
      14              :  * You should have received a copy of the GNU General Public License
      15              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      16              :  */
      17              : 
      18              : #include "core/FixedTimestepLoop.hpp"
      19              : #include "core/Clock.hpp"
      20              : 
      21              : #include <algorithm>
      22              : #include <chrono>
      23              : #include <cmath>
      24              : #include <thread>
      25              : 
      26              : namespace core
      27              : {
      28           20 :     FixedTimestepLoop::FixedTimestepLoop(float timestepSeconds) noexcept
      29           20 :         : m_timestepSeconds(timestepSeconds)
      30              :     {
      31           20 :     }
      32              : 
      33           14 :     void FixedTimestepLoop::Run(const std::function<void(float)>& update,
      34              :                                 std::atomic<bool>&                 runningFlag) const
      35              :     {
      36           14 :         const double timestep = std::max(1e-6, static_cast<double>(m_timestepSeconds));
      37           14 :         const double maxFrameTime = 0.25;
      38           14 :         const int maxUpdatesPerTick = 8;
      39           14 :         double        previous = Clock::NowSeconds();
      40           14 :         double        accumulator = 0.0;
      41              : 
      42          411 :         while (runningFlag.load())
      43              :         {
      44          400 :             const double current = Clock::NowSeconds();
      45          400 :             const double frameTime = std::clamp(current - previous, 0.0, maxFrameTime);
      46          400 :             previous = current;
      47          400 :             accumulator += frameTime;
      48              : 
      49          400 :             int updatesThisTick = 0;
      50          424 :             while (accumulator >= timestep && updatesThisTick < maxUpdatesPerTick)
      51              :             {
      52           27 :                 if (!runningFlag.load())
      53              :                 {
      54            0 :                     break;
      55              :                 }
      56              : 
      57           27 :                 update(m_timestepSeconds);
      58           24 :                 accumulator -= timestep;
      59           24 :                 ++updatesThisTick;
      60              :             }
      61              : 
      62          397 :             if (updatesThisTick == maxUpdatesPerTick && accumulator >= timestep)
      63              :             {
      64            0 :                 accumulator = std::fmod(accumulator, timestep);
      65              :             }
      66              : 
      67          397 :             if (accumulator < timestep)
      68              :             {
      69          397 :                 std::this_thread::sleep_for(std::chrono::milliseconds(1));
      70              :             }
      71              :         }
      72           11 :     }
      73              : }
        

Generated by: LCOV version 2.0-1