#pragma once #include namespace crepe{ class LoopTimer { public: /** * \brief Get the singleton instance of LoopTimer. * * \return A reference to the LoopTimer instance. */ static LoopTimer& get_instance(); /** * \brief Get the current delta time for the current frame. * * \return Delta time in seconds since the last frame. */ double get_delta_time() const; /** * \brief Get the current game time. * * \note The current game time may vary from the real-world elapsed time. * It is the cumulative sum of each frame's delta time. * * \return Elapsed game time in milliseconds. */ int get_current_time() const; /** * \brief Set the target frames per second (FPS). * * \param fps The number of frames that should be rendered per second. */ void set_fps(int fps); /** * \brief Get the current frames per second (FPS). * * \return Current FPS. */ int get_fps() const; /** * \brief Get the current game scale. * * \return The current game scale, where 0 = paused, 1 = normal speed, and values > 1 speed up the game. */ double get_game_scale() const; /** * \brief Set the game scale. * * \param game_scale The desired game scale (0 = pause, 1 = normal speed, > 1 = speed up). */ void set_game_scale(double game_scale); private: friend class LoopManager; /** * \brief Start the loop timer. * * Initializes the timer to begin tracking frame times. */ void start(); /** * \brief Enforce the frame rate limit. * * Ensures that the game loop does not exceed the target FPS by delaying * frame updates as necessary. */ void enforce_frame_rate(); /** * \brief Get the fixed delta time for consistent updates. * * Fixed delta time is used for operations that require uniform time steps, * such as physics calculations. * * \return Fixed delta time in seconds. */ double get_fixed_delta_time() const; /** * \brief Get the accumulated lag in the game loop. * * Lag represents the difference between the target frame time and the * actual frame time, useful for managing fixed update intervals. * * \return Accumulated lag in seconds. */ double get_lag() const; /** * \brief Construct a new LoopTimer object. * * Private constructor for singleton pattern to restrict instantiation * outside the class. */ LoopTimer(); /** * \brief Update the timer to the current frame. * * Calculates and updates the delta time for the current frame and adds it to * the cumulative game time. */ void update(); /** * \brief Advance the game loop by a fixed update interval. * * This method progresses the game state by a consistent, fixed time step, * allowing for stable updates independent of frame rate fluctuations. */ void advance_fixed_update(); private: //! Current frames per second int fps = 50; ///< Current game scale double game_scale = 1; //! Maximum delta time to avoid large jumps double maximum_delta_time = 0.25; //! Delta time for the current frame double delta_time = 0; //! Target time per frame in seconds double frame_target_time = 1.0 / fps; //! Fixed delta time for fixed updates double fixed_delta_time = 0.02; //! Total elapsed game time double elapsed_time = 0; //! Total elapsed time for fixed updates double elapsed_fixed_time = 0; //! Time of the last frame uint64_t last_frame_time = 0; }; } // namespace crepe