Files
crosstyanandClaude Fable 5 c948c7565c feat: unify app_utils/app_clock headers shared by the fleet
Merged from the three drifted hand-copies in TrackBackFwd, healthy-band-nrf
and zephyr_gateway_fwd:
- as_u8s(T&) overloads and deferrer (band/hub side)
- hexdump, add_overflow, constrain_value_in_range_static, to_mac_string
  (TrackBackFwd side)
- add_overflow now returns std::expected directly instead of the app_result
  alias; to_mac_string guarded by __cpp_lib_format for GCC 12 toolchains
- app_clock.hpp now() selects k_uptime_ticks / esp_timer_get_time via
  __ZEPHYR__ / ESP_PLATFORM; fixed doc comment (microseconds, not ms)
- dropped vestigial esp_err.h/esp_system.h/FreeRTOS.h includes

Dual build glue: ESP-IDF component (root CMakeLists) + Zephyr module (zephyr/).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 15:30:28 +08:00

106 lines
2.3 KiB
C++

#pragma once
#include <chrono>
#include <cstdint>
#include "app_clock.hpp"
namespace app::utils {
/**
* @brief A measurement of a monotonically nondecreasing clock.
* @tparam T the data type of the counter
* @sa https://doc.rust-lang.org/std/time/struct.Instant.html
*/
struct Instant {
public:
using clock = typename app::utils::clock_t;
using duration = typename clock::duration;
using time_point = typename clock::time_point;
using milliseconds = typename std::chrono::duration<uint32_t, std::milli>;
using ms_rep = typename milliseconds::rep;
Instant() {
time_ = clock::now();
}
static Instant now() {
return Instant{};
}
[[nodiscard]]
duration elapsed() const {
return clock::now() - time_;
}
[[nodiscard]]
ms_rep elapsed_ms() const {
return std::chrono::duration_cast<milliseconds>(elapsed()).count();
}
template <typename Rep, typename Period>
[[nodiscard]]
bool has_elapsed(const std::chrono::duration<Rep, Period> duration) const {
return elapsed() >= duration;
}
[[nodiscard]]
bool has_elapsed_ms(ms_rep ms) const {
return has_elapsed(milliseconds{ms});
}
/**
* @brief Check if the instant has elapsed and reset the time point if it has.
* @note use if periodic task to get some timer like behavior. (note that
* you might not want to busy wait to check this, although you are free to do so)
*
* @tparam Rep representation of the duration (int, uint32_t, uint64_t, etc.)
* @tparam Period unit of the duration (std::milli, std::micro, etc.)
* @param duration the duration to check against
* @return true if the instant has elapsed, and would be reset
* @return false if the instant has not elapsed
*/
template <typename Rep, typename Period>
[[nodiscard]]
bool mut_every(const std::chrono::duration<Rep, Period> duration) {
if (has_elapsed(duration)) {
mut_reset();
return true;
}
return false;
}
[[nodiscard]]
bool mut_every_ms(ms_rep ms) {
return mut_every(milliseconds{ms});
}
void mut_reset() {
time_ = clock::now();
}
/**
* @deprecated use `mut_reset` instead
*/
[[deprecated("use `mut_reset` instead")]]
void reset() {
mut_reset();
}
[[nodiscard]]
duration mut_elapsed_and_reset() {
auto e = elapsed();
mut_reset();
return e;
}
[[nodiscard]]
time_point last() const {
return time_;
}
private:
time_point time_;
};
}