LCOV - code coverage report
Current view: top level - engine/time/internal - clock.hpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 33 33
Test Date: 2026-03-11 04:45:14 Functions: 100.0 % 14 14

            Line data    Source code
       1              : #pragma once
       2              : 
       3              : #include <jage/engine/memory/cacheline_size.hpp>
       4              : #include <jage/engine/time/events/snapshot.hpp>
       5              : #include <jage/engine/time/hertz.hpp>
       6              : 
       7              : #include <jage/engine/time/internal/concepts/real_number_time_source.hpp>
       8              : 
       9              : #include <cmath>
      10              : #include <cstdint>
      11              : #include <stdexcept>
      12              : 
      13              : namespace jage::engine::time::internal {
      14              : 
      15              : template <internal::concepts::real_number_time_source TTimeSource>
      16              :   requires(TTimeSource::is_steady)
      17              : class clock {
      18              :   using duration_ = typename TTimeSource::duration;
      19              :   using snapshot_ = events::snapshot<duration_>;
      20              :   static_assert(memory::cacheline_size >= sizeof(snapshot_));
      21              :   static_assert(alignof(snapshot_) == memory::cacheline_size);
      22              :   static_assert(sizeof(snapshot_) % memory::cacheline_size == 0);
      23              :   duration_ elapsed_time_{};
      24              :   duration_ tick_duration_{};
      25              :   std::uint64_t elapsed_ticks_{};
      26              :   double time_scale_{1.0};
      27              : 
      28              :   [[nodiscard]] auto
      29           52 :   ticks(const duration_ current_time) const -> std::uint64_t {
      30           52 :     const auto accumulated_time = current_time - elapsed_time_;
      31           52 :     return static_cast<std::uint64_t>(
      32           52 :                std::floor(accumulated_time.count() / tick_duration_.count())) +
      33           52 :            elapsed_ticks_;
      34              :   }
      35              : 
      36              : public:
      37              :   using duration_type = duration_;
      38              :   using snapshot_type = snapshot_;
      39              : 
      40            8 :   constexpr clock(const hertz &cycles)
      41            8 :       : tick_duration_{static_cast<duration_type>(cycles)} {};
      42              : 
      43           67 :   [[nodiscard]] auto real_time() const -> duration_type {
      44           67 :     return TTimeSource::now().time_since_epoch();
      45              :   }
      46              : 
      47           42 :   [[nodiscard]] auto ticks() const -> std::uint64_t {
      48           42 :     return ticks(real_time() * time_scale_);
      49              :   }
      50              : 
      51            6 :   [[nodiscard]] auto game_time() const -> duration_type {
      52            6 :     return duration_type{ticks() * tick_duration_.count()};
      53              :   }
      54              : 
      55              :   [[nodiscard]] constexpr auto
      56            6 :   tick_duration() const noexcept -> const duration_type & {
      57            6 :     return tick_duration_;
      58              :   }
      59              : 
      60           13 :   auto set_time_scale(const double scale) -> void {
      61           13 :     if (scale < 0.0) [[unlikely]] {
      62            1 :       throw std::invalid_argument(
      63              :           "Refusing to set time scale to a negative value.");
      64              :     }
      65           12 :     elapsed_ticks_ = ticks();
      66           12 :     elapsed_time_ = real_time() * scale;
      67              : 
      68           12 :     time_scale_ = scale;
      69           12 :   }
      70              : 
      71           10 :   [[nodiscard]] auto snapshot() const -> snapshot_type {
      72           10 :     const auto current_real_time = real_time();
      73           10 :     const auto scaled_real_time = current_real_time * time_scale_;
      74           10 :     const auto accumulated_time = scaled_real_time - elapsed_time_;
      75           10 :     const auto accumulated_ticks =
      76           10 :         std::floor(accumulated_time / tick_duration_);
      77           10 :     const auto current_ticks = ticks(scaled_real_time);
      78              :     return {
      79              :         .real_time = current_real_time,
      80              :         .tick_duration = tick_duration_,
      81           10 :         .time_scale = time_scale_,
      82              :         .elapsed_time = elapsed_time_,
      83           10 :         .elapsed_frames = elapsed_ticks_,
      84              :         .frame = current_ticks,
      85              :         .accumulated_time =
      86           20 :             accumulated_time - accumulated_ticks * tick_duration_,
      87           20 :     };
      88              :   }
      89              : };
      90              : 
      91              : } // namespace jage::engine::time::internal
        

Generated by: LCOV version 2.0-1