Time Shield Library 2.0.0
C++ library for working with time
Loading...
Searching...
No Matches
DeadlineTimer.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2#pragma once
3#ifndef TIME_SHIELD_HEADER_TIMERS_DEADLINETIMER_HPP_INCLUDED
4#define TIME_SHIELD_HEADER_TIMERS_DEADLINETIMER_HPP_INCLUDED
5
12
13#include <time_shield/core.hpp>
14
15#include <chrono>
16
17namespace time_shield {
18
26 public:
27 using clock = std::chrono::steady_clock;
28 using duration = clock::duration;
29 using time_point = clock::time_point;
30
32 DeadlineTimer() noexcept = default;
33
35 explicit DeadlineTimer(time_point deadline) noexcept {
37 }
38
40 template<class Rep, class Period>
41 explicit DeadlineTimer(std::chrono::duration<Rep, Period> timeout) noexcept {
42 start(timeout);
43 }
44
46 explicit DeadlineTimer(ts_ms_t timeout_ms) noexcept {
47 start_ms(timeout_ms);
48 }
49
51 static DeadlineTimer from_timeout(duration timeout) noexcept {
52 DeadlineTimer timer;
53 timer.start(timeout);
54 return timer;
55 }
56
58 template<class Rep, class Period>
59 static DeadlineTimer from_timeout(std::chrono::duration<Rep, Period> timeout) noexcept {
60 DeadlineTimer timer;
61 timer.start(timeout);
62 return timer;
63 }
64
66 static DeadlineTimer from_timeout_sec(ts_t timeout_sec) noexcept {
67 DeadlineTimer timer;
68 timer.start_sec(timeout_sec);
69 return timer;
70 }
71
73 static DeadlineTimer from_timeout_ms(ts_ms_t timeout_ms) noexcept {
74 DeadlineTimer timer;
75 timer.start_ms(timeout_ms);
76 return timer;
77 }
78
80 void start(time_point deadline) noexcept {
82 m_is_running = true;
83 }
84
90 template<class Rep, class Period>
91 void start(std::chrono::duration<Rep, Period> timeout) noexcept {
92 const time_point now = clock::now();
93 if (timeout <= decltype(timeout)::zero()) {
94 start(now);
95 return;
96 }
97
98 duration safe_duration = std::chrono::duration_cast<duration>(timeout);
99 if (safe_duration <= duration::zero()) {
100 safe_duration = duration(1);
101 }
102
103 const time_point max_time = (time_point::max)();
104 const duration max_offset = max_time - now;
105 if (safe_duration >= max_offset) {
106 start(max_time);
107 return;
108 }
109
110 start(now + safe_duration);
111 }
112
114 void start_sec(ts_t timeout_sec) noexcept {
115 start(std::chrono::seconds(timeout_sec));
116 }
117
119 void start_ms(ts_ms_t timeout_ms) noexcept {
120 start(std::chrono::milliseconds(timeout_ms));
121 }
122
124 void stop() noexcept {
125 m_is_running = false;
127 }
128
130 void set_forever() noexcept {
131 m_is_running = true;
132 m_deadline = (time_point::max)();
133 }
134
136 TIME_SHIELD_NODISCARD bool is_running() const noexcept {
137 return m_is_running;
138 }
139
141 TIME_SHIELD_NODISCARD bool is_forever() const noexcept {
142 return m_is_running && m_deadline == (time_point::max)();
143 }
144
146 TIME_SHIELD_NODISCARD time_point deadline() const noexcept {
147 return m_deadline;
148 }
149
151 TIME_SHIELD_NODISCARD ts_ms_t deadline_ms() const noexcept {
152 return std::chrono::duration_cast<std::chrono::milliseconds>(m_deadline.time_since_epoch()).count();
153 }
154
156 TIME_SHIELD_NODISCARD ts_t deadline_sec() const noexcept {
157 return std::chrono::duration_cast<std::chrono::seconds>(m_deadline.time_since_epoch()).count();
158 }
159
161 TIME_SHIELD_NODISCARD bool has_expired() const noexcept {
162 return has_expired(clock::now());
163 }
164
166 TIME_SHIELD_NODISCARD bool has_expired_ms(ts_ms_t now_ms) const noexcept {
167 const duration since_epoch = std::chrono::duration_cast<duration>(std::chrono::milliseconds(now_ms));
168 return has_expired(time_point(since_epoch));
169 }
170
172 TIME_SHIELD_NODISCARD bool has_expired_sec(ts_t now_sec) const noexcept {
173 const duration since_epoch = std::chrono::duration_cast<duration>(std::chrono::seconds(now_sec));
174 return has_expired(time_point(since_epoch));
175 }
176
178 TIME_SHIELD_NODISCARD bool has_expired(time_point now) const noexcept {
179 return m_is_running && now >= m_deadline;
180 }
181
183 TIME_SHIELD_NODISCARD duration remaining_time() const noexcept {
184 return remaining_time(clock::now());
185 }
186
188 TIME_SHIELD_NODISCARD ts_ms_t remaining_time_ms() const noexcept {
189 return std::chrono::duration_cast<std::chrono::milliseconds>(remaining_time()).count();
190 }
191
193 TIME_SHIELD_NODISCARD ts_t remaining_time_sec() const noexcept {
194 return std::chrono::duration_cast<std::chrono::seconds>(remaining_time()).count();
195 }
196
200 TIME_SHIELD_NODISCARD duration remaining_time(time_point now) const noexcept {
201 if (!m_is_running || now >= m_deadline) {
202 return duration::zero();
203 }
204 return m_deadline - now;
205 }
206
208 void add(duration extend_by) noexcept {
209 if (!m_is_running || extend_by <= duration::zero()) {
210 return;
211 }
212
213 const time_point now = clock::now();
214 const time_point base = m_deadline > now ? m_deadline : now;
215 const duration max_offset = (time_point::max)() - base;
216 const duration safe_offset = extend_by < max_offset ? extend_by : max_offset;
217 m_deadline = base + safe_offset;
218 }
219
221 void add_sec(ts_t extend_by_sec) noexcept {
222 if (extend_by_sec <= 0) {
223 return;
224 }
225 add(std::chrono::seconds(extend_by_sec));
226 }
227
229 void add_ms(ts_ms_t extend_by_ms) noexcept {
230 if (extend_by_ms <= 0) {
231 return;
232 }
233 add(std::chrono::milliseconds(extend_by_ms));
234 }
235
236 private:
238 bool m_is_running{false};
239 };
240
241} // namespace time_shield
242
243#endif // TIME_SHIELD_HEADER_TIMERS_DEADLINETIMER_HPP_INCLUDED
Helper that models a monotonic deadline for timeout management.
static DeadlineTimer from_timeout(duration timeout) noexcept
Creates a timer that expires after the specified timeout.
void start(std::chrono::duration< Rep, Period > timeout) noexcept
Starts the timer so it expires after the specified timeout.
void add_ms(ts_ms_t extend_by_ms) noexcept
Extends deadline by the specified number of milliseconds while preventing overflow.
TIME_SHIELD_NODISCARD ts_t deadline_sec() const noexcept
Returns stored deadline as seconds since the steady epoch.
void add(duration extend_by) noexcept
Extends deadline by the specified duration while preventing overflow.
void start_sec(ts_t timeout_sec) noexcept
Starts the timer so it expires after the specified number of seconds.
TIME_SHIELD_NODISCARD time_point deadline() const noexcept
Returns stored deadline.
TIME_SHIELD_NODISCARD bool has_expired_sec(ts_t now_sec) const noexcept
Checks if the deadline has expired relative to the provided second timestamp.
TIME_SHIELD_NODISCARD ts_t remaining_time_sec() const noexcept
Returns remaining time in seconds until the deadline.
DeadlineTimer(std::chrono::duration< Rep, Period > timeout) noexcept
Constructs a timer that expires after the given timeout.
std::chrono::steady_clock clock
TIME_SHIELD_NODISCARD bool has_expired() const noexcept
Checks if the deadline has already expired.
void start(time_point deadline) noexcept
Sets the absolute deadline and marks the timer as active.
static DeadlineTimer from_timeout(std::chrono::duration< Rep, Period > timeout) noexcept
Creates a timer that expires after the specified timeout.
clock::time_point time_point
TIME_SHIELD_NODISCARD bool has_expired(time_point now) const noexcept
Checks if the deadline has expired relative to the provided time point.
DeadlineTimer(ts_ms_t timeout_ms) noexcept
Constructs a timer that expires after the given number of milliseconds.
static DeadlineTimer from_timeout_ms(ts_ms_t timeout_ms) noexcept
Creates a timer that expires after the specified number of milliseconds.
void start_ms(ts_ms_t timeout_ms) noexcept
Starts the timer so it expires after the specified number of milliseconds.
void add_sec(ts_t extend_by_sec) noexcept
Extends deadline by the specified number of seconds while preventing overflow.
TIME_SHIELD_NODISCARD ts_ms_t deadline_ms() const noexcept
Returns stored deadline as milliseconds since the steady epoch.
static DeadlineTimer from_timeout_sec(ts_t timeout_sec) noexcept
Creates a timer that expires after the specified number of seconds.
TIME_SHIELD_NODISCARD bool is_running() const noexcept
Checks whether the timer tracks a deadline.
TIME_SHIELD_NODISCARD duration remaining_time() const noexcept
Returns time remaining until the deadline.
void stop() noexcept
Stops the timer and invalidates the stored deadline.
void set_forever() noexcept
Marks the timer as running forever (no timeout).
DeadlineTimer() noexcept=default
Constructs an inactive timer.
TIME_SHIELD_NODISCARD bool has_expired_ms(ts_ms_t now_ms) const noexcept
Checks if the deadline has expired relative to the provided millisecond timestamp.
TIME_SHIELD_NODISCARD bool is_forever() const noexcept
Checks whether the timer is configured for an infinite timeout.
TIME_SHIELD_NODISCARD ts_ms_t remaining_time_ms() const noexcept
Returns remaining time in milliseconds until the deadline.
TIME_SHIELD_NODISCARD duration remaining_time(time_point now) const noexcept
Returns remaining time relative to the provided time point.
int64_t ts_t
Unix timestamp in seconds since 1970‑01‑01T00:00:00Z.
Definition types.hpp:48
int64_t ts_ms_t
Unix timestamp in milliseconds since epoch.
Definition types.hpp:49
ts_ms_t now() noexcept
Get the current UTC timestamp in milliseconds.
Main namespace for the Time Shield library.