From 96d528b3ac784c13ae0f54e77f0af4dad2609c0f Mon Sep 17 00:00:00 2001 From: gramps Date: Fri, 30 Oct 2026 14:44:56 -0700 Subject: [PATCH] fix(scoreboard): clear the two nullable warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- Models/ScoreboardLayout.cs | 7 ++++--- ViewModels/MainViewModel.cs | 2 +- ytLive.Tests/ScoreboardLayerTests.cs | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Models/ScoreboardLayout.cs b/Models/ScoreboardLayout.cs index 368eefa..64fca6a 100644 --- a/Models/ScoreboardLayout.cs +++ b/Models/ScoreboardLayout.cs @@ -53,11 +53,12 @@ public static class ScoreboardLayout public static Fit FitLine(IReadOnlyList tileWidths, double separatorWidth, double availableWidth, double requestedSize = MaxFontSize, double floorSize = FloorFontSize) { - var count = tileWidths?.Count ?? 0; + var widths = tileWidths ?? System.Array.Empty(); + 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; diff --git a/ViewModels/MainViewModel.cs b/ViewModels/MainViewModel.cs index b1fed40..9d1c85a 100644 --- a/ViewModels/MainViewModel.cs +++ b/ViewModels/MainViewModel.cs @@ -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), diff --git a/ytLive.Tests/ScoreboardLayerTests.cs b/ytLive.Tests/ScoreboardLayerTests.cs index 6835b62..7c2cfd3 100644 --- a/ytLive.Tests/ScoreboardLayerTests.cs +++ b/ytLive.Tests/ScoreboardLayerTests.cs @@ -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");