fix(scoreboard): clear the two nullable warnings

Both were mine, from the scoreboard units:
- ScoreboardLayout.FitLine null-forgave tileWidths on one expression and then iterated the field
  anyway; it now binds a non-null local once and uses that throughout.
- the output resolver dereferenced _scoreboardPresenter, which is assigned in InitScoreboard — it
  is nullable by construction, so the resolver reads '?.' exactly like the other optional services.

Clean build, 0 warnings, scoreboard tests green.
This commit is contained in:
2026-10-30 14:45:14 -07:00
parent d4a4b1c80e
commit 96d528b3ac
3 changed files with 6 additions and 5 deletions
+4 -3
View File
@@ -53,11 +53,12 @@ public static class ScoreboardLayout
public static Fit FitLine(IReadOnlyList<double> tileWidths, double separatorWidth,
double availableWidth, double requestedSize = MaxFontSize, double floorSize = FloorFontSize)
{
var count = tileWidths?.Count ?? 0;
var widths = tileWidths ?? System.Array.Empty<double>();
var count = widths.Count;
if (count == 0 || availableWidth <= 0)
return new Fit(requestedSize, 1, false);
var total = tileWidths!.Sum() + separatorWidth * (count - 1);
var total = widths.Sum() + separatorWidth * (count - 1);
if (total <= availableWidth)
return new Fit(requestedSize, 1, false);
@@ -70,7 +71,7 @@ public static class ScoreboardLayout
var factor = floorSize / requestedSize;
var lines = 1;
var lineWidth = 0.0;
foreach (var width in tileWidths)
foreach (var width in widths)
{
var w = width * factor;
var needed = lineWidth == 0 ? w : lineWidth + separatorWidth + w;
+1 -1
View File
@@ -596,7 +596,7 @@ public partial class MainViewModel : ViewModelBase
WebcamSceneConfig webcam => _cameraManager.GetLatestFrame(DeviceKeyForWebcam(webcam.WebcamId), EffectKeyFor(webcam)),
Source { IsLiveCapture: true, CaptureKey: not null } live => _screenCaptureManager.GetLatestFrame(live.CaptureKey),
Source { Type: SourceType.ChatBox } chatBox => RenderChatBox(chatBox),
Source { Type: SourceType.Scoreboard } => _scoreboardPresenter.Frame,
Source { Type: SourceType.Scoreboard } => _scoreboardPresenter?.Frame,
Source { Type: SourceType.AlertBox } alertBox => RenderAlertBox(alertBox),
Source { Type: SourceType.WebSource } web => _webView2Manager?.GetLatestFrame(web.Id),
Source { IsMediaSource: true, MediaPath: not null } media => _mediaManager.GetLatestFrame(media.MediaPath),
+1 -1
View File
@@ -23,7 +23,7 @@ public class ScoreboardLayerTests
// The output resolver knows how to produce its frame (same shape as the chat box/alert box).
var resolver = SourceAssert.Text("ViewModels", "MainViewModel.cs");
Assert.Contains("Source { Type: SourceType.Scoreboard } => _scoreboardPresenter.Frame", resolver);
Assert.Contains("Source { Type: SourceType.Scoreboard } => _scoreboardPresenter?.Frame", resolver);
// Session lifecycle: every start clears the tallies.
var ops = SourceAssert.Text("ViewModels", "MainViewModel.Streaming.Operations.cs");