Fist commit
This commit is contained in:
90
lib/timbre_core/Scheduler.h
Executable file
90
lib/timbre_core/Scheduler.h
Executable file
@@ -0,0 +1,90 @@
|
||||
#pragma once
|
||||
|
||||
#include "CivilTime.h"
|
||||
#include "Model.h"
|
||||
#include "SessionClock.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace timbre_core {
|
||||
|
||||
struct ScheduleDecision {
|
||||
bool due = false;
|
||||
bool firstObservation = false;
|
||||
bool alreadyProcessed = false;
|
||||
bool blockedByHoliday = false;
|
||||
bool invalidTime = false;
|
||||
ScheduleId scheduleId = kInvalidId;
|
||||
PatternId patternId = PatternId::A;
|
||||
std::uint64_t missedMinutes = 0;
|
||||
|
||||
constexpr explicit operator bool() const noexcept { return due; }
|
||||
constexpr bool triggered() const noexcept { return due; }
|
||||
};
|
||||
|
||||
using ScheduleMatch = ScheduleDecision;
|
||||
|
||||
class Scheduler {
|
||||
public:
|
||||
Scheduler() = default;
|
||||
|
||||
// Only the currently observed local minute is considered. If the source
|
||||
// jumped from minute N to N+K, the intermediate minutes are intentionally
|
||||
// discarded rather than replayed.
|
||||
ScheduleDecision poll(const AppState& state,
|
||||
const CivilDateTime& localTime,
|
||||
bool firstObservation = false);
|
||||
ScheduleDecision process(const AppState& state,
|
||||
const CivilDateTime& localTime,
|
||||
bool firstObservation = false) {
|
||||
return poll(state, localTime, firstObservation);
|
||||
}
|
||||
|
||||
// Convenience integration with SessionClock. The caller supplies the
|
||||
// current wall value; the injected monotonic source remains authoritative
|
||||
// inside SessionClock.
|
||||
ScheduleDecision poll(const AppState& state,
|
||||
SessionClock& clock,
|
||||
std::int64_t utcEpochSeconds);
|
||||
ScheduleDecision poll(const AppState& state,
|
||||
const SessionClock::Observation& observation) {
|
||||
if (!observation.valid) {
|
||||
ScheduleDecision decision;
|
||||
decision.invalidTime = true;
|
||||
return decision;
|
||||
}
|
||||
return poll(state, observation.local, observation.firstObservation);
|
||||
}
|
||||
ScheduleDecision process(const AppState& state,
|
||||
SessionClock& clock,
|
||||
std::int64_t utcEpochSeconds) {
|
||||
return poll(state, clock, utcEpochSeconds);
|
||||
}
|
||||
ScheduleDecision tick(const AppState& state,
|
||||
const CivilDateTime& localTime,
|
||||
bool firstObservation = false) {
|
||||
return poll(state, localTime, firstObservation);
|
||||
}
|
||||
ScheduleDecision evaluate(const AppState& state,
|
||||
const CivilDateTime& localTime,
|
||||
bool firstObservation = false) {
|
||||
return poll(state, localTime, firstObservation);
|
||||
}
|
||||
|
||||
bool hasLastKey() const noexcept { return hasLastKey_; }
|
||||
const LocalMinuteKey& lastKey() const noexcept { return lastKey_; }
|
||||
const LocalMinuteKey& key() const noexcept { return lastKey_; }
|
||||
void reset() noexcept;
|
||||
|
||||
static bool isHoliday(const AppState& state, std::uint8_t month,
|
||||
std::uint8_t day) noexcept;
|
||||
static bool scheduleMatches(const Schedule& schedule,
|
||||
const AppState& state,
|
||||
const CivilDateTime& localTime) noexcept;
|
||||
|
||||
private:
|
||||
bool hasLastKey_ = false;
|
||||
LocalMinuteKey lastKey_{};
|
||||
};
|
||||
|
||||
} // namespace timbre_core
|
||||
Reference in New Issue
Block a user