Time Shield Library
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_DEADLINE_TIMER_HPP_INCLUDED
4#define _TIME_SHIELD_DEADLINE_TIMER_HPP_INCLUDED
5
12
13#include "config.hpp"
14#include "types.hpp"
15
16#include <chrono>
17
18namespace time_shield {
19
27 public:
28 using clock = std::chrono::steady_clock;
29 using duration = clock::duration;
30 using time_point = clock::time_point;
31
33 DeadlineTimer() noexcept = default;
34
36 explicit DeadlineTimer(time_point deadline) noexcept {
38 }
39
41 template<class Rep, class Period>
42 explicit DeadlineTimer(std::chrono::duration<Rep, Period> timeout) noexcept {
43 start(timeout);
44 }
45
47 explicit DeadlineTimer(ts_ms_t timeout_ms) noexcept {
48 start_ms(timeout_ms);
49 }
50
52 static DeadlineTimer from_timeout(duration timeout) noexcept {
53 DeadlineTimer timer;
54 timer.start(timeout);
55 return timer;
56 }
57
59 template<class Rep, class Period>
60 static DeadlineTimer from_timeout(std::chrono::duration<Rep, Period> timeout) noexcept {
61 DeadlineTimer timer;
62 timer.start(timeout);
63 return timer;
64 }
65
67 static DeadlineTimer from_timeout_sec(ts_t timeout_sec) noexcept {
68 DeadlineTimer timer;
69 timer.start_sec(timeout_sec);
70 return timer;
71 }
72
74 static DeadlineTimer from_timeout_ms(ts_ms_t timeout_ms) noexcept {
75 DeadlineTimer timer;
76 timer.start_ms(timeout_ms);
77 return timer;
78 }
79
81 void start(time_point deadline) noexcept {
83 m_is_running = true;
84 }
85
91 template<class Rep, class Period>
92 void start(std::chrono::duration<Rep, Period> timeout) noexcept {
93 const time_point now = clock::now();
94 if (timeout <= decltype(timeout)::zero()) {
95 start(now);
96 return;
97 }
98
99 duration safe_duration = std::chrono::duration_cast<duration>(timeout);
100 if (safe_duration <= duration::zero()) {
101 safe_duration = duration(1);
102 }
103
104 const time_point max_time = (time_point::max)();
105 const duration max_offset = max_time - now;
106 if (safe_duration >= max_offset) {
107 start(max_time);
108 return;
109 }
110
111 start(now + safe_duration);
112 }
113
115 void start_sec(ts_t timeout_sec) noexcept {
116 start(std::chrono::seconds(timeout_sec));
117 }
118
120 void start_ms(ts_ms_t timeout_ms) noexcept {
121 start(std::chrono::milliseconds(timeout_ms));
122 }
123
125 void stop() noexcept {
126 m_is_running = false;
128 }
129
131 void set_forever() noexcept {
132 m_is_running = true;
133 m_deadline = (time_point::max)();
134 }
135
137 TIME_SHIELD_NODISCARD bool is_running() const noexcept {
138 return m_is_running;
139 }
140
142 TIME_SHIELD_NODISCARD bool is_forever() const noexcept {
143 return m_is_running && m_deadline == (time_point::max)();
144 }
145
147 TIME_SHIELD_NODISCARD time_point deadline() const noexcept {
148 return m_deadline;
149 }
150
152 TIME_SHIELD_NODISCARD ts_ms_t deadline_ms() const noexcept {
153 return std::chrono::duration_cast<std::chrono::milliseconds>(m_deadline.time_since_epoch()).count();
154 }
155
157 TIME_SHIELD_NODISCARD ts_t deadline_sec() const noexcept {
158 return std::chrono::duration_cast<std::chrono::seconds>(m_deadline.time_since_epoch()).count();
159 }
160
162 TIME_SHIELD_NODISCARD bool has_expired() const noexcept {
163 return has_expired(clock::now());
164 }
165
167 TIME_SHIELD_NODISCARD bool has_expired_ms(ts_ms_t now_ms) const noexcept {
168 const duration since_epoch = std::chrono::duration_cast<duration>(std::chrono::milliseconds(now_ms));
169 return has_expired(time_point(since_epoch));
170 }
171
173 TIME_SHIELD_NODISCARD bool has_expired_sec(ts_t now_sec) const noexcept {
174 const duration since_epoch = std::chrono::duration_cast<duration>(std::chrono::seconds(now_sec));
175 return has_expired(time_point(since_epoch));
176 }
177
179 TIME_SHIELD_NODISCARD bool has_expired(time_point now) const noexcept {
180 return m_is_running && now >= m_deadline;
181 }
182
184 TIME_SHIELD_NODISCARD duration remaining_time() const noexcept {
185 return remaining_time(clock::now());
186 }
187
189 TIME_SHIELD_NODISCARD ts_ms_t remaining_time_ms() const noexcept {
190 return std::chrono::duration_cast<std::chrono::milliseconds>(remaining_time()).count();
191 }
192
194 TIME_SHIELD_NODISCARD ts_t remaining_time_sec() const noexcept {
195 return std::chrono::duration_cast<std::chrono::seconds>(remaining_time()).count();
196 }
197
201 TIME_SHIELD_NODISCARD duration remaining_time(time_point now) const noexcept {
202 if (!m_is_running || now >= m_deadline) {
203 return duration::zero();
204 }
205 return m_deadline - now;
206 }
207
209 void add(duration extend_by) noexcept {
210 if (!m_is_running || extend_by <= duration::zero()) {
211 return;
212 }
213
214 const time_point now = clock::now();
215 const time_point base = m_deadline > now ? m_deadline : now;
216 const duration max_offset = (time_point::max)() - base;
217 const duration safe_offset = extend_by < max_offset ? extend_by : max_offset;
218 m_deadline = base + safe_offset;
219 }
220
222 void add_sec(ts_t extend_by_sec) noexcept {
223 if (extend_by_sec <= 0) {
224 return;
225 }
226 add(std::chrono::seconds(extend_by_sec));
227 }
228
230 void add_ms(ts_ms_t extend_by_ms) noexcept {
231 if (extend_by_ms <= 0) {
232 return;
233 }
234 add(std::chrono::milliseconds(extend_by_ms));
235 }
236
237 private:
239 bool m_is_running{false};
240 };
241
242} // namespace time_shield
243
244#endif // _TIME_SHIELD_DEADLINE_TIMER_HPP_INCLUDED
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 currently 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.
Configuration macros for the library.
int64_t ts_t
Unix timestamp in seconds since 1970‑01‑01T00:00:00Z.
Definition types.hpp:46
int64_t ts_ms_t
Unix timestamp in milliseconds since epoch.
Definition types.hpp:47
ts_ms_t now() noexcept
Get the current UTC timestamp in milliseconds.
Main namespace for the Time Shield library.
Type definitions for time-related units and formats.