#pragma once #include // The stopwatch of the dynamic pages, started and stopped in the web UI and Home Assistant. // Times are the real time in ms since 1970 (UTC), so it counts from a date, keeps counting // while the display is off or restarting (system/stopwatch_store keeps it in NVS) and can // run for years. Pure logic, tested in test/test_esp32. class Stopwatch { public: // The state as it is stored struct State { bool running = false; int64_t started = 0; // when it was started (again) int64_t before = 0; // ms counted before the last start }; void start(int64_t now) { if (_state.running) return; _state.running = true; _state.started = now; } void stop(int64_t now) { if (!_state.running) return; _state.before = elapsed(now); _state.running = false; } // Back to 0, stopped void reset() { _state = State(); } // Counts from this moment (in the past) on, running; false (nothing changed) when it is // in the future bool setStart(int64_t start, int64_t now) { if (start > now) return false; _state.running = true; _state.started = start; _state.before = 0; return true; } bool running() const { return _state.running; } // Never negative (the clock set back) uint64_t elapsed(int64_t now) const { int64_t ms = _state.before; if (_state.running && now > _state.started) ms += now - _state.started; return ms > 0 ? (uint64_t)ms : 0; } const State &state() const { return _state; } void restore(const State &state) { _state = state; } private: State _state; };