feat: make everything threads-safe.

feat: complete `uninstall.sh` logic to make everything synced.
	feat: complete basic play logic to handle background, music,
	lyric play.
This commit is contained in:
2026-08-30 15:13:28 +08:00
parent 00b7c0b324
commit 7edba3fbc0
10 changed files with 355 additions and 65 deletions
+50
View File
@@ -0,0 +1,50 @@
// 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 <chrono>
#include <mutex>
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<std::mutex> 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<std::mutex> lock(mutex_);
return started_;
}
// Seconds elapsed since the anchor (0 until start()).
double seconds() const {
std::lock_guard<std::mutex> lock(mutex_);
if (!started_) return 0.0;
return std::chrono::duration<double>(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<std::mutex> lock(mutex_);
return start_;
}
private:
mutable std::mutex mutex_;
std::chrono::steady_clock::time_point start_{};
bool started_ = false;
};