feat(scoreboard): a DEBUG-only "Simulate" switch, so the strip is provable in the preview

Creator (2026-10-30): pre-1.0, use DEBUG — add a toggle that simulates the ticker so the strip can
be SEEN and its compositing verified before a real stream.

The sample travels the REAL ScoreboardRecorder a stream uses (one new member, a gift of three, a
milestone, a $12.34 Super Chat), so what the preview shows is exactly what live events produce — a
fake renderer would prove nothing. Toggling off clears to an empty session, so the empty state is
visible too.

Debug-gated at COMPILE time: `DevelopmentBuild` is a const true in DEBUG / false in Release, and the
checkbox binds its Visibility to it. A shipped Release build therefore has no dev control at all,
rather than one hidden by a runtime flag.

Guard: ScoreboardSimulationTests — the sample lands all four tallies through the recorder, off clears,
and the panel + const pair exist in the Dual (DEBUG/Release) form.
This commit is contained in:
2026-10-30 14:58:56 -07:00
parent ea1017776d
commit e6abc13461
4 changed files with 108 additions and 0 deletions
+27
View File
@@ -45,6 +45,33 @@ public partial class MainViewModel
}
}
#if DEBUG
private const bool DevelopmentBuild = true;
#else
private const bool DevelopmentBuild = false;
#endif
/// <summary>True in a DEBUG build. Used only to expose development-only controls, never to
/// change behaviour — the shipped binary differs by their absence, not by a code path.</summary>
public bool IsDevelopmentBuild => DevelopmentBuild;
private bool _scoreboardSimulate;
/// <summary>DEBUG-only: push a representative set of events so the strip is visible in the
/// preview before any real stream. Off clears back to an empty session.</summary>
public bool ScoreboardSimulate
{
get => _scoreboardSimulate;
set
{
if (!SetProperty(ref _scoreboardSimulate, value)) return;
if (value) ScoreboardSample.Inject(_scoreboard);
else _scoreboard.StartSession(); // empty session: "nothing yet"
RefreshScoreboardPreviews();
OnPropertyChanged(nameof(ScoreboardFrame));
}
}
/// <summary>What the cadence policy asks: the master switch AND at least one scene showing it.</summary>
internal bool ScoreboardPollsEnabled =>
_scoreboardEnabled && Scenes.Any(scene =>