using System.Collections.Generic;
using ytLive.Models;
namespace ytLive.Services.Compositor;
/// Turns the session's tallies into the strip frame, and keeps the raster until a displayed
/// value actually moves.
///
/// The cache is the point: a strip re-rasterised every tick would be the most expensive layer
/// the compositor carries, for pixels that did not change. `ScoreboardRecorder.Changed` only fires
/// on a visible change, so the presenter rebuilds only then.
public sealed class ScoreboardPresenter
{
private readonly ScoreboardRecorder _recorder;
private VideoFrame? _frame;
private string? _tilesFingerprint;
private ScoreboardStyle _style;
private ScoreboardTiles _tiles = ScoreboardTiles.None;
public ScoreboardPresenter(ScoreboardRecorder recorder, ScoreboardStyle style)
{
_recorder = recorder;
_style = style;
_recorder.Changed += Invalidate;
}
/// The strip frame for the current tallies, or null when nothing is enabled/shown.
public VideoFrame? Frame
{
get
{
var tiles = _tiles.Build(_recorder.State);
var fingerprint = $"{_tiles.CacheKey}|{string.Join('|', tiles)}|{_style}";
if (_frame != null && fingerprint == _tilesFingerprint) return _frame;
_tilesFingerprint = fingerprint;
_frame = ScoreboardRenderer.Render(tiles, _style);
return _frame;
}
}
public void SetTiles(ScoreboardTiles tiles)
{
_tiles = tiles;
Invalidate();
}
public void SetStyle(ScoreboardStyle style)
{
_style = style;
Invalidate();
}
/// Drops the cached raster so the next read rebuilds it.
public void Invalidate()
{
_frame = null;
_tilesFingerprint = null;
}
}