Helios Engine 0.1.0
A modular ECS based data-oriented C++23 game engine
 
Loading...
Searching...
No Matches
time.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <helios/core_pch.hpp>
4
6
7#include <chrono>
8#include <cstdint>
9#include <string_view>
10
11namespace helios::app {
12
13/**
14 * @brief Resource for tracking frame timing information.
15 * @details Provides delta time (time since last frame), total elapsed time, and frame count.
16 * Updated automatically by the engine before each frame.
17 * @note Thread-safe for read operations. Written only by the runner before Update().
18 *
19 * @example
20 * @code
21 * void MovementSystem(SystemContext& ctx) {
22 * const auto& time = ctx.ReadResource<Time>();
23 * auto query = ctx.Query().Get<Position&, const Velocity&>();
24 * for (auto&& [entity, pos, vel] : query) {
25 * pos.x += vel.x * time.DeltaSeconds();
26 * pos.y += vel.y * time.DeltaSeconds();
27 * }
28 * }
29 * @endcode
30 */
31class Time {
32public:
33 using ClockType = std::chrono::steady_clock;
34 using TimePoint = ClockType::time_point;
35 using Duration = ClockType::duration;
36
37 /**
38 * @brief Default constructor.
39 * @details Initializes time with zero delta and records start time.
40 */
41 constexpr Time() noexcept = default;
42 constexpr Time(const Time&) noexcept = default;
43 constexpr Time(Time&&) noexcept = default;
44 constexpr ~Time() noexcept = default;
45
46 constexpr Time& operator=(const Time&) noexcept = default;
47 constexpr Time& operator=(Time&&) noexcept = default;
48
49 /**
50 * @brief Updates timing information for a new frame.
51 * @details Should be called at the beginning of each frame by the runner.
52 * Calculates delta time based on the time since last update.
53 */
54 void Tick() noexcept;
55
56 /**
57 * @brief Resets all timing information.
58 * @details Sets delta to zero, resets elapsed time, and resets frame count.
59 */
60 void Reset() noexcept;
61
62 /**
63 * @brief Checks if this is the first frame.
64 * @return True if frame count is 0
65 */
66 [[nodiscard]] constexpr bool IsFirstFrame() const noexcept { return frame_count_ == 0; }
67
68 /**
69 * @brief Gets the raw delta duration.
70 * @return Delta time as std::chrono::duration
71 */
72 [[nodiscard]] constexpr Duration Delta() const noexcept { return delta_; }
73
74 /**
75 * @brief Gets the time elapsed since the last frame in seconds.
76 * @return Delta time in seconds as float
77 */
78 [[nodiscard]] constexpr float DeltaSeconds() const noexcept { return delta_seconds_; }
79
80 /**
81 * @brief Gets the time elapsed since the last frame in milliseconds.
82 * @return Delta time in milliseconds as float
83 */
84 [[nodiscard]] constexpr float DeltaMilliseconds() const noexcept { return delta_seconds_ * 1000.0F; }
85
86 /**
87 * @brief Gets the total elapsed time since timing started.
88 * @return Total elapsed time as std::chrono::duration
89 */
90 [[nodiscard]] constexpr Duration Elapsed() const noexcept { return elapsed_; }
91
92 /**
93 * @brief Gets the total elapsed time since timing started in seconds.
94 * @return Total elapsed time in seconds as float
95 */
96 [[nodiscard]] constexpr float ElapsedSeconds() const noexcept { return elapsed_seconds_; }
97
98 /**
99 * @brief Gets the current frame number.
100 * @details Incremented each time Tick() is called.
101 * @return Current frame count (0-indexed, first frame is 0)
102 */
103 [[nodiscard]] constexpr uint64_t FrameCount() const noexcept { return frame_count_; }
104
105 /**
106 * @brief Calculates the current frames per second.
107 * @details Based on the current delta time.
108 * @return FPS as float, or 0 if delta is zero
109 */
110 [[nodiscard]] constexpr float Fps() const noexcept { return delta_seconds_ > 0.0F ? 1.0F / delta_seconds_ : 0.0F; }
111
112 /**
113 * @brief Gets the resource name for trait requirements.
114 * @return Resource name
115 */
116 static constexpr std::string_view GetName() noexcept { return "Time"; }
117
118private:
119 TimePoint last_tick_{ClockType::now()}; ///< Time point of the last tick
120 TimePoint start_time_{ClockType::now()}; ///< Time point when timing started
121
122 Duration delta_{Duration::zero()}; ///< Duration since last frame
123 Duration elapsed_{Duration::zero()}; ///< Total elapsed duration
124
125 float delta_seconds_ = 0.0F; ///< Delta time in seconds (cached for performance)
126 float elapsed_seconds_ = 0.0F; ///< Elapsed time in seconds (cached for performance)
127
128 uint64_t frame_count_ = 0; ///< Number of frames since timing started
129};
130
131inline void Time::Tick() noexcept {
132 const TimePoint now = ClockType::now();
133
134 delta_ = now - last_tick_;
135 elapsed_ = now - start_time_;
136
137 delta_seconds_ = std::chrono::duration<float>(delta_).count();
138 elapsed_seconds_ = std::chrono::duration<float>(elapsed_).count();
139
140 last_tick_ = now;
141 ++frame_count_;
142}
143
144inline void Time::Reset() noexcept {
145 const TimePoint now = ClockType::now();
146
147 last_tick_ = now;
148 start_time_ = now;
149 delta_ = Duration::zero();
150 elapsed_ = Duration::zero();
151 delta_seconds_ = 0.0F;
152 elapsed_seconds_ = 0.0F;
153 frame_count_ = 0;
154}
155
156// Ensure Time satisfies ResourceTrait
157static_assert(ecs::ResourceTrait<Time>, "Time must satisfy ResourceTrait");
158
159} // namespace helios::app
constexpr uint64_t FrameCount() const noexcept
Gets the current frame number.
Definition time.hpp:103
constexpr bool IsFirstFrame() const noexcept
Checks if this is the first frame.
Definition time.hpp:66
constexpr float DeltaSeconds() const noexcept
Gets the time elapsed since the last frame in seconds.
Definition time.hpp:78
constexpr float Fps() const noexcept
Calculates the current frames per second.
Definition time.hpp:110
constexpr Duration Delta() const noexcept
Gets the raw delta duration.
Definition time.hpp:72
constexpr float DeltaMilliseconds() const noexcept
Gets the time elapsed since the last frame in milliseconds.
Definition time.hpp:84
constexpr Time() noexcept=default
Default constructor.
std::chrono::steady_clock ClockType
Definition time.hpp:33
void Tick() noexcept
Updates timing information for a new frame.
Definition time.hpp:131
ClockType::duration Duration
Definition time.hpp:35
constexpr float ElapsedSeconds() const noexcept
Gets the total elapsed time since timing started in seconds.
Definition time.hpp:96
ClockType::time_point TimePoint
Definition time.hpp:34
void Reset() noexcept
Resets all timing information.
Definition time.hpp:144
static constexpr std::string_view GetName() noexcept
Gets the resource name for trait requirements.
Definition time.hpp:116
constexpr Duration Elapsed() const noexcept
Gets the total elapsed time since timing started.
Definition time.hpp:90
Concept for valid resource types.
Definition resource.hpp:21