// timeline.h // // Shared playback clock. The show's modules (video / music / lyrics) all // receive a Timeline* so they time their output against the same anchor: // the video paces its frames from Timeline::startTime(), the lyrics pick the // line for Timeline::seconds(), and the audio simply plays in real time. // // The timeline is anchored once (idempotently) before the show starts. #pragma once #include #include class Timeline { public: // Anchor the timeline to now. Safe to call more than once; an already // anchored timeline is not re-anchored by the modules. void start() { std::lock_guard lock(mutex_); if (started_) return; start_ = std::chrono::steady_clock::now(); started_ = true; } // Whether the timeline has been anchored yet. bool started() const { std::lock_guard lock(mutex_); return started_; } // Seconds elapsed since the anchor (0 until start()). double seconds() const { std::lock_guard lock(mutex_); if (!started_) return 0.0; return std::chrono::duration(std::chrono::steady_clock::now() - start_) .count(); } // Wall-clock instant the timeline was anchored, for deadline math. std::chrono::steady_clock::time_point startTime() const { std::lock_guard lock(mutex_); return start_; } private: mutable std::mutex mutex_; std::chrono::steady_clock::time_point start_{}; bool started_ = false; };