ForestHub SDK 0.1.0
C++14 LLM SDK for PC and embedded platforms
Loading...
Searching...
No Matches
ticker.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: AGPL-3.0-only
2// Copyright (c) 2026 ForestHub. All rights reserved.
3// For commercial licensing, visit https://github.com/ForestHubAI/fh-sdk
4
5#ifndef FORESTHUB_UTIL_TICKER_HPP
6#define FORESTHUB_UTIL_TICKER_HPP
7
10
11namespace foresthub {
12namespace util {
13
42class Ticker {
43public:
49 explicit Ticker(unsigned long period, long offset = 0)
50 : period_(period),
51 offset_(offset),
52 tz_offset_sec_(0),
53 relative_(false),
54 start_time_(0),
55 last_slot_(0),
56 fire_count_(0),
57 missed_ticks_(0),
58 max_fires_(0),
59 running_(false) {}
60
61 // -- Factory methods ------------------------------------------------------
62
68 static Ticker Periodic(unsigned long interval) {
69 Ticker t(interval);
70 t.relative_ = true;
71 return t;
72 }
73
78 static Ticker OneShot(unsigned long delay) {
79 Ticker t = Periodic(delay);
80 t.max_fires_ = 1;
81 return t;
82 }
83
90 static Ticker Daily(int hour, int minute = 0) {
91 return Ticker(86400UL, kEpochSundayOffset - (static_cast<long>(hour) * 3600L + minute * 60L));
92 }
93
99 static Ticker Weekly(int weekday, int hour, int minute = 0) {
100 return Ticker(604800UL, kEpochSundayOffset - (static_cast<long>(weekday) * 86400L +
101 static_cast<long>(hour) * 3600L + minute * 60L));
102 }
103
107 static Ticker Hourly(int minute = 0) { return Ticker(3600UL, -(minute * 60L)); }
108
109 // -- Builder --------------------------------------------------------------
110
112 Ticker& WithMaxFires(unsigned long n) {
113 max_fires_ = n;
114 return *this;
115 }
116
124 tz_offset_sec_ = tz_offset_sec;
125 return *this;
126 }
127
128 // -- Lifecycle ------------------------------------------------------------
129
135 void Start(unsigned long time) {
136 if (relative_) {
137 start_time_ = time;
138 } else {
139 last_slot_ = Slot(time);
140 }
141 fire_count_ = 0;
142 missed_ticks_ = 0;
143 running_ = true;
144 }
145
152 bool Check(unsigned long time) {
153 if (!running_) return false;
154
155 if (relative_) {
156 // Wrap-safe unsigned path (immune to 32-bit unsigned overflow).
157 unsigned long elapsed = time - start_time_;
158 if (elapsed < period_) return false;
159 missed_ticks_ = (elapsed / period_) - 1;
160 start_time_ += (missed_ticks_ + 1) * period_; // Drift correction: snap to grid.
161 } else {
162 // Slot-based path for calendar/epoch scheduling.
163 long current_slot = Slot(time);
164 if (current_slot <= last_slot_) return false;
165 missed_ticks_ = static_cast<unsigned long>(current_slot - last_slot_ - 1);
166 last_slot_ = current_slot;
167 }
168
169 ++fire_count_;
170 if (max_fires_ > 0 && fire_count_ >= max_fires_) running_ = false;
171 return true;
172 }
173
175 void Stop() { running_ = false; }
176
179 void SetTimezoneOffset(long tz_offset_sec) { tz_offset_sec_ = tz_offset_sec; }
180
181 // -- Getters --------------------------------------------------------------
182
184 bool running() const { return running_; }
185
187 unsigned long fire_count() const { return fire_count_; }
188
192 unsigned long missed_ticks() const { return missed_ticks_; }
193
195 unsigned long period() const { return period_; }
196
198 long tz_offset_sec() const { return tz_offset_sec_; }
199
200private:
204 static constexpr long kEpochSundayOffset = 4L * 86400L;
205
210 long Slot(unsigned long time) const {
211 long val = static_cast<long>(time) + tz_offset_sec_ + offset_;
212 long p = static_cast<long>(period_);
213 return val / p - (val % p < 0);
214 }
215
216 unsigned long period_;
217 long offset_;
218 long tz_offset_sec_; // Timezone offset in seconds (applied in Slot()).
219 bool relative_;
220 unsigned long start_time_; // Reference time for relative mode (unsigned, wrap-safe).
221 long last_slot_; // Last computed slot for absolute mode (signed for negative slots).
222 unsigned long fire_count_;
223 unsigned long missed_ticks_;
224 unsigned long max_fires_;
225 bool running_;
226};
227
228} // namespace util
229} // namespace foresthub
230
231#endif // FORESTHUB_UTIL_TICKER_HPP
unsigned long period() const
Configured period in time units.
Definition ticker.hpp:195
void SetTimezoneOffset(long tz_offset_sec)
Update timezone offset at runtime (e.g., after DST transition).
Definition ticker.hpp:179
unsigned long missed_ticks() const
Number of intervals skipped in the last Check() that fired.
Definition ticker.hpp:192
static Ticker Periodic(unsigned long interval)
Create a periodic ticker that fires at a fixed interval.
Definition ticker.hpp:68
static Ticker OneShot(unsigned long delay)
Create a one-shot timer that fires exactly once after a delay.
Definition ticker.hpp:78
static Ticker Hourly(int minute=0)
Create an hourly ticker that fires once per hour at a specific minute.
Definition ticker.hpp:107
Ticker & WithMaxFires(unsigned long n)
Set the maximum number of fires before auto-stopping (0 = unlimited).
Definition ticker.hpp:112
void Stop()
Stop the ticker. Call Start() to restart.
Definition ticker.hpp:175
static Ticker Weekly(int weekday, int hour, int minute=0)
Create a weekly ticker that fires once per week on a specific day and time.
Definition ticker.hpp:99
unsigned long fire_count() const
Number of times the ticker has fired since last Start().
Definition ticker.hpp:187
bool Check(unsigned long time)
Check if the ticker should fire at the given time.
Definition ticker.hpp:152
Ticker & WithTimezoneOffset(long tz_offset_sec)
Set timezone offset for calendar-based scheduling (Daily/Weekly/Hourly).
Definition ticker.hpp:123
Ticker(unsigned long period, long offset=0)
Construct a Ticker with custom period and offset.
Definition ticker.hpp:49
long tz_offset_sec() const
Configured timezone offset in seconds (0 if not set).
Definition ticker.hpp:198
bool running() const
Whether the ticker is currently running.
Definition ticker.hpp:184
static Ticker Daily(int hour, int minute=0)
Create a daily ticker that fires once per day at a specific hour and minute.
Definition ticker.hpp:90
void Start(unsigned long time)
Start (or restart) the ticker with the given time reference.
Definition ticker.hpp:135
Utility types: Optional polyfill, JSON Schema normalization, Ticker.
Top-level namespace for the ForestHub SDK.