Fist commit
This commit is contained in:
91
lib/timbre_core/SessionClock.h
Executable file
91
lib/timbre_core/SessionClock.h
Executable file
@@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
|
||||
#include "CivilTime.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
namespace timbre_core {
|
||||
|
||||
// Hardware integration supplies this interface. The core never calls a
|
||||
// platform-specific tick function itself.
|
||||
class MonotonicClock {
|
||||
public:
|
||||
virtual ~MonotonicClock() = default;
|
||||
virtual std::uint64_t nowMs() const = 0;
|
||||
};
|
||||
|
||||
class SessionClock {
|
||||
public:
|
||||
using Callback = std::function<std::uint64_t()>;
|
||||
|
||||
struct Observation {
|
||||
bool valid = false;
|
||||
bool firstObservation = false;
|
||||
bool monotonicRegression = false;
|
||||
bool resynchronized = false;
|
||||
std::uint64_t monotonicMs = 0;
|
||||
std::int64_t utcEpochSeconds = 0;
|
||||
CivilDateTime local{};
|
||||
|
||||
constexpr operator bool() const noexcept { return valid; }
|
||||
constexpr bool isFirstObservation() const noexcept { return firstObservation; }
|
||||
};
|
||||
|
||||
explicit SessionClock(Callback callback) : callback_(std::move(callback)) {}
|
||||
explicit SessionClock(MonotonicClock& clock) : clock_(&clock) {}
|
||||
SessionClock(const SessionClock&) = delete;
|
||||
SessionClock& operator=(const SessionClock&) = delete;
|
||||
|
||||
// The first wall-clock observation establishes an anchor and returns
|
||||
// firstObservation=true. It never attempts to replay older wall time.
|
||||
Observation observe(std::int64_t utcEpochSeconds);
|
||||
Observation poll(std::int64_t utcEpochSeconds) { return observe(utcEpochSeconds); }
|
||||
Observation sync(std::int64_t utcEpochSeconds) { return observe(utcEpochSeconds); }
|
||||
Observation update(std::int64_t utcEpochSeconds) { return observe(utcEpochSeconds); }
|
||||
|
||||
// Deterministic injection for tests and for a caller that already has a
|
||||
// monotonic sample. It follows exactly the same first-observation rule.
|
||||
Observation observeAt(std::int64_t utcEpochSeconds, std::uint64_t monotonicMs);
|
||||
|
||||
// Advance only from the injected monotonic source. No wall-clock catch-up
|
||||
// is performed, so a sleep or a clock correction cannot create old events.
|
||||
Observation tick();
|
||||
Observation update() { return tick(); }
|
||||
|
||||
bool initialized() const noexcept { return initialized_; }
|
||||
bool hasObservation() const noexcept { return initialized_; }
|
||||
bool hasFirstObservation() const noexcept { return initialized_; }
|
||||
bool lastWasFirstObservation() const noexcept { return lastObservation_.firstObservation; }
|
||||
std::uint64_t monotonicNowMs() const;
|
||||
std::uint64_t now() const { return monotonicNowMs(); }
|
||||
std::uint64_t elapsedMs() const noexcept;
|
||||
std::uint64_t sessionElapsedMs() const noexcept;
|
||||
std::uint64_t elapsedSinceAnchorMs() const noexcept { return sessionElapsedMs(); }
|
||||
std::int64_t utcEpochSeconds() const noexcept { return lastWallSeconds_; }
|
||||
std::int64_t wallEpochSeconds() const noexcept { return lastWallSeconds_; }
|
||||
std::int64_t anchorUtcEpochSeconds() const noexcept { return anchorWallSeconds_; }
|
||||
const CivilDateTime& localTime() const noexcept { return lastLocal_; }
|
||||
const CivilDateTime& civilTime() const noexcept { return lastLocal_; }
|
||||
const Observation& lastObservation() const noexcept { return lastObservation_; }
|
||||
|
||||
void reset() noexcept;
|
||||
|
||||
private:
|
||||
std::uint64_t readMonotonic() const;
|
||||
bool setObservation(std::int64_t wallSeconds, std::uint64_t monotonicMs,
|
||||
bool first, bool regression, bool resynchronized);
|
||||
|
||||
Callback callback_;
|
||||
MonotonicClock* clock_ = nullptr;
|
||||
bool initialized_ = false;
|
||||
std::uint64_t anchorMonotonicMs_ = 0;
|
||||
std::uint64_t lastMonotonicMs_ = 0;
|
||||
std::int64_t anchorWallSeconds_ = 0;
|
||||
std::int64_t lastWallSeconds_ = 0;
|
||||
CivilDateTime lastLocal_{};
|
||||
Observation lastObservation_{};
|
||||
};
|
||||
|
||||
} // namespace timbre_core
|
||||
Reference in New Issue
Block a user