From 06fe5583cb9ecd4915aad3835b09ae732dfc1aff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jul 2023 15:47:57 +0900 Subject: [PATCH 01/90] Expose a new SSDQ from playfield for skinnable area bounds --- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 17 +++++++++++++++++ osu.Game/Rulesets/UI/Playfield.cs | 11 +++++++++++ 2 files changed, 28 insertions(+) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index e3ebadc836..7b00447238 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -9,6 +9,7 @@ using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Graphics.Primitives; using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Objects; @@ -25,6 +26,22 @@ namespace osu.Game.Rulesets.Mania.UI private readonly List stages = new List(); + public override Quad SkinnableComponentScreenSpaceDrawQuad + { + get + { + if (Stages.Count == 1) + return Stages.First().ScreenSpaceDrawQuad; + + RectangleF area = RectangleF.Empty; + + foreach (var stage in Stages) + area = RectangleF.Union(area, stage.ScreenSpaceDrawQuad.AABBFloat); + + return area; + } + } + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => stages.Any(s => s.ReceivePositionalInputAt(screenSpacePos)); public ManiaPlayfield(List stageDefinitions) diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 3f263aba63..e9c35555c8 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -23,6 +23,7 @@ using osu.Game.Skinning; using osuTK; using osu.Game.Rulesets.Objects.Pooling; using osu.Framework.Extensions.ObjectExtensions; +using osu.Framework.Graphics.Primitives; namespace osu.Game.Rulesets.UI { @@ -94,6 +95,16 @@ namespace osu.Game.Rulesets.UI /// public readonly BindableBool DisplayJudgements = new BindableBool(true); + /// + /// A screen space draw quad which resembles the edges of the playfield for skinning purposes. + /// This will allow users / components to snap objects to the "edge" of the playfield. + /// + /// + /// Rulesets which reduce the visible area further than the full relative playfield space itself + /// should retarget this to the ScreenSpaceDrawQuad of the appropriate container. + /// + public virtual Quad SkinnableComponentScreenSpaceDrawQuad => ScreenSpaceDrawQuad; + [Resolved(CanBeNull = true)] [CanBeNull] protected IReadOnlyList Mods { get; private set; } From 5bd06832d0a4e35bbbd52eea2ffb3970764e6d0e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jul 2023 15:48:40 +0900 Subject: [PATCH 02/90] Fix skin component toolbox not working correctly for ruleset matching Until now, the only usage of ruleset layers was where there is both a ruleset specific and non-ruleset-specific layer present. The matching code was making assumptions about this. As I tried to add a new playfield layer which breaks this assumption, non-ruleset-specifc components were not being displayed in the toolbox. This turned out to be due to a `target` of `null` being provided due to the weird `getTarget` matching (that happened to *just* do what we wanted previously due to the equals implementation, but only because there was a container without the ruleset present in the available targets). I've changed this to be a more appropriate lookup method, where the target for dependency sourcing is provided separately from the ruleset filter. --- .../Overlays/SkinEditor/SkinComponentToolbox.cs | 17 +++++++++++++---- osu.Game/Overlays/SkinEditor/SkinEditor.cs | 4 ++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs b/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs index 1ce253d67c..a476fc1a6d 100644 --- a/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs +++ b/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs @@ -13,6 +13,7 @@ using osu.Framework.Threading; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Localisation; +using osu.Game.Rulesets; using osu.Game.Screens.Edit.Components; using osu.Game.Skinning; using osuTK; @@ -23,14 +24,22 @@ namespace osu.Game.Overlays.SkinEditor { public Action? RequestPlacement; - private readonly SkinComponentsContainer? target; + private readonly SkinComponentsContainer target; + + private readonly RulesetInfo? ruleset; private FillFlowContainer fill = null!; - public SkinComponentToolbox(SkinComponentsContainer? target = null) - : base(target?.Lookup.Ruleset == null ? SkinEditorStrings.Components : LocalisableString.Interpolate($"{SkinEditorStrings.Components} ({target.Lookup.Ruleset.Name})")) + /// + /// Create a new component toolbox for the specified taget. + /// + /// The target. This is mainly used as a dependency source to find candidate components. + /// A ruleset to filter components by. If null, only components which are not ruleset-specific will be included. + public SkinComponentToolbox(SkinComponentsContainer target, RulesetInfo? ruleset) + : base(ruleset == null ? SkinEditorStrings.Components : LocalisableString.Interpolate($"{SkinEditorStrings.Components} ({ruleset.Name})")) { this.target = target; + this.ruleset = ruleset; } [BackgroundDependencyLoader] @@ -51,7 +60,7 @@ namespace osu.Game.Overlays.SkinEditor { fill.Clear(); - var skinnableTypes = SerialisedDrawableInfo.GetAllAvailableDrawables(target?.Lookup.Ruleset); + var skinnableTypes = SerialisedDrawableInfo.GetAllAvailableDrawables(ruleset); foreach (var type in skinnableTypes) attemptAddComponent(type); } diff --git a/osu.Game/Overlays/SkinEditor/SkinEditor.cs b/osu.Game/Overlays/SkinEditor/SkinEditor.cs index 2b23ce290f..67cf0eab18 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditor.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditor.cs @@ -366,14 +366,14 @@ namespace osu.Game.Overlays.SkinEditor // If the new target has a ruleset, let's show ruleset-specific items at the top, and the rest below. if (target.NewValue.Ruleset != null) { - componentsSidebar.Add(new SkinComponentToolbox(skinComponentsContainer) + componentsSidebar.Add(new SkinComponentToolbox(skinComponentsContainer, target.NewValue.Ruleset) { RequestPlacement = requestPlacement }); } // Remove the ruleset from the lookup to get base components. - componentsSidebar.Add(new SkinComponentToolbox(getTarget(new SkinComponentsContainerLookup(target.NewValue.Target))) + componentsSidebar.Add(new SkinComponentToolbox(skinComponentsContainer, null) { RequestPlacement = requestPlacement }); From 6cf065f6d1c92ddcdf36efa97fbe4634ee3cd9f8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jul 2023 15:48:21 +0900 Subject: [PATCH 03/90] Add playfield layer to skin editor --- osu.Game/Screens/Play/HUDOverlay.cs | 14 ++++++++++++-- osu.Game/Skinning/SkinComponentsContainerLookup.cs | 5 ++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index d11171e3fe..6696332307 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -12,6 +12,7 @@ using osu.Framework.Bindables; using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Primitives; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Game.Configuration; @@ -103,10 +104,11 @@ namespace osu.Game.Screens.Play private readonly List hideTargets; + private readonly Drawable playfieldComponents; + public HUDOverlay(DrawableRuleset drawableRuleset, IReadOnlyList mods, bool alwaysShowLeaderboard = true) { Drawable rulesetComponents; - this.drawableRuleset = drawableRuleset; this.mods = mods; @@ -123,6 +125,9 @@ namespace osu.Game.Screens.Play rulesetComponents = drawableRuleset != null ? new HUDComponentsContainer(drawableRuleset.Ruleset.RulesetInfo) { AlwaysPresent = true, } : Empty(), + playfieldComponents = drawableRuleset != null + ? new SkinComponentsContainer(new SkinComponentsContainerLookup(SkinComponentsContainerLookup.TargetArea.Playfield, drawableRuleset.Ruleset.RulesetInfo)) { AlwaysPresent = true, } + : Empty(), topRightElements = new FillFlowContainer { Anchor = Anchor.TopRight, @@ -162,7 +167,7 @@ namespace osu.Game.Screens.Play }, }; - hideTargets = new List { mainComponents, rulesetComponents, topRightElements }; + hideTargets = new List { mainComponents, rulesetComponents, playfieldComponents, topRightElements }; if (!alwaysShowLeaderboard) hideTargets.Add(LeaderboardFlow); @@ -230,6 +235,11 @@ namespace osu.Game.Screens.Play { base.Update(); + Quad playfieldScreenSpaceDrawQuad = drawableRuleset.Playfield.SkinnableComponentScreenSpaceDrawQuad; + + playfieldComponents.Position = ToLocalSpace(playfieldScreenSpaceDrawQuad.TopLeft); + playfieldComponents.Size = ToLocalSpace(playfieldScreenSpaceDrawQuad.BottomRight) - ToLocalSpace(playfieldScreenSpaceDrawQuad.TopLeft); + float? lowestTopScreenSpaceLeft = null; float? lowestTopScreenSpaceRight = null; diff --git a/osu.Game/Skinning/SkinComponentsContainerLookup.cs b/osu.Game/Skinning/SkinComponentsContainerLookup.cs index fbc0ab58ad..34358c3f06 100644 --- a/osu.Game/Skinning/SkinComponentsContainerLookup.cs +++ b/osu.Game/Skinning/SkinComponentsContainerLookup.cs @@ -68,7 +68,10 @@ namespace osu.Game.Skinning MainHUDComponents, [Description("Song select")] - SongSelect + SongSelect, + + [Description("Playfield")] + Playfield } } } From 26c128a09323cb0ee00cdb3c93d0463367b2f451 Mon Sep 17 00:00:00 2001 From: QuantumSno Date: Fri, 28 Jul 2023 14:39:30 -0400 Subject: [PATCH 04/90] added keybind and localization string --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 6 +++++- osu.Game/Localisation/GlobalActionKeyBindingStrings.cs | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index 01c454e3f9..3d24afbb16 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -116,9 +116,10 @@ namespace osu.Game.Input.Bindings new KeyBinding(new[] { InputKey.F3 }, GlobalAction.DecreaseScrollSpeed), new KeyBinding(new[] { InputKey.F4 }, GlobalAction.IncreaseScrollSpeed), new KeyBinding(new[] { InputKey.Shift, InputKey.Tab }, GlobalAction.ToggleInGameInterface), + new KeyBinding(InputKey.Tab, GlobalAction.ToggleInGameLeaderboard), new KeyBinding(InputKey.MouseMiddle, GlobalAction.PauseGameplay), new KeyBinding(InputKey.Control, GlobalAction.HoldForHUD), - new KeyBinding(InputKey.Tab, GlobalAction.ToggleChatFocus), + new KeyBinding(InputKey.Enter, GlobalAction.ToggleChatFocus), new KeyBinding(InputKey.F1, GlobalAction.SaveReplay), new KeyBinding(InputKey.F2, GlobalAction.ExportReplay), }; @@ -285,6 +286,9 @@ namespace osu.Game.Input.Bindings [LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.ToggleInGameInterface))] ToggleInGameInterface, + [LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.ToggleInGameLeaderboard))] + ToggleInGameLeaderboard, + // Song select keybindings [LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.ToggleModSelection))] ToggleModSelection, diff --git a/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs b/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs index f93d86225c..ceefc27968 100644 --- a/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs +++ b/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs @@ -219,6 +219,11 @@ namespace osu.Game.Localisation /// public static LocalisableString ToggleInGameInterface => new TranslatableString(getKey(@"toggle_in_game_interface"), @"Toggle in-game interface"); + /// + /// "Toggle in-game leaderboard" + /// + public static LocalisableString ToggleInGameLeaderboard => new TranslatableString(getKey(@"toggle_in_game_leaderboard"), @"Toggle in-game leaderboard"); + /// /// "Toggle mod select" /// From a4065486c198fd49fd538ba779f7e6cfb08fe79e Mon Sep 17 00:00:00 2001 From: QuantumSno Date: Fri, 28 Jul 2023 14:39:41 -0400 Subject: [PATCH 05/90] bound bind during gameplay --- osu.Game/Screens/Play/HUDOverlay.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index d11171e3fe..9c001b3db3 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -78,6 +78,7 @@ namespace osu.Game.Screens.Play public Bindable ShowHud { get; } = new BindableBool(); private Bindable configVisibilityMode; + private Bindable configLeaderboardVisibility; private Bindable configSettingsOverlay; private readonly BindableBool replayLoaded = new BindableBool(); @@ -179,6 +180,7 @@ namespace osu.Game.Screens.Play ModDisplay.Current.Value = mods; configVisibilityMode = config.GetBindable(OsuSetting.HUDVisibilityMode); + configLeaderboardVisibility = config.GetBindable(OsuSetting.GameplayLeaderboard); configSettingsOverlay = config.GetBindable(OsuSetting.ReplaySettingsOverlay); if (configVisibilityMode.Value == HUDVisibilityMode.Never && !hasShownNotificationOnce) @@ -381,6 +383,10 @@ namespace osu.Game.Screens.Play } return true; + + case GlobalAction.ToggleInGameLeaderboard: + configLeaderboardVisibility.Value = !configLeaderboardVisibility.Value; + return true; } return false; From aca8310cd1df87a131e1e1dfc7d0bc047101c578 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 28 Jul 2023 23:36:57 +0200 Subject: [PATCH 06/90] Fix non-compiling test To be fair, currently the test is a bit pointless (as it has no reason to be a `SkinnableTestScene`, it gains precisely nothing from it - all that is shown there is some generic components on song select). But that is no worse then `master`, so look away for now. --- .../Visual/Gameplay/TestSceneSkinEditorComponentsList.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorComponentsList.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorComponentsList.cs index 515bc09bbb..b7b2a6c175 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorComponentsList.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorComponentsList.cs @@ -8,6 +8,7 @@ using osu.Game.Overlays; using osu.Game.Overlays.SkinEditor; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; +using osu.Game.Skinning; namespace osu.Game.Tests.Visual.Gameplay { @@ -19,7 +20,9 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestToggleEditor() { - AddStep("show available components", () => SetContents(_ => new SkinComponentToolbox + var skinComponentsContainer = new SkinComponentsContainer(new SkinComponentsContainerLookup(SkinComponentsContainerLookup.TargetArea.SongSelect)); + + AddStep("show available components", () => SetContents(_ => new SkinComponentToolbox(skinComponentsContainer, null) { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, From 1fd4a6dc96fe5b87ee9c616a2518775a731a765e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 29 Jul 2023 01:07:08 +0200 Subject: [PATCH 07/90] Fix tests crashing due to `HUDOverlay` not finding `DrawableRuleset` in `Update()` --- osu.Game/Screens/Play/HUDOverlay.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 6696332307..536d3ac146 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -70,7 +70,9 @@ namespace osu.Game.Screens.Play public Bindable ShowHealthBar = new Bindable(true); + [CanBeNull] private readonly DrawableRuleset drawableRuleset; + private readonly IReadOnlyList mods; /// @@ -106,7 +108,7 @@ namespace osu.Game.Screens.Play private readonly Drawable playfieldComponents; - public HUDOverlay(DrawableRuleset drawableRuleset, IReadOnlyList mods, bool alwaysShowLeaderboard = true) + public HUDOverlay([CanBeNull] DrawableRuleset drawableRuleset, IReadOnlyList mods, bool alwaysShowLeaderboard = true) { Drawable rulesetComponents; this.drawableRuleset = drawableRuleset; @@ -235,10 +237,13 @@ namespace osu.Game.Screens.Play { base.Update(); - Quad playfieldScreenSpaceDrawQuad = drawableRuleset.Playfield.SkinnableComponentScreenSpaceDrawQuad; + if (drawableRuleset != null) + { + Quad playfieldScreenSpaceDrawQuad = drawableRuleset.Playfield.SkinnableComponentScreenSpaceDrawQuad; - playfieldComponents.Position = ToLocalSpace(playfieldScreenSpaceDrawQuad.TopLeft); - playfieldComponents.Size = ToLocalSpace(playfieldScreenSpaceDrawQuad.BottomRight) - ToLocalSpace(playfieldScreenSpaceDrawQuad.TopLeft); + playfieldComponents.Position = ToLocalSpace(playfieldScreenSpaceDrawQuad.TopLeft); + playfieldComponents.Size = ToLocalSpace(playfieldScreenSpaceDrawQuad.BottomRight) - ToLocalSpace(playfieldScreenSpaceDrawQuad.TopLeft); + } float? lowestTopScreenSpaceLeft = null; float? lowestTopScreenSpaceRight = null; From a3301dc7ffb0a6e4958065f8b8210a3b98c1fdc4 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Fri, 28 Jul 2023 23:22:28 -0700 Subject: [PATCH 08/90] Fix accuracy break info decimal separator being incorrect in certain languages --- osu.Game/Screens/Play/Break/BreakInfoLine.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Break/BreakInfoLine.cs b/osu.Game/Screens/Play/Break/BreakInfoLine.cs index 7261155c94..b8696352e8 100644 --- a/osu.Game/Screens/Play/Break/BreakInfoLine.cs +++ b/osu.Game/Screens/Play/Break/BreakInfoLine.cs @@ -58,7 +58,7 @@ namespace osu.Game.Screens.Play.Break private void currentValueChanged(ValueChangedEvent e) { - string newText = prefix + Format(e.NewValue); + LocalisableString newText = LocalisableString.Interpolate($"{prefix}{Format(e.NewValue)}"); if (valueText.Text == newText) return; From 8a06914438fd3d1d8bdcc462c5fe196891bee2c7 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Tue, 25 Jul 2023 20:50:55 +0900 Subject: [PATCH 09/90] remove #nullable disable in tournament --- .../NonVisual/LadderInfoSerialisationTest.cs | 5 +- .../Screens/TestSceneLadderEditorScreen.cs | 2 +- .../Screens/TestSceneSeedingEditorScreen.cs | 3 +- .../Screens/TestSceneTeamIntroScreen.cs | 2 +- .../Screens/TestSceneTeamWinScreen.cs | 2 +- .../TournamentTestScene.cs | 9 +-- .../Components/DrawableTeamFlag.cs | 10 ++- .../Components/DrawableTeamTitle.cs | 8 +-- .../Components/DrawableTournamentTeam.cs | 11 ++-- osu.Game.Tournament/Components/SongBar.cs | 8 +-- .../Components/TournamentBeatmapPanel.cs | 18 +++-- .../Components/TournamentMatchChatDisplay.cs | 4 +- .../Components/TourneyVideo.cs | 6 +- osu.Game.Tournament/IPC/FileBasedIPC.cs | 65 +++++++++---------- osu.Game.Tournament/JsonPointConverter.cs | 9 +-- osu.Game.Tournament/Models/LadderInfo.cs | 6 +- osu.Game.Tournament/Models/RoundBeatmap.cs | 1 - osu.Game.Tournament/Models/StableInfo.cs | 6 +- osu.Game.Tournament/Models/TournamentMatch.cs | 22 +++---- osu.Game.Tournament/Models/TournamentTeam.cs | 9 ++- .../Screens/Drawings/Components/Group.cs | 4 +- .../Components/ScrollingTeamContainer.cs | 27 ++++---- .../Components/StorageBackedTeamList.cs | 6 +- .../Components/VisualiserContainer.cs | 4 +- .../Screens/Drawings/DrawingsScreen.cs | 28 ++++---- .../Screens/Editors/LadderEditorScreen.cs | 64 ++++++++---------- .../Gameplay/Components/MatchHeader.cs | 8 +-- .../Gameplay/Components/TeamDisplay.cs | 2 +- .../Gameplay/Components/TeamScoreDisplay.cs | 24 ++++--- .../Components/TournamentMatchScoreDisplay.cs | 4 +- .../Screens/Gameplay/GameplayScreen.cs | 36 +++++----- .../Ladder/Components/DrawableMatchTeam.cs | 29 ++++----- .../Components/DrawableTournamentMatch.cs | 28 ++++---- .../Components/DrawableTournamentRound.cs | 4 +- .../Ladder/Components/LadderEditorSettings.cs | 22 +++---- .../Ladder/Components/SettingsTeamDropdown.cs | 2 +- .../Screens/Ladder/LadderScreen.cs | 12 ++-- .../Screens/MapPool/MapPoolScreen.cs | 38 ++++++----- .../Screens/Schedule/ScheduleScreen.cs | 10 ++- .../Screens/Setup/ResolutionSelector.cs | 6 +- .../Screens/Setup/SetupScreen.cs | 22 +++---- .../Screens/Setup/StablePathSelectScreen.cs | 12 ++-- .../Screens/Setup/TournamentSwitcher.cs | 10 ++- .../Screens/Showcase/ShowcaseScreen.cs | 2 +- .../Screens/TeamIntro/SeedingScreen.cs | 22 +++---- .../Screens/TeamIntro/TeamIntroScreen.cs | 6 +- .../Screens/TeamWin/TeamWinScreen.cs | 12 ++-- .../Screens/TournamentMatchScreen.cs | 8 +-- osu.Game.Tournament/TournamentGame.cs | 8 +-- osu.Game.Tournament/TournamentGameBase.cs | 29 +++++---- osu.Game.Tournament/TournamentSceneManager.cs | 20 +++--- 51 files changed, 333 insertions(+), 382 deletions(-) diff --git a/osu.Game.Tournament.Tests/NonVisual/LadderInfoSerialisationTest.cs b/osu.Game.Tournament.Tests/NonVisual/LadderInfoSerialisationTest.cs index 962a6fbd6c..d18651b8bb 100644 --- a/osu.Game.Tournament.Tests/NonVisual/LadderInfoSerialisationTest.cs +++ b/osu.Game.Tournament.Tests/NonVisual/LadderInfoSerialisationTest.cs @@ -3,6 +3,7 @@ using Newtonsoft.Json; using NUnit.Framework; +using osu.Framework.Extensions.ObjectExtensions; using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Tests.NonVisual @@ -35,8 +36,8 @@ namespace osu.Game.Tournament.Tests.NonVisual PlayersPerTeam = { Value = 4 }, Teams = { - match.Team1.Value, - match.Team2.Value, + match.Team1.Value.AsNonNull(), + match.Team2.Value.AsNonNull(), }, Rounds = { diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneLadderEditorScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneLadderEditorScreen.cs index 29ecdaf873..b9b150d264 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneLadderEditorScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneLadderEditorScreen.cs @@ -94,7 +94,7 @@ namespace osu.Game.Tournament.Tests.Screens AddStep("release mouse button", () => InputManager.ReleaseButton(MouseButton.Left)); - AddAssert("assert ladder teams reset", () => Ladder.CurrentMatch.Value.Team1.Value == null && Ladder.CurrentMatch.Value.Team2.Value == null); + AddAssert("assert ladder teams reset", () => Ladder.CurrentMatch.Value?.Team1.Value == null && Ladder.CurrentMatch.Value?.Team2.Value == null); } } } diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneSeedingEditorScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneSeedingEditorScreen.cs index 15d4fb1f3f..a7ef4d7a29 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneSeedingEditorScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneSeedingEditorScreen.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Game.Tournament.Models; using osu.Game.Tournament.Screens.Editors; @@ -17,7 +18,7 @@ namespace osu.Game.Tournament.Tests.Screens { var match = CreateSampleMatch(); - Add(new SeedingEditorScreen(match.Team1.Value, new TeamEditorScreen()) + Add(new SeedingEditorScreen(match.Team1.Value.AsNonNull(), new TeamEditorScreen()) { Width = 0.85f // create room for control panel }); diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneTeamIntroScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneTeamIntroScreen.cs index b76e0d7521..d6941848b7 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneTeamIntroScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneTeamIntroScreen.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tournament.Tests.Screens { Team1 = { Value = Ladder.Teams.FirstOrDefault(t => t.Acronym.Value == "USA") }, Team2 = { Value = Ladder.Teams.FirstOrDefault(t => t.Acronym.Value == "JPN") }, - Round = { Value = Ladder.Rounds.FirstOrDefault(g => g.Name.Value == "Finals") } + Round = { Value = Ladder.Rounds.First(g => g.Name.Value == "Quarterfinals") } }; Add(new TeamIntroScreen diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneTeamWinScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneTeamWinScreen.cs index 05c21fa0b1..1e3ff72d43 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneTeamWinScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneTeamWinScreen.cs @@ -17,7 +17,7 @@ namespace osu.Game.Tournament.Tests.Screens { var match = Ladder.CurrentMatch.Value!; - match.Round.Value = Ladder.Rounds.FirstOrDefault(g => g.Name.Value == "Finals"); + match.Round.Value = Ladder.Rounds.First(g => g.Name.Value == "Quarterfinals"); match.Completed.Value = true; }); diff --git a/osu.Game.Tournament.Tests/TournamentTestScene.cs b/osu.Game.Tournament.Tests/TournamentTestScene.cs index 84e5da62f4..0cf1e22211 100644 --- a/osu.Game.Tournament.Tests/TournamentTestScene.cs +++ b/osu.Game.Tournament.Tests/TournamentTestScene.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading; using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Platform; using osu.Framework.Testing; using osu.Framework.Utils; @@ -40,10 +41,10 @@ namespace osu.Game.Tournament.Tests match = CreateSampleMatch(); - Ladder.Rounds.Add(match.Round.Value); + Ladder.Rounds.Add(match.Round.Value.AsNonNull()); Ladder.Matches.Add(match); - Ladder.Teams.Add(match.Team1.Value); - Ladder.Teams.Add(match.Team2.Value); + Ladder.Teams.Add(match.Team1.Value.AsNonNull()); + Ladder.Teams.Add(match.Team2.Value.AsNonNull()); Ruleset.BindTo(Ladder.Ruleset); Dependencies.CacheAs(new StableInfo(storage)); @@ -152,7 +153,7 @@ namespace osu.Game.Tournament.Tests }, Round = { - Value = new TournamentRound { Name = { Value = "Quarterfinals" } } + Value = new TournamentRound { Name = { Value = "Quarterfinals" } }, } }; diff --git a/osu.Game.Tournament/Components/DrawableTeamFlag.cs b/osu.Game.Tournament/Components/DrawableTeamFlag.cs index 317d685ee7..aef854bb8d 100644 --- a/osu.Game.Tournament/Components/DrawableTeamFlag.cs +++ b/osu.Game.Tournament/Components/DrawableTeamFlag.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -17,14 +15,14 @@ namespace osu.Game.Tournament.Components { public partial class DrawableTeamFlag : Container { - private readonly TournamentTeam team; + private readonly TournamentTeam? team; [UsedImplicitly] - private Bindable flag; + private Bindable? flag; - private Sprite flagSprite; + private Sprite? flagSprite; - public DrawableTeamFlag(TournamentTeam team) + public DrawableTeamFlag(TournamentTeam? team) { this.team = team; } diff --git a/osu.Game.Tournament/Components/DrawableTeamTitle.cs b/osu.Game.Tournament/Components/DrawableTeamTitle.cs index 68cc46be19..85b3e5419c 100644 --- a/osu.Game.Tournament/Components/DrawableTeamTitle.cs +++ b/osu.Game.Tournament/Components/DrawableTeamTitle.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -12,12 +10,12 @@ namespace osu.Game.Tournament.Components { public partial class DrawableTeamTitle : TournamentSpriteTextWithBackground { - private readonly TournamentTeam team; + private readonly TournamentTeam? team; [UsedImplicitly] - private Bindable acronym; + private Bindable? acronym; - public DrawableTeamTitle(TournamentTeam team) + public DrawableTeamTitle(TournamentTeam? team) { this.team = team; } diff --git a/osu.Game.Tournament/Components/DrawableTournamentTeam.cs b/osu.Game.Tournament/Components/DrawableTournamentTeam.cs index 0036f5f115..9583682e8b 100644 --- a/osu.Game.Tournament/Components/DrawableTournamentTeam.cs +++ b/osu.Game.Tournament/Components/DrawableTournamentTeam.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -14,15 +12,15 @@ namespace osu.Game.Tournament.Components { public abstract partial class DrawableTournamentTeam : CompositeDrawable { - public readonly TournamentTeam Team; + public readonly TournamentTeam? Team; protected readonly Container Flag; protected readonly TournamentSpriteText AcronymText; [UsedImplicitly] - private Bindable acronym; + private Bindable? acronym; - protected DrawableTournamentTeam(TournamentTeam team) + protected DrawableTournamentTeam(TournamentTeam? team) { Team = team; @@ -36,7 +34,8 @@ namespace osu.Game.Tournament.Components [BackgroundDependencyLoader] private void load() { - if (Team == null) return; + if (Team == null) + return; (acronym = Team.Acronym.GetBoundCopy()).BindValueChanged(_ => AcronymText.Text = Team?.Acronym.Value?.ToUpperInvariant() ?? string.Empty, true); } diff --git a/osu.Game.Tournament/Components/SongBar.cs b/osu.Game.Tournament/Components/SongBar.cs index 4f4a02ccf1..19d63286d8 100644 --- a/osu.Game.Tournament/Components/SongBar.cs +++ b/osu.Game.Tournament/Components/SongBar.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -24,12 +22,12 @@ namespace osu.Game.Tournament.Components { public partial class SongBar : CompositeDrawable { - private TournamentBeatmap beatmap; + private TournamentBeatmap? beatmap; public const float HEIGHT = 145 / 2f; [Resolved] - private IBindable ruleset { get; set; } + private IBindable ruleset { get; set; } = null!; public TournamentBeatmap Beatmap { @@ -55,7 +53,7 @@ namespace osu.Game.Tournament.Components } } - private FillFlowContainer flow; + private FillFlowContainer flow = null!; private bool expanded; diff --git a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs index 49478a2174..2d5844d02b 100644 --- a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs +++ b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs @@ -22,13 +22,13 @@ namespace osu.Game.Tournament.Components { public readonly TournamentBeatmap? Beatmap; - private readonly string mod; + private readonly string? mod; public const float HEIGHT = 50; private readonly Bindable currentMatch = new Bindable(); - private Box flash = null!; + private Box? flash; public TournamentBeatmapPanel(TournamentBeatmap? beatmap, string mod = "") { @@ -135,25 +135,29 @@ namespace osu.Game.Tournament.Components match.OldValue.PicksBans.CollectionChanged -= picksBansOnCollectionChanged; if (match.NewValue != null) match.NewValue.PicksBans.CollectionChanged += picksBansOnCollectionChanged; - - Scheduler.AddOnce(updateState); + updateState(); } private void picksBansOnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) - => Scheduler.AddOnce(updateState); + => updateState(); private BeatmapChoice? choice; private void updateState() { - var newChoice = currentMatch.Value?.PicksBans.FirstOrDefault(p => p.BeatmapID == Beatmap?.OnlineID); + if (currentMatch.Value == null) + { + return; + } + + var newChoice = currentMatch.Value.PicksBans.FirstOrDefault(p => p.BeatmapID == Beatmap?.OnlineID); bool shouldFlash = newChoice != choice; if (newChoice != null) { if (shouldFlash) - flash.FadeOutFromOne(500).Loop(0, 10); + flash?.FadeOutFromOne(500).Loop(0, 10); BorderThickness = 6; diff --git a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs index e943cb8b8c..0998e606e9 100644 --- a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs +++ b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs @@ -92,9 +92,9 @@ namespace osu.Game.Tournament.Components { if (info.CurrentMatch.Value is TournamentMatch match) { - if (match.Team1.Value.Players.Any(u => u.OnlineID == Message.Sender.OnlineID)) + if (match.Team1.Value?.Players.Any(u => u.OnlineID == Message.Sender.OnlineID) == true) UsernameColour = TournamentGame.COLOUR_RED; - else if (match.Team2.Value.Players.Any(u => u.OnlineID == Message.Sender.OnlineID)) + else if (match.Team2.Value?.Players.Any(u => u.OnlineID == Message.Sender.OnlineID) == true) UsernameColour = TournamentGame.COLOUR_BLUE; } } diff --git a/osu.Game.Tournament/Components/TourneyVideo.cs b/osu.Game.Tournament/Components/TourneyVideo.cs index b9ce84b735..6e45c7556b 100644 --- a/osu.Game.Tournament/Components/TourneyVideo.cs +++ b/osu.Game.Tournament/Components/TourneyVideo.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; @@ -19,8 +17,8 @@ namespace osu.Game.Tournament.Components { private readonly string filename; private readonly bool drawFallbackGradient; - private Video video; - private ManualClock manualClock; + private Video? video; + private ManualClock? manualClock; public bool VideoAvailable => video != null; diff --git a/osu.Game.Tournament/IPC/FileBasedIPC.cs b/osu.Game.Tournament/IPC/FileBasedIPC.cs index 7babb3ea5a..333dd0fd73 100644 --- a/osu.Game.Tournament/IPC/FileBasedIPC.cs +++ b/osu.Game.Tournament/IPC/FileBasedIPC.cs @@ -1,12 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.IO; using System.Linq; -using JetBrains.Annotations; using Microsoft.Win32; using osu.Framework.Allocation; using osu.Framework.Extensions.ObjectExtensions; @@ -24,36 +21,35 @@ namespace osu.Game.Tournament.IPC { public partial class FileBasedIPC : MatchIPCInfo { - public Storage IPCStorage { get; private set; } + public Storage? IPCStorage { get; private set; } [Resolved] - protected IAPIProvider API { get; private set; } + protected IAPIProvider API { get; private set; } = null!; [Resolved] - protected IRulesetStore Rulesets { get; private set; } + protected IRulesetStore Rulesets { get; private set; } = null!; [Resolved] - private GameHost host { get; set; } + private GameHost host { get; set; } = null!; [Resolved] - private LadderInfo ladder { get; set; } + private LadderInfo ladder { get; set; } = null!; [Resolved] - private StableInfo stableInfo { get; set; } + private StableInfo stableInfo { get; set; } = null!; private int lastBeatmapId; - private ScheduledDelegate scheduled; - private GetBeatmapRequest beatmapLookupRequest; + private ScheduledDelegate? scheduled; + private GetBeatmapRequest? beatmapLookupRequest; [BackgroundDependencyLoader] private void load() { - string stablePath = stableInfo.StablePath ?? findStablePath(); + string? stablePath = stableInfo.StablePath ?? findStablePath(); initialiseIPCStorage(stablePath); } - [CanBeNull] - private Storage initialiseIPCStorage(string path) + private Storage? initialiseIPCStorage(string? path) { scheduled?.Cancel(); @@ -89,9 +85,9 @@ namespace osu.Game.Tournament.IPC lastBeatmapId = beatmapId; - var existing = ladder.CurrentMatch.Value?.Round.Value?.Beatmaps.FirstOrDefault(b => b.ID == beatmapId && b.Beatmap != null); + var existing = ladder.CurrentMatch.Value?.Round.Value?.Beatmaps.FirstOrDefault(b => b.ID == beatmapId); - if (existing != null) + if (existing?.Beatmap != null) Beatmap.Value = existing.Beatmap; else { @@ -114,7 +110,7 @@ namespace osu.Game.Tournament.IPC using (var stream = IPCStorage.GetStream(file_ipc_channel_filename)) using (var sr = new StreamReader(stream)) { - ChatChannel.Value = sr.ReadLine(); + ChatChannel.Value = sr.ReadLine().AsNonNull(); } } catch (Exception) @@ -140,8 +136,8 @@ namespace osu.Game.Tournament.IPC using (var stream = IPCStorage.GetStream(file_ipc_scores_filename)) using (var sr = new StreamReader(stream)) { - Score1.Value = int.Parse(sr.ReadLine()); - Score2.Value = int.Parse(sr.ReadLine()); + Score1.Value = int.Parse(sr.ReadLine().AsNonNull()); + Score2.Value = int.Parse(sr.ReadLine().AsNonNull()); } } catch (Exception) @@ -164,7 +160,7 @@ namespace osu.Game.Tournament.IPC /// /// Path to the IPC directory /// Whether the supplied path was a valid IPC directory. - public bool SetIPCLocation(string path) + public bool SetIPCLocation(string? path) { if (path == null || !ipcFileExistsInDirectory(path)) return false; @@ -184,29 +180,28 @@ namespace osu.Game.Tournament.IPC /// Whether an IPC directory was successfully auto-detected. public bool AutoDetectIPCLocation() => SetIPCLocation(findStablePath()); - private static bool ipcFileExistsInDirectory(string p) => p != null && File.Exists(Path.Combine(p, "ipc.txt")); + private static bool ipcFileExistsInDirectory(string? p) => p != null && File.Exists(Path.Combine(p, "ipc.txt")); - [CanBeNull] - private string findStablePath() + private string? findStablePath() { - string stableInstallPath = findFromEnvVar() ?? - findFromRegistry() ?? - findFromLocalAppData() ?? - findFromDotFolder(); + string? stableInstallPath = findFromEnvVar() ?? + findFromRegistry() ?? + findFromLocalAppData() ?? + findFromDotFolder(); Logger.Log($"Stable path for tourney usage: {stableInstallPath}"); return stableInstallPath; } - private string findFromEnvVar() + private string? findFromEnvVar() { try { Logger.Log("Trying to find stable with environment variables"); - string stableInstallPath = Environment.GetEnvironmentVariable("OSU_STABLE_PATH"); + string? stableInstallPath = Environment.GetEnvironmentVariable("OSU_STABLE_PATH"); if (ipcFileExistsInDirectory(stableInstallPath)) - return stableInstallPath; + return stableInstallPath!; } catch { @@ -215,7 +210,7 @@ namespace osu.Game.Tournament.IPC return null; } - private string findFromLocalAppData() + private string? findFromLocalAppData() { Logger.Log("Trying to find stable in %LOCALAPPDATA%"); string stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"osu!"); @@ -226,7 +221,7 @@ namespace osu.Game.Tournament.IPC return null; } - private string findFromDotFolder() + private string? findFromDotFolder() { Logger.Log("Trying to find stable in dotfolders"); string stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".osu"); @@ -237,16 +232,16 @@ namespace osu.Game.Tournament.IPC return null; } - private string findFromRegistry() + private string? findFromRegistry() { Logger.Log("Trying to find stable in registry"); try { - string stableInstallPath; + string? stableInstallPath; #pragma warning disable CA1416 - using (RegistryKey key = Registry.ClassesRoot.OpenSubKey("osu")) + using (RegistryKey? key = Registry.ClassesRoot.OpenSubKey("osu")) stableInstallPath = key?.OpenSubKey(@"shell\open\command")?.GetValue(string.Empty)?.ToString()?.Split('"')[1].Replace("osu!.exe", ""); #pragma warning restore CA1416 diff --git a/osu.Game.Tournament/JsonPointConverter.cs b/osu.Game.Tournament/JsonPointConverter.cs index d3b40a3526..a58ec47612 100644 --- a/osu.Game.Tournament/JsonPointConverter.cs +++ b/osu.Game.Tournament/JsonPointConverter.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Diagnostics; using System.Drawing; @@ -28,7 +26,7 @@ namespace osu.Game.Tournament if (reader.TokenType != JsonToken.StartObject) { // if there's no object present then this is using string representation (System.Drawing.Point serializes to "x,y") - string str = (string)reader.Value; + string? str = (string?)reader.Value; Debug.Assert(str != null); @@ -45,9 +43,12 @@ namespace osu.Game.Tournament if (reader.TokenType == JsonToken.PropertyName) { - string name = reader.Value?.ToString(); + string? name = reader.Value?.ToString(); int? val = reader.ReadAsInt32(); + if (name == null) + continue; + if (val == null) continue; diff --git a/osu.Game.Tournament/Models/LadderInfo.cs b/osu.Game.Tournament/Models/LadderInfo.cs index 229837c94e..219a2a7bfb 100644 --- a/osu.Game.Tournament/Models/LadderInfo.cs +++ b/osu.Game.Tournament/Models/LadderInfo.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using Newtonsoft.Json; @@ -17,7 +15,7 @@ namespace osu.Game.Tournament.Models [Serializable] public class LadderInfo { - public Bindable Ruleset = new Bindable(); + public Bindable Ruleset = new Bindable(); public BindableList Matches = new BindableList(); public BindableList Rounds = new BindableList(); @@ -27,7 +25,7 @@ namespace osu.Game.Tournament.Models public List Progressions = new List(); [JsonIgnore] // updated manually in TournamentGameBase - public Bindable CurrentMatch = new Bindable(); + public Bindable CurrentMatch = new Bindable(); public Bindable ChromaKeyWidth = new BindableInt(1024) { diff --git a/osu.Game.Tournament/Models/RoundBeatmap.cs b/osu.Game.Tournament/Models/RoundBeatmap.cs index f2ec261246..b03b28b3b8 100644 --- a/osu.Game.Tournament/Models/RoundBeatmap.cs +++ b/osu.Game.Tournament/Models/RoundBeatmap.cs @@ -8,7 +8,6 @@ namespace osu.Game.Tournament.Models public class RoundBeatmap { public int ID; - public string Mods = string.Empty; [JsonProperty("BeatmapInfo")] diff --git a/osu.Game.Tournament/Models/StableInfo.cs b/osu.Game.Tournament/Models/StableInfo.cs index 1ae80d4596..7ee0b4a361 100644 --- a/osu.Game.Tournament/Models/StableInfo.cs +++ b/osu.Game.Tournament/Models/StableInfo.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.IO; using Newtonsoft.Json; @@ -20,12 +18,12 @@ namespace osu.Game.Tournament.Models /// /// Path to the IPC directory used by the stable (cutting-edge) install. /// - public string StablePath { get; set; } + public string? StablePath { get; set; } /// /// Fired whenever stable info is successfully saved to file. /// - public event Action OnStableInfoSaved; + public event Action? OnStableInfoSaved; private const string config_path = "stable.json"; diff --git a/osu.Game.Tournament/Models/TournamentMatch.cs b/osu.Game.Tournament/Models/TournamentMatch.cs index 97c2060f2c..0a700eb4d6 100644 --- a/osu.Game.Tournament/Models/TournamentMatch.cs +++ b/osu.Game.Tournament/Models/TournamentMatch.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -33,16 +31,16 @@ namespace osu.Game.Tournament.Models } [JsonIgnore] - public readonly Bindable Team1 = new Bindable(); + public readonly Bindable Team1 = new Bindable(); - public string Team1Acronym; + public string? Team1Acronym; public readonly Bindable Team1Score = new Bindable(); [JsonIgnore] - public readonly Bindable Team2 = new Bindable(); + public readonly Bindable Team2 = new Bindable(); - public string Team2Acronym; + public string? Team2Acronym; public readonly Bindable Team2Score = new Bindable(); @@ -53,13 +51,13 @@ namespace osu.Game.Tournament.Models public readonly ObservableCollection PicksBans = new ObservableCollection(); [JsonIgnore] - public readonly Bindable Round = new Bindable(); + public readonly Bindable Round = new Bindable(); [JsonIgnore] - public readonly Bindable Progression = new Bindable(); + public readonly Bindable Progression = new Bindable(); [JsonIgnore] - public readonly Bindable LosersProgression = new Bindable(); + public readonly Bindable LosersProgression = new Bindable(); /// /// Should not be set directly. Use LadderInfo.CurrentMatch.Value = this instead. @@ -79,7 +77,7 @@ namespace osu.Game.Tournament.Models Team2.BindValueChanged(t => Team2Acronym = t.NewValue?.Acronym.Value, true); } - public TournamentMatch(TournamentTeam team1 = null, TournamentTeam team2 = null) + public TournamentMatch(TournamentTeam? team1 = null, TournamentTeam? team2 = null) : this() { Team1.Value = team1; @@ -87,10 +85,10 @@ namespace osu.Game.Tournament.Models } [JsonIgnore] - public TournamentTeam Winner => !Completed.Value ? null : Team1Score.Value > Team2Score.Value ? Team1.Value : Team2.Value; + public TournamentTeam? Winner => !Completed.Value ? null : Team1Score.Value > Team2Score.Value ? Team1.Value : Team2.Value; [JsonIgnore] - public TournamentTeam Loser => !Completed.Value ? null : Team1Score.Value > Team2Score.Value ? Team2.Value : Team1.Value; + public TournamentTeam? Loser => !Completed.Value ? null : Team1Score.Value > Team2Score.Value ? Team2.Value : Team1.Value; public TeamColour WinnerColour => Winner == Team1.Value ? TeamColour.Red : TeamColour.Blue; diff --git a/osu.Game.Tournament/Models/TournamentTeam.cs b/osu.Game.Tournament/Models/TournamentTeam.cs index 1beea517d5..3587aa937e 100644 --- a/osu.Game.Tournament/Models/TournamentTeam.cs +++ b/osu.Game.Tournament/Models/TournamentTeam.cs @@ -1,12 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using Newtonsoft.Json; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; namespace osu.Game.Tournament.Models { @@ -39,7 +38,7 @@ namespace osu.Game.Tournament.Models { int[] ranks = Players.Select(p => p.Rank) .Where(i => i.HasValue) - .Select(i => i.Value) + .Select(i => i.AsNonNull().Value) .ToArray(); if (ranks.Length == 0) @@ -66,14 +65,14 @@ namespace osu.Game.Tournament.Models { // use a sane default flag name based on acronym. if (val.OldValue.StartsWith(FlagName.Value, StringComparison.InvariantCultureIgnoreCase)) - FlagName.Value = val.NewValue.Length >= 2 ? val.NewValue?.Substring(0, 2).ToUpperInvariant() : string.Empty; + FlagName.Value = val.NewValue?.Length >= 2 ? val.NewValue.Substring(0, 2).ToUpperInvariant() : string.Empty; }; FullName.ValueChanged += val => { // use a sane acronym based on full name. if (val.OldValue.StartsWith(Acronym.Value, StringComparison.InvariantCultureIgnoreCase)) - Acronym.Value = val.NewValue.Length >= 3 ? val.NewValue?.Substring(0, 3).ToUpperInvariant() : string.Empty; + Acronym.Value = val.NewValue?.Length >= 3 ? val.NewValue.Substring(0, 3).ToUpperInvariant() : string.Empty; }; } diff --git a/osu.Game.Tournament/Screens/Drawings/Components/Group.cs b/osu.Game.Tournament/Screens/Drawings/Components/Group.cs index a79e2253a4..9d4474a58c 100644 --- a/osu.Game.Tournament/Screens/Drawings/Components/Group.cs +++ b/osu.Game.Tournament/Screens/Drawings/Components/Group.cs @@ -84,7 +84,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components public bool ContainsTeam(string fullName) { - return allTeams.Any(t => t.Team.FullName.Value == fullName); + return allTeams.Any(t => t.Team?.FullName.Value == fullName); } public bool RemoveTeam(TournamentTeam team) @@ -112,7 +112,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components { StringBuilder sb = new StringBuilder(); foreach (GroupTeam gt in allTeams) - sb.AppendLine(gt.Team.FullName.Value); + sb.AppendLine(gt.Team?.FullName.Value); return sb.ToString(); } } diff --git a/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs b/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs index c2b15dd3e9..4a47de8714 100644 --- a/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs +++ b/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs @@ -1,12 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; @@ -22,8 +21,8 @@ namespace osu.Game.Tournament.Screens.Drawings.Components { public partial class ScrollingTeamContainer : Container { - public event Action OnScrollStarted; - public event Action OnSelected; + public event Action? OnScrollStarted; + public event Action? OnSelected; private readonly List availableTeams = new List(); @@ -42,7 +41,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components private double lastTime; - private ScheduledDelegate delayedStateChangeDelegate; + private ScheduledDelegate? delayedStateChangeDelegate; public ScrollingTeamContainer() { @@ -117,7 +116,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components if (!Children.Any()) break; - ScrollingTeam closest = null; + ScrollingTeam? closest = null; foreach (var c in Children) { @@ -139,15 +138,14 @@ namespace osu.Game.Tournament.Screens.Drawings.Components Trace.Assert(closest != null, "closest != null"); - // ReSharper disable once PossibleNullReferenceException - offset += DrawWidth / 2f - (closest.Position.X + closest.DrawWidth / 2f); + offset += DrawWidth / 2f - (closest.AsNonNull().Position.X + closest.AsNonNull().DrawWidth / 2f); - ScrollingTeam st = closest; + ScrollingTeam st = closest.AsNonNull(); availableTeams.RemoveAll(at => at == st.Team); st.Selected = true; - OnSelected?.Invoke(st.Team); + OnSelected?.Invoke(st.Team.AsNonNull()); delayedStateChangeDelegate = Scheduler.AddDelayed(() => setScrollState(ScrollState.Idle), 10000); break; @@ -174,7 +172,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components setScrollState(ScrollState.Idle); } - public void AddTeams(IEnumerable teams) + public void AddTeams(IEnumerable? teams) { if (teams == null) return; @@ -190,8 +188,11 @@ namespace osu.Game.Tournament.Screens.Drawings.Components setScrollState(ScrollState.Idle); } - public void RemoveTeam(TournamentTeam team) + public void RemoveTeam(TournamentTeam? team) { + if (team == null) + return; + availableTeams.Remove(team); foreach (var c in Children) @@ -311,6 +312,8 @@ namespace osu.Game.Tournament.Screens.Drawings.Components public partial class ScrollingTeam : DrawableTournamentTeam { + public new TournamentTeam Team => base.Team.AsNonNull(); + public const float WIDTH = 58; public const float HEIGHT = 44; diff --git a/osu.Game.Tournament/Screens/Drawings/Components/StorageBackedTeamList.cs b/osu.Game.Tournament/Screens/Drawings/Components/StorageBackedTeamList.cs index 74afb42c1a..e13462b9bd 100644 --- a/osu.Game.Tournament/Screens/Drawings/Components/StorageBackedTeamList.cs +++ b/osu.Game.Tournament/Screens/Drawings/Components/StorageBackedTeamList.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.IO; @@ -39,7 +37,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components { while (sr.Peek() != -1) { - string line = sr.ReadLine()?.Trim(); + string? line = sr.ReadLine()?.Trim(); if (string.IsNullOrEmpty(line)) continue; @@ -56,7 +54,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components teams.Add(new TournamentTeam { FullName = { Value = split[1], }, - Acronym = { Value = split.Length >= 3 ? split[2] : null, }, + Acronym = { Value = split.Length >= 3 ? split[2] : string.Empty, }, FlagName = { Value = split[0] } }); } diff --git a/osu.Game.Tournament/Screens/Drawings/Components/VisualiserContainer.cs b/osu.Game.Tournament/Screens/Drawings/Components/VisualiserContainer.cs index 676eec14cd..d5e39e3f44 100644 --- a/osu.Game.Tournament/Screens/Drawings/Components/VisualiserContainer.cs +++ b/osu.Game.Tournament/Screens/Drawings/Components/VisualiserContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; @@ -72,7 +70,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components private float leftPos => -(float)((Time.Current + Offset) / CycleTime) + expiredCount; - private Texture texture; + private Texture texture = null!; private int expiredCount; diff --git a/osu.Game.Tournament/Screens/Drawings/DrawingsScreen.cs b/osu.Game.Tournament/Screens/Drawings/DrawingsScreen.cs index 23d0edf26e..b2dd4e8c36 100644 --- a/osu.Game.Tournament/Screens/Drawings/DrawingsScreen.cs +++ b/osu.Game.Tournament/Screens/Drawings/DrawingsScreen.cs @@ -1,14 +1,13 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -28,27 +27,27 @@ namespace osu.Game.Tournament.Screens.Drawings { private const string results_filename = "drawings_results.txt"; - private ScrollingTeamContainer teamsContainer; - private GroupContainer groupsContainer; - private TournamentSpriteText fullTeamNameText; + private ScrollingTeamContainer teamsContainer = null!; + private GroupContainer groupsContainer = null!; + private TournamentSpriteText fullTeamNameText = null!; private readonly List allTeams = new List(); - private DrawingsConfigManager drawingsConfig; + private DrawingsConfigManager drawingsConfig = null!; - private Task writeOp; + private Task? writeOp; - private Storage storage; + private Storage storage = null!; - public ITeamList TeamList; + public ITeamList? TeamList; [BackgroundDependencyLoader] private void load(Storage storage) { - RelativeSizeAxes = Axes.Both; - this.storage = storage; + RelativeSizeAxes = Axes.Both; + TeamList ??= new StorageBackedTeamList(storage); if (!TeamList.Teams.Any()) @@ -224,7 +223,7 @@ namespace osu.Game.Tournament.Screens.Drawings teamsContainer.ClearTeams(); allTeams.Clear(); - foreach (TournamentTeam t in TeamList.Teams) + foreach (TournamentTeam t in TeamList.AsNonNull().Teams) { if (groupsContainer.ContainsTeam(t.FullName.Value)) continue; @@ -251,7 +250,7 @@ namespace osu.Game.Tournament.Screens.Drawings using (Stream stream = storage.GetStream(results_filename, FileAccess.Read, FileMode.Open)) using (StreamReader sr = new StreamReader(stream)) { - string line; + string? line; while ((line = sr.ReadLine()?.Trim()) != null) { @@ -261,8 +260,7 @@ namespace osu.Game.Tournament.Screens.Drawings if (line.ToUpperInvariant().StartsWith("GROUP", StringComparison.Ordinal)) continue; - // ReSharper disable once AccessToModifiedClosure - TournamentTeam teamToAdd = allTeams.FirstOrDefault(t => t.FullName.Value == line); + TournamentTeam? teamToAdd = allTeams.FirstOrDefault(t => t.FullName.Value == line); if (teamToAdd == null) continue; diff --git a/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs index 9411892dc5..a82ac57ee9 100644 --- a/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs @@ -1,12 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Drawing; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -35,13 +32,12 @@ namespace osu.Game.Tournament.Screens.Editors [Cached] private LadderEditorInfo editorInfo = new LadderEditorInfo(); - private WarningBox rightClickMessage; + private WarningBox rightClickMessage = null!; - private RectangularPositionSnapGrid grid; + private RectangularPositionSnapGrid grid = null!; [Resolved(canBeNull: true)] - [CanBeNull] - private IDialogOverlay dialogOverlay { get; set; } + private IDialogOverlay? dialogOverlay { get; set; } protected override bool DrawLoserPaths => true; @@ -94,36 +90,28 @@ namespace osu.Game.Tournament.Screens.Editors ScrollContent.Add(new JoinVisualiser(MatchesContainer, match, losers, UpdateLayout)); } - public MenuItem[] ContextMenuItems - { - get + public MenuItem[] ContextMenuItems => + new MenuItem[] { - if (editorInfo == null) - return Array.Empty(); - - return new MenuItem[] + new OsuMenuItem("Create new match", MenuItemType.Highlighted, () => { - new OsuMenuItem("Create new match", MenuItemType.Highlighted, () => + Vector2 pos = MatchesContainer.Count == 0 ? Vector2.Zero : lastMatchesContainerMouseDownPosition; + + TournamentMatch newMatch = new TournamentMatch { Position = { Value = new Point((int)pos.X, (int)pos.Y) } }; + + LadderInfo.Matches.Add(newMatch); + + editorInfo.Selected.Value = newMatch; + }), + new OsuMenuItem("Reset teams", MenuItemType.Destructive, () => + { + dialogOverlay?.Push(new LadderResetTeamsDialog(() => { - Vector2 pos = MatchesContainer.Count == 0 ? Vector2.Zero : lastMatchesContainerMouseDownPosition; - - TournamentMatch newMatch = new TournamentMatch { Position = { Value = new Point((int)pos.X, (int)pos.Y) } }; - - LadderInfo.Matches.Add(newMatch); - - editorInfo.Selected.Value = newMatch; - }), - new OsuMenuItem("Reset teams", MenuItemType.Destructive, () => - { - dialogOverlay?.Push(new LadderResetTeamsDialog(() => - { - foreach (var p in MatchesContainer) - p.Match.Reset(); - })); - }) - }; - } - } + foreach (var p in MatchesContainer) + p.Match.Reset(); + })); + }) + }; public void Remove(TournamentMatch match) { @@ -135,11 +123,11 @@ namespace osu.Game.Tournament.Screens.Editors private readonly Container matchesContainer; public readonly TournamentMatch Source; private readonly bool losers; - private readonly Action complete; + private readonly Action? complete; - private ProgressionPath path; + private ProgressionPath? path; - public JoinVisualiser(Container matchesContainer, TournamentMatch source, bool losers, Action complete) + public JoinVisualiser(Container matchesContainer, TournamentMatch source, bool losers, Action? complete) { this.matchesContainer = matchesContainer; RelativeSizeAxes = Axes.Both; @@ -153,7 +141,7 @@ namespace osu.Game.Tournament.Screens.Editors Source.Progression.Value = null; } - private DrawableTournamentMatch findTarget(InputState state) + private DrawableTournamentMatch? findTarget(InputState state) { return matchesContainer.FirstOrDefault(d => d.ReceivePositionalInputAt(state.Mouse.Position)); } diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs b/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs index 8f7484980d..69f150c8ac 100644 --- a/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs +++ b/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -14,9 +12,9 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components { public partial class MatchHeader : Container { - private TeamScoreDisplay teamDisplay1; - private TeamScoreDisplay teamDisplay2; - private DrawableTournamentHeaderLogo logo; + private TeamScoreDisplay teamDisplay1 = null!; + private TeamScoreDisplay teamDisplay2 = null!; + private DrawableTournamentHeaderLogo logo = null!; private bool showScores = true; diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/TeamDisplay.cs b/osu.Game.Tournament/Screens/Gameplay/Components/TeamDisplay.cs index c23327a43f..3fdbbb5973 100644 --- a/osu.Game.Tournament/Screens/Gameplay/Components/TeamDisplay.cs +++ b/osu.Game.Tournament/Screens/Gameplay/Components/TeamDisplay.cs @@ -35,7 +35,7 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components } } - public TeamDisplay(TournamentTeam team, TeamColour colour, Bindable currentTeamScore, int pointsToWin) + public TeamDisplay(TournamentTeam? team, TeamColour colour, Bindable currentTeamScore, int pointsToWin) : base(team) { AutoSizeAxes = Axes.Both; diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/TeamScoreDisplay.cs b/osu.Game.Tournament/Screens/Gameplay/Components/TeamScoreDisplay.cs index 57fe1c7312..c7fcfae602 100644 --- a/osu.Game.Tournament/Screens/Gameplay/Components/TeamScoreDisplay.cs +++ b/osu.Game.Tournament/Screens/Gameplay/Components/TeamScoreDisplay.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -17,16 +15,22 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components { private readonly TeamColour teamColour; - private readonly Bindable currentMatch = new Bindable(); - private readonly Bindable currentTeam = new Bindable(); + private readonly Bindable currentMatch = new Bindable(); + private readonly Bindable currentTeam = new Bindable(); private readonly Bindable currentTeamScore = new Bindable(); - private TeamDisplay teamDisplay; + private TeamDisplay? teamDisplay; public bool ShowScore { - get => teamDisplay.ShowScore; - set => teamDisplay.ShowScore = value; + get => teamDisplay?.ShowScore ?? false; + set + { + if (teamDisplay != null) + { + teamDisplay.ShowScore = value; + } + } } public TeamScoreDisplay(TeamColour teamColour) @@ -48,7 +52,7 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components updateMatch(); } - private void matchChanged(ValueChangedEvent match) + private void matchChanged(ValueChangedEvent match) { currentTeamScore.UnbindBindings(); currentTeam.UnbindBindings(); @@ -78,7 +82,7 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components switch (e.Button) { case MouseButton.Left: - if (currentTeamScore.Value < currentMatch.Value.PointsToWin) + if (currentTeamScore.Value < currentMatch.Value?.PointsToWin) currentTeamScore.Value++; return true; @@ -91,7 +95,7 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components return base.OnMouseDown(e); } - private void teamChanged(ValueChangedEvent team) + private void teamChanged(ValueChangedEvent team) { bool wasShowingScores = teamDisplay?.ShowScore ?? false; diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/TournamentMatchScoreDisplay.cs b/osu.Game.Tournament/Screens/Gameplay/Components/TournamentMatchScoreDisplay.cs index 838e5fa071..7ae20acc77 100644 --- a/osu.Game.Tournament/Screens/Gameplay/Components/TournamentMatchScoreDisplay.cs +++ b/osu.Game.Tournament/Screens/Gameplay/Components/TournamentMatchScoreDisplay.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -146,7 +144,7 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components private partial class MatchScoreCounter : CommaSeparatedScoreCounter { - private OsuSpriteText displayedSpriteText; + private OsuSpriteText displayedSpriteText = null!; public MatchScoreCounter() { diff --git a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs index 4258522cff..79c50e60ba 100644 --- a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs +++ b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -26,16 +24,16 @@ namespace osu.Game.Tournament.Screens.Gameplay private readonly BindableBool warmup = new BindableBool(); public readonly Bindable State = new Bindable(); - private OsuButton warmupButton; - private MatchIPCInfo ipc; + private OsuButton warmupButton = null!; + private MatchIPCInfo ipc = null!; [Resolved(canBeNull: true)] - private TournamentSceneManager sceneManager { get; set; } + private TournamentSceneManager? sceneManager { get; set; } [Resolved] - private TournamentMatchChatDisplay chat { get; set; } + private TournamentMatchChatDisplay chat { get; set; } = null!; - private Drawable chroma; + private Drawable chroma = null!; [BackgroundDependencyLoader] private void load(LadderInfo ladder, MatchIPCInfo ipc) @@ -142,7 +140,7 @@ namespace osu.Game.Tournament.Screens.Gameplay State.BindValueChanged(_ => updateState(), true); } - protected override void CurrentMatchChanged(ValueChangedEvent match) + protected override void CurrentMatchChanged(ValueChangedEvent match) { base.CurrentMatchChanged(match); @@ -153,29 +151,35 @@ namespace osu.Game.Tournament.Screens.Gameplay scheduledScreenChange?.Cancel(); } - private ScheduledDelegate scheduledScreenChange; - private ScheduledDelegate scheduledContract; + private ScheduledDelegate? scheduledScreenChange; + private ScheduledDelegate? scheduledContract; - private TournamentMatchScoreDisplay scoreDisplay; + private TournamentMatchScoreDisplay scoreDisplay = null!; private TourneyState lastState; - private MatchHeader header; + private MatchHeader header = null!; private void contract() { + if (!IsLoaded) + return; + scheduledContract?.Cancel(); SongBar.Expanded = false; scoreDisplay.FadeOut(100); - using (chat?.BeginDelayedSequence(500)) - chat?.Expand(); + using (chat.BeginDelayedSequence(500)) + chat.Expand(); } private void expand() { + if (!IsLoaded) + return; + scheduledContract?.Cancel(); - chat?.Contract(); + chat.Contract(); using (BeginDelayedSequence(300)) { @@ -252,7 +256,7 @@ namespace osu.Game.Tournament.Screens.Gameplay private partial class ChromaArea : CompositeDrawable { [Resolved] - private LadderInfo ladder { get; set; } + private LadderInfo ladder { get; set; } = null!; [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs b/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs index 2b66df1a31..a380ad9b49 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -28,20 +26,20 @@ namespace osu.Game.Tournament.Screens.Ladder.Components { private readonly TournamentMatch match; private readonly bool losers; - private TournamentSpriteText scoreText; - private Box background; - private Box backgroundRight; + private TournamentSpriteText scoreText = null!; + private Box background = null!; + private Box backgroundRight = null!; private readonly Bindable score = new Bindable(); private readonly BindableBool completed = new BindableBool(); private Color4 colourWinner; - private readonly Func isWinner; - private LadderEditorScreen ladderEditor; + private readonly Func? isWinner; + private LadderEditorScreen ladderEditor = null!; [Resolved(canBeNull: true)] - private LadderInfo ladderInfo { get; set; } + private LadderInfo? ladderInfo { get; set; } private void setCurrent() { @@ -56,9 +54,9 @@ namespace osu.Game.Tournament.Screens.Ladder.Components } [Resolved(CanBeNull = true)] - private LadderEditorInfo editorInfo { get; set; } + private LadderEditorInfo? editorInfo { get; set; } - public DrawableMatchTeam(TournamentTeam team, TournamentMatch match, bool losers) + public DrawableMatchTeam(TournamentTeam? team, TournamentMatch match, bool losers) : base(team) { this.match = match; @@ -72,14 +70,11 @@ namespace osu.Game.Tournament.Screens.Ladder.Components AcronymText.Padding = new MarginPadding { Left = 50 }; AcronymText.Font = OsuFont.Torus.With(size: 22, weight: FontWeight.Bold); - if (match != null) - { - isWinner = () => match.Winner == Team; + isWinner = () => match.Winner == Team; - completed.BindTo(match.Completed); - if (team != null) - score.BindTo(team == match.Team1.Value ? match.Team1Score : match.Team2Score); - } + completed.BindTo(match.Completed); + if (team != null) + score.BindTo(team == match.Team1.Value ? match.Team1Score : match.Team2Score); } [BackgroundDependencyLoader(true)] diff --git a/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs b/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs index c394877ae9..7b8f2e373b 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs @@ -1,10 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; +using System.Diagnostics; using System.Drawing; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -27,13 +26,13 @@ namespace osu.Game.Tournament.Screens.Ladder.Components protected readonly FillFlowContainer Flow; private readonly Drawable selectionBox; private readonly Drawable currentMatchSelectionBox; - private Bindable globalSelection; + private Bindable? globalSelection; [Resolved(CanBeNull = true)] - private LadderEditorInfo editorInfo { get; set; } + private LadderEditorInfo? editorInfo { get; set; } [Resolved(CanBeNull = true)] - private LadderInfo ladderInfo { get; set; } + private LadderInfo? ladderInfo { get; set; } public DrawableTournamentMatch(TournamentMatch match, bool editor = false) { @@ -129,7 +128,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components /// /// Fired when something changed that requires a ladder redraw. /// - public Action Changed; + public Action? Changed; private readonly List refBindables = new List(); @@ -201,20 +200,22 @@ namespace osu.Game.Tournament.Screens.Ladder.Components } else { - transferProgression(Match.Progression?.Value, Match.Winner); - transferProgression(Match.LosersProgression?.Value, Match.Loser); + Debug.Assert(Match.Winner != null); + transferProgression(Match.Progression.Value, Match.Winner); + Debug.Assert(Match.Loser != null); + transferProgression(Match.LosersProgression.Value, Match.Loser); } Changed?.Invoke(); } - private void transferProgression(TournamentMatch destination, TournamentTeam team) + private void transferProgression(TournamentMatch? destination, TournamentTeam team) { if (destination == null) return; bool progressionAbove = destination.ID < Match.ID; - Bindable destinationTeam; + Bindable destinationTeam; // check for the case where we have already transferred out value if (destination.Team1.Value == team) @@ -268,8 +269,8 @@ namespace osu.Game.Tournament.Screens.Ladder.Components { foreach (var conditional in Match.ConditionalMatches) { - bool team1Match = conditional.Acronyms.Contains(Match.Team1Acronym); - bool team2Match = conditional.Acronyms.Contains(Match.Team2Acronym); + bool team1Match = Match.Team1Acronym != null && conditional.Acronyms.Contains(Match.Team1Acronym); + bool team2Match = Match.Team2Acronym != null && conditional.Acronyms.Contains(Match.Team2Acronym); if (team1Match && team2Match) Match.Date.Value = conditional.Date.Value; @@ -344,6 +345,9 @@ namespace osu.Game.Tournament.Screens.Ladder.Components Match.Progression.Value = null; Match.LosersProgression.Value = null; + if (ladderInfo == null) + return; + ladderInfo.Matches.Remove(Match); foreach (var m in ladderInfo.Matches) diff --git a/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentRound.cs b/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentRound.cs index 4b2a29247b..216e0a5a3e 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentRound.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentRound.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using JetBrains.Annotations; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -52,7 +50,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components name.BindValueChanged(_ => textName.Text = ((losers ? "Losers " : "") + round.Name).ToUpperInvariant(), true); description = round.Description.GetBoundCopy(); - description.BindValueChanged(_ => textDescription.Text = round.Description.Value?.ToUpperInvariant(), true); + description.BindValueChanged(_ => textDescription.Text = round.Description.Value?.ToUpperInvariant() ?? string.Empty, true); } } } diff --git a/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs b/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs index 5c9c14cc30..9f0fa19915 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; @@ -23,17 +21,17 @@ namespace osu.Game.Tournament.Screens.Ladder.Components { public partial class LadderEditorSettings : CompositeDrawable { - private SettingsDropdown roundDropdown; - private PlayerCheckbox losersCheckbox; - private DateTextBox dateTimeBox; - private SettingsTeamDropdown team1Dropdown; - private SettingsTeamDropdown team2Dropdown; + private SettingsDropdown roundDropdown = null!; + private PlayerCheckbox losersCheckbox = null!; + private DateTextBox dateTimeBox = null!; + private SettingsTeamDropdown team1Dropdown = null!; + private SettingsTeamDropdown team2Dropdown = null!; [Resolved] - private LadderEditorInfo editorInfo { get; set; } + private LadderEditorInfo editorInfo { get; set; } = null!; [Resolved] - private LadderInfo ladderInfo { get; set; } + private LadderInfo ladderInfo { get; set; } = null!; [BackgroundDependencyLoader] private void load() @@ -77,7 +75,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components }; } - private void roundDropdownChanged(ValueChangedEvent round) + private void roundDropdownChanged(ValueChangedEvent round) { if (editorInfo.Selected.Value?.Date.Value < round.NewValue?.StartDate.Value) { @@ -101,11 +99,11 @@ namespace osu.Game.Tournament.Screens.Ladder.Components { } - private partial class SettingsRoundDropdown : SettingsDropdown + private partial class SettingsRoundDropdown : SettingsDropdown { public SettingsRoundDropdown(BindableList rounds) { - Current = new Bindable(); + Current = new Bindable(); foreach (var r in rounds.Prepend(new TournamentRound())) add(r); diff --git a/osu.Game.Tournament/Screens/Ladder/Components/SettingsTeamDropdown.cs b/osu.Game.Tournament/Screens/Ladder/Components/SettingsTeamDropdown.cs index 00e5353edd..7e35190e2e 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/SettingsTeamDropdown.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/SettingsTeamDropdown.cs @@ -12,7 +12,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Screens.Ladder.Components { - public partial class SettingsTeamDropdown : SettingsDropdown + public partial class SettingsTeamDropdown : SettingsDropdown { public SettingsTeamDropdown(BindableList teams) { diff --git a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs index 2d5281b893..4f56a2fcc9 100644 --- a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs +++ b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Specialized; using System.Diagnostics; using System.Linq; @@ -22,13 +20,13 @@ namespace osu.Game.Tournament.Screens.Ladder { public partial class LadderScreen : TournamentScreen { - protected Container MatchesContainer; - private Container paths; - private Container headings; + protected Container MatchesContainer = null!; + private Container paths = null!; + private Container headings = null!; - protected LadderDragContainer ScrollContent; + protected LadderDragContainer ScrollContent = null!; - protected Container Content; + protected Container Content = null!; [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs b/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs index f45da861cb..3091f4293c 100644 --- a/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs +++ b/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -24,20 +22,20 @@ namespace osu.Game.Tournament.Screens.MapPool { public partial class MapPoolScreen : TournamentMatchScreen { - private FillFlowContainer> mapFlows; + private FillFlowContainer> mapFlows = null!; [Resolved(canBeNull: true)] - private TournamentSceneManager sceneManager { get; set; } + private TournamentSceneManager? sceneManager { get; set; } private TeamColour pickColour; private ChoiceType pickType; - private OsuButton buttonRedBan; - private OsuButton buttonBlueBan; - private OsuButton buttonRedPick; - private OsuButton buttonBluePick; + private OsuButton buttonRedBan = null!; + private OsuButton buttonBlueBan = null!; + private OsuButton buttonRedPick = null!; + private OsuButton buttonBluePick = null!; - private ScheduledDelegate scheduledScreenChange; + private ScheduledDelegate? scheduledScreenChange; [BackgroundDependencyLoader] private void load(MatchIPCInfo ipc) @@ -113,7 +111,7 @@ namespace osu.Game.Tournament.Screens.MapPool ipc.Beatmap.BindValueChanged(beatmapChanged); } - private Bindable splitMapPoolByMods; + private Bindable? splitMapPoolByMods; protected override void LoadComplete() { @@ -148,6 +146,9 @@ namespace osu.Game.Tournament.Screens.MapPool private void setNextMode() { + if (CurrentMatch.Value == null) + return; + const TeamColour roll_winner = TeamColour.Red; //todo: draw from match var nextColour = (CurrentMatch.Value.PicksBans.LastOrDefault()?.Team ?? roll_winner) == TeamColour.Red ? TeamColour.Blue : TeamColour.Red; @@ -169,11 +170,11 @@ namespace osu.Game.Tournament.Screens.MapPool addForBeatmap(map.Beatmap.OnlineID); else { - var existing = CurrentMatch.Value.PicksBans.FirstOrDefault(p => p.BeatmapID == map.Beatmap?.OnlineID); + var existing = CurrentMatch.Value?.PicksBans.FirstOrDefault(p => p.BeatmapID == map.Beatmap?.OnlineID); if (existing != null) { - CurrentMatch.Value.PicksBans.Remove(existing); + CurrentMatch.Value?.PicksBans.Remove(existing); setNextMode(); } } @@ -186,13 +187,13 @@ namespace osu.Game.Tournament.Screens.MapPool private void reset() { - CurrentMatch.Value.PicksBans.Clear(); + CurrentMatch.Value?.PicksBans.Clear(); setNextMode(); } private void addForBeatmap(int beatmapId) { - if (CurrentMatch.Value == null) + if (CurrentMatch.Value?.Round.Value == null) return; if (CurrentMatch.Value.Round.Value.Beatmaps.All(b => b.Beatmap?.OnlineID != beatmapId)) @@ -228,7 +229,7 @@ namespace osu.Game.Tournament.Screens.MapPool base.Hide(); } - protected override void CurrentMatchChanged(ValueChangedEvent match) + protected override void CurrentMatchChanged(ValueChangedEvent match) { base.CurrentMatchChanged(match); updateDisplay(); @@ -245,12 +246,15 @@ namespace osu.Game.Tournament.Screens.MapPool if (CurrentMatch.Value.Round.Value != null) { - FillFlowContainer currentFlow = null; - string currentMods = null; + FillFlowContainer? currentFlow = null; + string? currentMods = null; int flowCount = 0; foreach (var b in CurrentMatch.Value.Round.Value.Beatmaps) { + if (b.Beatmap == null) + continue; + if (currentFlow == null || (LadderInfo.SplitMapPoolByMods.Value && currentMods != b.Mods)) { mapFlows.Add(currentFlow = new FillFlowContainer diff --git a/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs b/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs index 9232b4c689..063c231add 100644 --- a/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs +++ b/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using osu.Framework.Allocation; @@ -21,9 +19,9 @@ namespace osu.Game.Tournament.Screens.Schedule { public partial class ScheduleScreen : TournamentScreen { - private readonly Bindable currentMatch = new Bindable(); - private Container mainContainer; - private LadderInfo ladder; + private readonly Bindable currentMatch = new Bindable(); + private Container mainContainer = null!; + private LadderInfo ladder = null!; [BackgroundDependencyLoader] private void load(LadderInfo ladder) @@ -107,7 +105,7 @@ namespace osu.Game.Tournament.Screens.Schedule currentMatch.BindValueChanged(matchChanged, true); } - private void matchChanged(ValueChangedEvent match) + private void matchChanged(ValueChangedEvent match) { var upcoming = ladder.Matches.Where(p => !p.Completed.Value && p.Team1.Value != null && p.Team2.Value != null && Math.Abs(p.Date.Value.DayOfYear - DateTimeOffset.UtcNow.DayOfYear) < 4); var conditionals = ladder diff --git a/osu.Game.Tournament/Screens/Setup/ResolutionSelector.cs b/osu.Game.Tournament/Screens/Setup/ResolutionSelector.cs index e6ab6f143a..c700e3bfdd 100644 --- a/osu.Game.Tournament/Screens/Setup/ResolutionSelector.cs +++ b/osu.Game.Tournament/Screens/Setup/ResolutionSelector.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Graphics; using osu.Game.Graphics.UserInterface; @@ -14,9 +12,9 @@ namespace osu.Game.Tournament.Screens.Setup private const int minimum_window_height = 480; private const int maximum_window_height = 2160; - public new Action Action; + public new Action? Action; - private OsuNumberBox numberBox; + private OsuNumberBox? numberBox; protected override Drawable CreateComponent() { diff --git a/osu.Game.Tournament/Screens/Setup/SetupScreen.cs b/osu.Game.Tournament/Screens/Setup/SetupScreen.cs index 5c7bbed69c..1152759c2a 100644 --- a/osu.Game.Tournament/Screens/Setup/SetupScreen.cs +++ b/osu.Game.Tournament/Screens/Setup/SetupScreen.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Drawing; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -24,27 +22,27 @@ namespace osu.Game.Tournament.Screens.Setup { public partial class SetupScreen : TournamentScreen { - private FillFlowContainer fillFlow; + private FillFlowContainer fillFlow = null!; - private LoginOverlay loginOverlay; - private ResolutionSelector resolution; + private LoginOverlay? loginOverlay; + private ResolutionSelector resolution = null!; [Resolved] - private MatchIPCInfo ipc { get; set; } + private MatchIPCInfo ipc { get; set; } = null!; [Resolved] - private StableInfo stableInfo { get; set; } + private StableInfo stableInfo { get; set; } = null!; [Resolved] - private IAPIProvider api { get; set; } + private IAPIProvider api { get; set; } = null!; [Resolved] - private RulesetStore rulesets { get; set; } + private RulesetStore rulesets { get; set; } = null!; [Resolved(canBeNull: true)] - private TournamentSceneManager sceneManager { get; set; } + private TournamentSceneManager? sceneManager { get; set; } - private Bindable windowSize; + private Bindable windowSize = null!; [BackgroundDependencyLoader] private void load(FrameworkConfigManager frameworkConfig) @@ -115,7 +113,7 @@ namespace osu.Game.Tournament.Screens.Setup Failing = api.IsLoggedIn != true, Description = "In order to access the API and display metadata, signing in is required." }, - new LabelledDropdown + new LabelledDropdown { Label = "Ruleset", Description = "Decides what stats are displayed and which ranks are retrieved for players. This requires a restart to reload data for an existing bracket.", diff --git a/osu.Game.Tournament/Screens/Setup/StablePathSelectScreen.cs b/osu.Game.Tournament/Screens/Setup/StablePathSelectScreen.cs index 463b012b77..c3d072b6a0 100644 --- a/osu.Game.Tournament/Screens/Setup/StablePathSelectScreen.cs +++ b/osu.Game.Tournament/Screens/Setup/StablePathSelectScreen.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.IO; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -24,19 +22,19 @@ namespace osu.Game.Tournament.Screens.Setup public partial class StablePathSelectScreen : TournamentScreen { [Resolved(canBeNull: true)] - private TournamentSceneManager sceneManager { get; set; } + private TournamentSceneManager? sceneManager { get; set; } [Resolved] - private MatchIPCInfo ipc { get; set; } + private MatchIPCInfo ipc { get; set; } = null!; - private OsuDirectorySelector directorySelector; - private DialogOverlay overlay; + private OsuDirectorySelector directorySelector = null!; + private DialogOverlay? overlay; [BackgroundDependencyLoader(true)] private void load(Storage storage, OsuColour colours) { var initialStorage = (ipc as FileBasedIPC)?.IPCStorage ?? storage; - string initialPath = new DirectoryInfo(initialStorage.GetFullPath(string.Empty)).Parent?.FullName; + string? initialPath = new DirectoryInfo(initialStorage.GetFullPath(string.Empty)).Parent?.FullName; AddRangeInternal(new Drawable[] { diff --git a/osu.Game.Tournament/Screens/Setup/TournamentSwitcher.cs b/osu.Game.Tournament/Screens/Setup/TournamentSwitcher.cs index ae49ccb63b..e55cbc2dbb 100644 --- a/osu.Game.Tournament/Screens/Setup/TournamentSwitcher.cs +++ b/osu.Game.Tournament/Screens/Setup/TournamentSwitcher.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Graphics.UserInterface; @@ -13,12 +11,12 @@ namespace osu.Game.Tournament.Screens.Setup { internal partial class TournamentSwitcher : ActionableInfo { - private OsuDropdown dropdown; - private OsuButton folderButton; - private OsuButton reloadTournamentsButton; + private OsuDropdown dropdown = null!; + private OsuButton folderButton = null!; + private OsuButton reloadTournamentsButton = null!; [Resolved] - private TournamentGameBase game { get; set; } + private TournamentGameBase game { get; set; } = null!; [BackgroundDependencyLoader] private void load(TournamentStorage storage) diff --git a/osu.Game.Tournament/Screens/Showcase/ShowcaseScreen.cs b/osu.Game.Tournament/Screens/Showcase/ShowcaseScreen.cs index db4d6198e6..ae2ec0c291 100644 --- a/osu.Game.Tournament/Screens/Showcase/ShowcaseScreen.cs +++ b/osu.Game.Tournament/Screens/Showcase/ShowcaseScreen.cs @@ -42,7 +42,7 @@ namespace osu.Game.Tournament.Screens.Showcase }); } - protected override void CurrentMatchChanged(ValueChangedEvent match) + protected override void CurrentMatchChanged(ValueChangedEvent match) { // showcase screen doesn't care about a match being selected. // base call intentionally omitted to not show match warning. diff --git a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs index b07a0a65dd..120a76c127 100644 --- a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs +++ b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -22,12 +20,12 @@ namespace osu.Game.Tournament.Screens.TeamIntro { public partial class SeedingScreen : TournamentMatchScreen { - private Container mainContainer; + private Container mainContainer = null!; - private readonly Bindable currentTeam = new Bindable(); + private readonly Bindable currentTeam = new Bindable(); - private TourneyButton showFirstTeamButton; - private TourneyButton showSecondTeamButton; + private TourneyButton showFirstTeamButton = null!; + private TourneyButton showSecondTeamButton = null!; [BackgroundDependencyLoader] private void load() @@ -53,13 +51,13 @@ namespace osu.Game.Tournament.Screens.TeamIntro { RelativeSizeAxes = Axes.X, Text = "Show first team", - Action = () => currentTeam.Value = CurrentMatch.Value.Team1.Value, + Action = () => currentTeam.Value = CurrentMatch.Value?.Team1.Value, }, showSecondTeamButton = new TourneyButton { RelativeSizeAxes = Axes.X, Text = "Show second team", - Action = () => currentTeam.Value = CurrentMatch.Value.Team2.Value, + Action = () => currentTeam.Value = CurrentMatch.Value?.Team2.Value, }, new SettingsTeamDropdown(LadderInfo.Teams) { @@ -73,7 +71,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro currentTeam.BindValueChanged(teamChanged, true); } - private void teamChanged(ValueChangedEvent team) => updateTeamDisplay(); + private void teamChanged(ValueChangedEvent team) => updateTeamDisplay(); public override void Show() { @@ -84,7 +82,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro updateTeamDisplay(); } - protected override void CurrentMatchChanged(ValueChangedEvent match) + protected override void CurrentMatchChanged(ValueChangedEvent match) { base.CurrentMatchChanged(match); @@ -256,7 +254,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro private partial class LeftInfo : CompositeDrawable { - public LeftInfo(TournamentTeam team) + public LeftInfo(TournamentTeam? team) { FillFlowContainer fill; @@ -315,7 +313,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro private partial class TeamDisplay : DrawableTournamentTeam { - public TeamDisplay(TournamentTeam team) + public TeamDisplay(TournamentTeam? team) : base(team) { AutoSizeAxes = Axes.Both; diff --git a/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs index 950a63808c..2280f21d47 100644 --- a/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs +++ b/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -15,7 +13,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro { public partial class TeamIntroScreen : TournamentMatchScreen { - private Container mainContainer; + private Container mainContainer = null!; [BackgroundDependencyLoader] private void load() @@ -36,7 +34,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro }; } - protected override void CurrentMatchChanged(ValueChangedEvent match) + protected override void CurrentMatchChanged(ValueChangedEvent match) { base.CurrentMatchChanged(match); diff --git a/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs b/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs index 9206de1dc2..af21613541 100644 --- a/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs +++ b/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -16,12 +14,12 @@ namespace osu.Game.Tournament.Screens.TeamWin { public partial class TeamWinScreen : TournamentMatchScreen { - private Container mainContainer; + private Container mainContainer = null!; private readonly Bindable currentCompleted = new Bindable(); - private TourneyVideo blueWinVideo; - private TourneyVideo redWinVideo; + private TourneyVideo blueWinVideo = null!; + private TourneyVideo redWinVideo = null!; [BackgroundDependencyLoader] private void load() @@ -51,7 +49,7 @@ namespace osu.Game.Tournament.Screens.TeamWin currentCompleted.BindValueChanged(_ => update()); } - protected override void CurrentMatchChanged(ValueChangedEvent match) + protected override void CurrentMatchChanged(ValueChangedEvent match) { base.CurrentMatchChanged(match); @@ -70,7 +68,7 @@ namespace osu.Game.Tournament.Screens.TeamWin { var match = CurrentMatch.Value; - if (match.Winner == null) + if (match?.Winner == null) { mainContainer.Clear(); return; diff --git a/osu.Game.Tournament/Screens/TournamentMatchScreen.cs b/osu.Game.Tournament/Screens/TournamentMatchScreen.cs index 58444d0c1b..5a9b9d05ed 100644 --- a/osu.Game.Tournament/Screens/TournamentMatchScreen.cs +++ b/osu.Game.Tournament/Screens/TournamentMatchScreen.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; using osu.Game.Tournament.Models; @@ -10,8 +8,8 @@ namespace osu.Game.Tournament.Screens { public abstract partial class TournamentMatchScreen : TournamentScreen { - protected readonly Bindable CurrentMatch = new Bindable(); - private WarningBox noMatchWarning; + protected readonly Bindable CurrentMatch = new Bindable(); + private WarningBox? noMatchWarning; protected override void LoadComplete() { @@ -21,7 +19,7 @@ namespace osu.Game.Tournament.Screens CurrentMatch.BindValueChanged(CurrentMatchChanged, true); } - protected virtual void CurrentMatchChanged(ValueChangedEvent match) + protected virtual void CurrentMatchChanged(ValueChangedEvent match) { if (match.NewValue == null) { diff --git a/osu.Game.Tournament/TournamentGame.cs b/osu.Game.Tournament/TournamentGame.cs index c79cc9cd57..ba3b17b513 100644 --- a/osu.Game.Tournament/TournamentGame.cs +++ b/osu.Game.Tournament/TournamentGame.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Drawing; using System.Linq; using osu.Framework.Allocation; @@ -35,12 +33,12 @@ namespace osu.Game.Tournament public static readonly Color4 ELEMENT_FOREGROUND_COLOUR = Color4Extensions.FromHex("#000"); public static readonly Color4 TEXT_COLOUR = Color4Extensions.FromHex("#fff"); - private Drawable heightWarning; + private Drawable heightWarning = null!; - private Bindable windowMode; + private Bindable windowMode = null!; private readonly BindableSize windowSize = new BindableSize(); - private LoadingSpinner loadingSpinner; + private LoadingSpinner loadingSpinner = null!; [Cached(typeof(IDialogOverlay))] private readonly DialogOverlay dialogOverlay = new DialogOverlay(); diff --git a/osu.Game.Tournament/TournamentGameBase.cs b/osu.Game.Tournament/TournamentGameBase.cs index 509c8bb940..ee03b4c35d 100644 --- a/osu.Game.Tournament/TournamentGameBase.cs +++ b/osu.Game.Tournament/TournamentGameBase.cs @@ -1,14 +1,13 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.IO; using System.Linq; using System.Threading.Tasks; using Newtonsoft.Json; using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Textures; using osu.Framework.Input; @@ -31,11 +30,11 @@ namespace osu.Game.Tournament public partial class TournamentGameBase : OsuGameBase { public const string BRACKET_FILENAME = @"bracket.json"; - private LadderInfo ladder; - private TournamentStorage storage; - private DependencyContainer dependencies; - private FileBasedIPC ipc; - private BeatmapLookupCache beatmapCache; + private LadderInfo ladder = null!; + private TournamentStorage storage = null!; + private DependencyContainer dependencies = null!; + private FileBasedIPC ipc = null!; + private BeatmapLookupCache beatmapCache = null!; protected Task BracketLoadTask => bracketLoadTaskCompletionSource.Task; @@ -54,7 +53,7 @@ namespace osu.Game.Tournament return new ProductionEndpointConfiguration(); } - private TournamentSpriteText initialisationText; + private TournamentSpriteText initialisationText = null!; [BackgroundDependencyLoader] private void load(Storage baseStorage) @@ -78,6 +77,8 @@ namespace osu.Game.Tournament dependencies.CacheAs(new StableInfo(storage)); beatmapCache = dependencies.Get(); + + ladder = new LadderInfo(); } protected override void LoadComplete() @@ -100,11 +101,11 @@ namespace osu.Game.Tournament { using (Stream stream = storage.GetStream(BRACKET_FILENAME, FileAccess.Read, FileMode.Open)) using (var sr = new StreamReader(stream)) - ladder = JsonConvert.DeserializeObject(await sr.ReadToEndAsync().ConfigureAwait(false), new JsonPointConverter()); + { + ladder = JsonConvert.DeserializeObject(await sr.ReadToEndAsync().ConfigureAwait(false), new JsonPointConverter()) ?? ladder; + } } - ladder ??= new LadderInfo(); - var resolvedRuleset = ladder.Ruleset.Value != null ? RulesetStore.GetRuleset(ladder.Ruleset.Value.ShortName) : RulesetStore.AvailableRulesets.First(); @@ -283,7 +284,7 @@ namespace osu.Game.Tournament private void updateLoadProgressMessage(string s) => Schedule(() => initialisationText.Text = s); - public void PopulatePlayer(TournamentUser user, Action success = null, Action failure = null, bool immediate = false) + public void PopulatePlayer(TournamentUser user, Action? success = null, Action? failure = null, bool immediate = false) { var req = new GetUserRequest(user.OnlineID, ladder.Ruleset.Value); @@ -348,8 +349,8 @@ namespace osu.Game.Tournament foreach (var r in ladder.Rounds) r.Matches = ladder.Matches.Where(p => p.Round.Value == r).Select(p => p.ID).ToList(); - ladder.Progressions = ladder.Matches.Where(p => p.Progression.Value != null).Select(p => new TournamentProgression(p.ID, p.Progression.Value.ID)).Concat( - ladder.Matches.Where(p => p.LosersProgression.Value != null).Select(p => new TournamentProgression(p.ID, p.LosersProgression.Value.ID, true))) + ladder.Progressions = ladder.Matches.Where(p => p.Progression.Value != null).Select(p => new TournamentProgression(p.ID, p.Progression.Value.AsNonNull().ID)).Concat( + ladder.Matches.Where(p => p.LosersProgression.Value != null).Select(p => new TournamentProgression(p.ID, p.LosersProgression.Value.AsNonNull().ID, true))) .ToList(); return JsonConvert.SerializeObject(ladder, diff --git a/osu.Game.Tournament/TournamentSceneManager.cs b/osu.Game.Tournament/TournamentSceneManager.cs index 9ac5a9de12..c69b76ae29 100644 --- a/osu.Game.Tournament/TournamentSceneManager.cs +++ b/osu.Game.Tournament/TournamentSceneManager.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using osu.Framework.Allocation; @@ -35,8 +33,8 @@ namespace osu.Game.Tournament [Cached] public partial class TournamentSceneManager : CompositeDrawable { - private Container screens; - private TourneyVideo video; + private Container screens = null!; + private TourneyVideo video = null!; public const int CONTROL_AREA_WIDTH = 200; @@ -50,8 +48,8 @@ namespace osu.Game.Tournament [Cached] private TournamentMatchChatDisplay chat = new TournamentMatchChatDisplay(); - private Container chatContainer; - private FillFlowContainer buttons; + private Container chatContainer = null!; + private FillFlowContainer buttons = null!; public TournamentSceneManager() { @@ -166,10 +164,10 @@ namespace osu.Game.Tournament private float depth; - private Drawable currentScreen; - private ScheduledDelegate scheduledHide; + private Drawable? currentScreen; + private ScheduledDelegate? scheduledHide; - private Drawable temporaryScreen; + private Drawable? temporaryScreen; public void SetScreen(Drawable screen) { @@ -284,7 +282,7 @@ namespace osu.Game.Tournament Y = -2, Anchor = Anchor.Centre, Origin = Anchor.Centre, - Text = shortcutKey.ToString(), + Text = shortcutKey.Value.ToString(), } } }); @@ -304,7 +302,7 @@ namespace osu.Game.Tournament private bool isSelected; - public Action RequestSelection; + public Action? RequestSelection; public bool IsSelected { From 4c33013674a9f2ddd761d966e1c6e08e88de66a6 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sat, 29 Jul 2023 22:41:26 +0900 Subject: [PATCH 10/90] null check in test --- .../Screens/TestSceneMapPoolScreen.cs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneMapPoolScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneMapPoolScreen.cs index 2c17cd0d52..254d5c6996 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneMapPoolScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneMapPoolScreen.cs @@ -1,11 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics.Containers; using osu.Framework.Testing; using osu.Game.Tournament.Components; @@ -16,7 +15,7 @@ namespace osu.Game.Tournament.Tests.Screens { public partial class TestSceneMapPoolScreen : TournamentScreenTestScene { - private MapPoolScreen screen; + private MapPoolScreen screen = null!; [BackgroundDependencyLoader] private void load() @@ -32,7 +31,7 @@ namespace osu.Game.Tournament.Tests.Screens { AddStep("load few maps", () => { - Ladder.CurrentMatch.Value.Round.Value.Beatmaps.Clear(); + Ladder.CurrentMatch.Value.AsNonNull().Round.Value.AsNonNull().Beatmaps.Clear(); for (int i = 0; i < 8; i++) addBeatmap(); @@ -52,7 +51,7 @@ namespace osu.Game.Tournament.Tests.Screens { AddStep("load just enough maps", () => { - Ladder.CurrentMatch.Value.Round.Value.Beatmaps.Clear(); + Ladder.CurrentMatch.Value.AsNonNull().Round.Value.AsNonNull().Beatmaps.Clear(); for (int i = 0; i < 18; i++) addBeatmap(); @@ -72,7 +71,7 @@ namespace osu.Game.Tournament.Tests.Screens { AddStep("load many maps", () => { - Ladder.CurrentMatch.Value.Round.Value.Beatmaps.Clear(); + Ladder.CurrentMatch.Value.AsNonNull().Round.Value.AsNonNull().Beatmaps.Clear(); for (int i = 0; i < 19; i++) addBeatmap(); @@ -92,7 +91,7 @@ namespace osu.Game.Tournament.Tests.Screens { AddStep("load many maps", () => { - Ladder.CurrentMatch.Value.Round.Value.Beatmaps.Clear(); + Ladder.CurrentMatch.Value.AsNonNull().Round.Value.AsNonNull().Beatmaps.Clear(); for (int i = 0; i < 11; i++) addBeatmap(i > 4 ? Ruleset.Value.CreateInstance().AllMods.ElementAt(i).Acronym : "NM"); @@ -118,7 +117,7 @@ namespace osu.Game.Tournament.Tests.Screens { AddStep("load many maps", () => { - Ladder.CurrentMatch.Value.Round.Value.Beatmaps.Clear(); + Ladder.CurrentMatch.Value.AsNonNull().Round.Value.AsNonNull().Beatmaps.Clear(); for (int i = 0; i < 12; i++) addBeatmap(i > 4 ? Ruleset.Value.CreateInstance().AllMods.ElementAt(i).Acronym : "NM"); @@ -138,7 +137,7 @@ namespace osu.Game.Tournament.Tests.Screens { AddStep("load many maps", () => { - Ladder.CurrentMatch.Value.Round.Value.Beatmaps.Clear(); + Ladder.CurrentMatch.Value.AsNonNull().Round.Value.AsNonNull().Beatmaps.Clear(); for (int i = 0; i < 12; i++) addBeatmap(i > 4 ? Ruleset.Value.CreateInstance().AllMods.ElementAt(i).Acronym : "NM"); @@ -155,7 +154,7 @@ namespace osu.Game.Tournament.Tests.Screens private void addBeatmap(string mods = "NM") { - Ladder.CurrentMatch.Value.Round.Value.Beatmaps.Add(new RoundBeatmap + Ladder.CurrentMatch.Value.AsNonNull().Round.Value.AsNonNull().Beatmaps.Add(new RoundBeatmap { Beatmap = CreateSampleBeatmap(), Mods = mods From 033c9091c04377869a13185230fb4e95bf62c665 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 30 Jul 2023 01:39:31 +0900 Subject: [PATCH 11/90] use cast instead AsNonNull --- osu.Game.Tournament/Models/TournamentTeam.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tournament/Models/TournamentTeam.cs b/osu.Game.Tournament/Models/TournamentTeam.cs index 3587aa937e..b3b2f213ce 100644 --- a/osu.Game.Tournament/Models/TournamentTeam.cs +++ b/osu.Game.Tournament/Models/TournamentTeam.cs @@ -38,7 +38,7 @@ namespace osu.Game.Tournament.Models { int[] ranks = Players.Select(p => p.Rank) .Where(i => i.HasValue) - .Select(i => i.AsNonNull().Value) + .Cast() .ToArray(); if (ranks.Length == 0) From 625ed729eed3a76703fe0c1713fa9617baf5e33b Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 30 Jul 2023 01:39:56 +0900 Subject: [PATCH 12/90] debug assert `closest != null` --- .../Screens/Drawings/Components/ScrollingTeamContainer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs b/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs index 4a47de8714..7f19e8a497 100644 --- a/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs +++ b/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs @@ -136,11 +136,11 @@ namespace osu.Game.Tournament.Screens.Drawings.Components closest = stc; } - Trace.Assert(closest != null, "closest != null"); + Debug.Assert(closest != null, "closest != null"); - offset += DrawWidth / 2f - (closest.AsNonNull().Position.X + closest.AsNonNull().DrawWidth / 2f); + offset += DrawWidth / 2f - (closest.Position.X + closest.DrawWidth / 2f); - ScrollingTeam st = closest.AsNonNull(); + ScrollingTeam st = closest; availableTeams.RemoveAll(at => at == st.Team); From cb4adf115cae1dbef79f1b8af64d0d71c768b537 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 30 Jul 2023 01:40:13 +0900 Subject: [PATCH 13/90] RemoveTeam shouldn't have nullable arg --- .../Screens/Drawings/Components/ScrollingTeamContainer.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs b/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs index 7f19e8a497..d4e0f29852 100644 --- a/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs +++ b/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs @@ -188,11 +188,8 @@ namespace osu.Game.Tournament.Screens.Drawings.Components setScrollState(ScrollState.Idle); } - public void RemoveTeam(TournamentTeam? team) + public void RemoveTeam(TournamentTeam team) { - if (team == null) - return; - availableTeams.Remove(team); foreach (var c in Children) From 9482f7445614907f001aee2097939d25ad6c0b92 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 30 Jul 2023 01:49:57 +0900 Subject: [PATCH 14/90] fix nullable for TeamList --- osu.Game.Tournament/Screens/Drawings/DrawingsScreen.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tournament/Screens/Drawings/DrawingsScreen.cs b/osu.Game.Tournament/Screens/Drawings/DrawingsScreen.cs index b2dd4e8c36..fc59b486fe 100644 --- a/osu.Game.Tournament/Screens/Drawings/DrawingsScreen.cs +++ b/osu.Game.Tournament/Screens/Drawings/DrawingsScreen.cs @@ -39,7 +39,7 @@ namespace osu.Game.Tournament.Screens.Drawings private Storage storage = null!; - public ITeamList? TeamList; + public ITeamList TeamList = null!; [BackgroundDependencyLoader] private void load(Storage storage) @@ -48,7 +48,8 @@ namespace osu.Game.Tournament.Screens.Drawings RelativeSizeAxes = Axes.Both; - TeamList ??= new StorageBackedTeamList(storage); + if (TeamList.IsNull()) + TeamList = new StorageBackedTeamList(storage); if (!TeamList.Teams.Any()) { @@ -223,7 +224,7 @@ namespace osu.Game.Tournament.Screens.Drawings teamsContainer.ClearTeams(); allTeams.Clear(); - foreach (TournamentTeam t in TeamList.AsNonNull().Teams) + foreach (TournamentTeam t in TeamList.Teams) { if (groupsContainer.ContainsTeam(t.FullName.Value)) continue; From 88a1cf40052a92f70f8055fd1da33b44d575f022 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 30 Jul 2023 01:57:44 +0900 Subject: [PATCH 15/90] remove all `canBeNull` from attribute --- osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs | 2 +- osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs | 2 +- .../Screens/Ladder/Components/DrawableMatchTeam.cs | 4 ++-- .../Screens/Ladder/Components/DrawableTournamentMatch.cs | 4 ++-- osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs | 2 +- osu.Game.Tournament/Screens/Setup/SetupScreen.cs | 2 +- osu.Game.Tournament/Screens/Setup/StablePathSelectScreen.cs | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs index a82ac57ee9..4074e681f9 100644 --- a/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs @@ -36,7 +36,7 @@ namespace osu.Game.Tournament.Screens.Editors private RectangularPositionSnapGrid grid = null!; - [Resolved(canBeNull: true)] + [Resolved] private IDialogOverlay? dialogOverlay { get; set; } protected override bool DrawLoserPaths => true; diff --git a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs index 79c50e60ba..20188cc5dc 100644 --- a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs +++ b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs @@ -27,7 +27,7 @@ namespace osu.Game.Tournament.Screens.Gameplay private OsuButton warmupButton = null!; private MatchIPCInfo ipc = null!; - [Resolved(canBeNull: true)] + [Resolved] private TournamentSceneManager? sceneManager { get; set; } [Resolved] diff --git a/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs b/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs index a380ad9b49..637591c6f6 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs @@ -38,7 +38,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components private readonly Func? isWinner; private LadderEditorScreen ladderEditor = null!; - [Resolved(canBeNull: true)] + [Resolved] private LadderInfo? ladderInfo { get; set; } private void setCurrent() @@ -53,7 +53,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components ladderInfo.CurrentMatch.Value.Current.Value = true; } - [Resolved(CanBeNull = true)] + [Resolved] private LadderEditorInfo? editorInfo { get; set; } public DrawableMatchTeam(TournamentTeam? team, TournamentMatch match, bool losers) diff --git a/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs b/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs index 7b8f2e373b..4de47d7c7f 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs @@ -28,10 +28,10 @@ namespace osu.Game.Tournament.Screens.Ladder.Components private readonly Drawable currentMatchSelectionBox; private Bindable? globalSelection; - [Resolved(CanBeNull = true)] + [Resolved] private LadderEditorInfo? editorInfo { get; set; } - [Resolved(CanBeNull = true)] + [Resolved] private LadderInfo? ladderInfo { get; set; } public DrawableTournamentMatch(TournamentMatch match, bool editor = false) diff --git a/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs b/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs index 3091f4293c..cfce2694e9 100644 --- a/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs +++ b/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs @@ -24,7 +24,7 @@ namespace osu.Game.Tournament.Screens.MapPool { private FillFlowContainer> mapFlows = null!; - [Resolved(canBeNull: true)] + [Resolved] private TournamentSceneManager? sceneManager { get; set; } private TeamColour pickColour; diff --git a/osu.Game.Tournament/Screens/Setup/SetupScreen.cs b/osu.Game.Tournament/Screens/Setup/SetupScreen.cs index 1152759c2a..df1ce69c33 100644 --- a/osu.Game.Tournament/Screens/Setup/SetupScreen.cs +++ b/osu.Game.Tournament/Screens/Setup/SetupScreen.cs @@ -39,7 +39,7 @@ namespace osu.Game.Tournament.Screens.Setup [Resolved] private RulesetStore rulesets { get; set; } = null!; - [Resolved(canBeNull: true)] + [Resolved] private TournamentSceneManager? sceneManager { get; set; } private Bindable windowSize = null!; diff --git a/osu.Game.Tournament/Screens/Setup/StablePathSelectScreen.cs b/osu.Game.Tournament/Screens/Setup/StablePathSelectScreen.cs index c3d072b6a0..74404e06f8 100644 --- a/osu.Game.Tournament/Screens/Setup/StablePathSelectScreen.cs +++ b/osu.Game.Tournament/Screens/Setup/StablePathSelectScreen.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tournament.Screens.Setup { public partial class StablePathSelectScreen : TournamentScreen { - [Resolved(canBeNull: true)] + [Resolved] private TournamentSceneManager? sceneManager { get; set; } [Resolved] From 65b4ae506ee563b9a2b940c4a72b9c9d34ac5dc2 Mon Sep 17 00:00:00 2001 From: QuantumSno Date: Sat, 29 Jul 2023 13:18:47 -0400 Subject: [PATCH 16/90] Moved enum to bottom of enumeration table --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index 3d24afbb16..79f098f90e 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -286,9 +286,6 @@ namespace osu.Game.Input.Bindings [LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.ToggleInGameInterface))] ToggleInGameInterface, - [LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.ToggleInGameLeaderboard))] - ToggleInGameLeaderboard, - // Song select keybindings [LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.ToggleModSelection))] ToggleModSelection, @@ -382,5 +379,9 @@ namespace osu.Game.Input.Bindings [LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.ToggleReplaySettings))] ToggleReplaySettings, + + // Editor (cont) + [LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.ToggleInGameLeaderboard))] + ToggleInGameLeaderboard, } } From 9d928c0225d3b86257f1cf8cd71a606c46038892 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 29 Jul 2023 10:39:50 -0700 Subject: [PATCH 17/90] Apply NRT to `BreakInfoLine` --- osu.Game/Screens/Play/Break/BreakInfoLine.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/Break/BreakInfoLine.cs b/osu.Game/Screens/Play/Break/BreakInfoLine.cs index b8696352e8..c6a0ca0ef6 100644 --- a/osu.Game/Screens/Play/Break/BreakInfoLine.cs +++ b/osu.Game/Screens/Play/Break/BreakInfoLine.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -71,7 +69,7 @@ namespace osu.Game.Screens.Play.Break if (count is Enum countEnum) return countEnum.GetDescription(); - return count.ToString(); + return count.ToString() ?? string.Empty; } [BackgroundDependencyLoader] From 740898dffb910d5d6e8306c746e9578b383b47d0 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 29 Jul 2023 10:40:18 -0700 Subject: [PATCH 18/90] Remove unnecessary prefix parameter --- osu.Game/Screens/Play/Break/BreakInfoLine.cs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Play/Break/BreakInfoLine.cs b/osu.Game/Screens/Play/Break/BreakInfoLine.cs index c6a0ca0ef6..cfdf6cc651 100644 --- a/osu.Game/Screens/Play/Break/BreakInfoLine.cs +++ b/osu.Game/Screens/Play/Break/BreakInfoLine.cs @@ -24,12 +24,8 @@ namespace osu.Game.Screens.Play.Break private readonly OsuSpriteText text; private readonly OsuSpriteText valueText; - private readonly string prefix; - - public BreakInfoLine(LocalisableString name, string prefix = @"") + public BreakInfoLine(LocalisableString name) { - this.prefix = prefix; - AutoSizeAxes = Axes.Y; Children = new Drawable[] { @@ -45,7 +41,7 @@ namespace osu.Game.Screens.Play.Break { Anchor = Anchor.Centre, Origin = Anchor.CentreLeft, - Text = prefix + @"-", + Text = @"-", Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 17), Margin = new MarginPadding { Left = margin } } @@ -56,7 +52,7 @@ namespace osu.Game.Screens.Play.Break private void currentValueChanged(ValueChangedEvent e) { - LocalisableString newText = LocalisableString.Interpolate($"{prefix}{Format(e.NewValue)}"); + LocalisableString newText = Format(e.NewValue); if (valueText.Text == newText) return; @@ -82,8 +78,8 @@ namespace osu.Game.Screens.Play.Break public partial class PercentageBreakInfoLine : BreakInfoLine { - public PercentageBreakInfoLine(LocalisableString name, string prefix = "") - : base(name, prefix) + public PercentageBreakInfoLine(LocalisableString name) + : base(name) { } From 6ad8339c6674300806378693d79cc9f12285e71a Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 30 Jul 2023 02:30:11 +0900 Subject: [PATCH 19/90] use no null when true --- osu.Game.Tournament/IPC/FileBasedIPC.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tournament/IPC/FileBasedIPC.cs b/osu.Game.Tournament/IPC/FileBasedIPC.cs index 333dd0fd73..daf1417f6f 100644 --- a/osu.Game.Tournament/IPC/FileBasedIPC.cs +++ b/osu.Game.Tournament/IPC/FileBasedIPC.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using Microsoft.Win32; @@ -180,7 +181,7 @@ namespace osu.Game.Tournament.IPC /// Whether an IPC directory was successfully auto-detected. public bool AutoDetectIPCLocation() => SetIPCLocation(findStablePath()); - private static bool ipcFileExistsInDirectory(string? p) => p != null && File.Exists(Path.Combine(p, "ipc.txt")); + private static bool ipcFileExistsInDirectory([NotNullWhen(true)] string? p) => p != null && File.Exists(Path.Combine(p, "ipc.txt")); private string? findStablePath() { @@ -201,7 +202,7 @@ namespace osu.Game.Tournament.IPC string? stableInstallPath = Environment.GetEnvironmentVariable("OSU_STABLE_PATH"); if (ipcFileExistsInDirectory(stableInstallPath)) - return stableInstallPath!; + return stableInstallPath; } catch { From a1f0e5978448040c646e0252ffc7fdf4077beb17 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 30 Jul 2023 02:30:51 +0900 Subject: [PATCH 20/90] remove null check for b.Beatmap --- osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs b/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs index cfce2694e9..9caa87d75e 100644 --- a/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs +++ b/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs @@ -252,9 +252,6 @@ namespace osu.Game.Tournament.Screens.MapPool foreach (var b in CurrentMatch.Value.Round.Value.Beatmaps) { - if (b.Beatmap == null) - continue; - if (currentFlow == null || (LadderInfo.SplitMapPoolByMods.Value && currentMods != b.Mods)) { mapFlows.Add(currentFlow = new FillFlowContainer From bc2ca11bb0497b81c0a891a34aac645089828e02 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 30 Jul 2023 02:31:05 +0900 Subject: [PATCH 21/90] move to initialiser --- osu.Game.Tournament/TournamentGameBase.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game.Tournament/TournamentGameBase.cs b/osu.Game.Tournament/TournamentGameBase.cs index ee03b4c35d..eecd097a97 100644 --- a/osu.Game.Tournament/TournamentGameBase.cs +++ b/osu.Game.Tournament/TournamentGameBase.cs @@ -30,7 +30,7 @@ namespace osu.Game.Tournament public partial class TournamentGameBase : OsuGameBase { public const string BRACKET_FILENAME = @"bracket.json"; - private LadderInfo ladder = null!; + private LadderInfo ladder = new LadderInfo(); private TournamentStorage storage = null!; private DependencyContainer dependencies = null!; private FileBasedIPC ipc = null!; @@ -77,8 +77,6 @@ namespace osu.Game.Tournament dependencies.CacheAs(new StableInfo(storage)); beatmapCache = dependencies.Get(); - - ladder = new LadderInfo(); } protected override void LoadComplete() From 059012130924902e36d3e8311d23e4381b7d07eb Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 30 Jul 2023 02:38:19 +0900 Subject: [PATCH 22/90] string mod should not null Already assigned in the constructor --- osu.Game.Tournament/Components/TournamentBeatmapPanel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs index 2d5844d02b..0f916d931d 100644 --- a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs +++ b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs @@ -22,7 +22,7 @@ namespace osu.Game.Tournament.Components { public readonly TournamentBeatmap? Beatmap; - private readonly string? mod; + private readonly string mod; public const float HEIGHT = 50; From ba80d1e2d5e766a5791b047fcad736adb4f54340 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 30 Jul 2023 02:49:13 +0900 Subject: [PATCH 23/90] remove nullable for Box --- osu.Game.Tournament/Components/TournamentBeatmapPanel.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs index 0f916d931d..ba922c7c7b 100644 --- a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs +++ b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs @@ -28,7 +28,7 @@ namespace osu.Game.Tournament.Components private readonly Bindable currentMatch = new Bindable(); - private Box? flash; + private Box flash = null!; public TournamentBeatmapPanel(TournamentBeatmap? beatmap, string mod = "") { @@ -135,11 +135,12 @@ namespace osu.Game.Tournament.Components match.OldValue.PicksBans.CollectionChanged -= picksBansOnCollectionChanged; if (match.NewValue != null) match.NewValue.PicksBans.CollectionChanged += picksBansOnCollectionChanged; - updateState(); + + Scheduler.AddOnce(updateState); } private void picksBansOnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) - => updateState(); + => Scheduler.AddOnce(updateState); private BeatmapChoice? choice; @@ -157,7 +158,7 @@ namespace osu.Game.Tournament.Components if (newChoice != null) { if (shouldFlash) - flash?.FadeOutFromOne(500).Loop(0, 10); + flash.FadeOutFromOne(500).Loop(0, 10); BorderThickness = 6; From 5d09eca1041e10119738707c608340a3d8ddf861 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 30 Jul 2023 02:49:30 +0900 Subject: [PATCH 24/90] revert test change --- osu.Game.Tournament.Tests/Screens/TestSceneTeamIntroScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneTeamIntroScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneTeamIntroScreen.cs index d6941848b7..b76e0d7521 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneTeamIntroScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneTeamIntroScreen.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tournament.Tests.Screens { Team1 = { Value = Ladder.Teams.FirstOrDefault(t => t.Acronym.Value == "USA") }, Team2 = { Value = Ladder.Teams.FirstOrDefault(t => t.Acronym.Value == "JPN") }, - Round = { Value = Ladder.Rounds.First(g => g.Name.Value == "Quarterfinals") } + Round = { Value = Ladder.Rounds.FirstOrDefault(g => g.Name.Value == "Finals") } }; Add(new TeamIntroScreen From 99dd156d5322ab17a542b855796323fadd981e36 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 30 Jul 2023 02:50:16 +0900 Subject: [PATCH 25/90] remove useless using --- osu.Game.Tournament/Models/TournamentTeam.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tournament/Models/TournamentTeam.cs b/osu.Game.Tournament/Models/TournamentTeam.cs index b3b2f213ce..3cd527aaaa 100644 --- a/osu.Game.Tournament/Models/TournamentTeam.cs +++ b/osu.Game.Tournament/Models/TournamentTeam.cs @@ -5,7 +5,6 @@ using System; using System.Linq; using Newtonsoft.Json; using osu.Framework.Bindables; -using osu.Framework.Extensions.ObjectExtensions; namespace osu.Game.Tournament.Models { From 404a927caf55f05be24d1eadf0f3bda06227d92e Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 30 Jul 2023 02:56:52 +0900 Subject: [PATCH 26/90] fix Possible NullReferenceException in test --- .../Components/TestSceneTournamentModDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tournament.Tests/Components/TestSceneTournamentModDisplay.cs b/osu.Game.Tournament.Tests/Components/TestSceneTournamentModDisplay.cs index cea4306ff8..0cb95c2e43 100644 --- a/osu.Game.Tournament.Tests/Components/TestSceneTournamentModDisplay.cs +++ b/osu.Game.Tournament.Tests/Components/TestSceneTournamentModDisplay.cs @@ -45,7 +45,7 @@ namespace osu.Game.Tournament.Tests.Components private void success(APIBeatmap beatmap) { - var ruleset = rulesets.GetRuleset(Ladder.Ruleset.Value.OnlineID); + var ruleset = rulesets.GetRuleset(Ladder.Ruleset.Value?.OnlineID ?? -1); if (ruleset == null) return; From 6ebfafa9c3b1f24cc89ec72a577e70a799b052d1 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 29 Jul 2023 11:02:04 -0700 Subject: [PATCH 27/90] Remove unnecessary text comparison --- osu.Game/Screens/Play/Break/BreakInfoLine.cs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/osu.Game/Screens/Play/Break/BreakInfoLine.cs b/osu.Game/Screens/Play/Break/BreakInfoLine.cs index cfdf6cc651..3357963fac 100644 --- a/osu.Game/Screens/Play/Break/BreakInfoLine.cs +++ b/osu.Game/Screens/Play/Break/BreakInfoLine.cs @@ -47,17 +47,7 @@ namespace osu.Game.Screens.Play.Break } }; - Current.ValueChanged += currentValueChanged; - } - - private void currentValueChanged(ValueChangedEvent e) - { - LocalisableString newText = Format(e.NewValue); - - if (valueText.Text == newText) - return; - - valueText.Text = newText; + Current.ValueChanged += text => valueText.Text = Format(text.NewValue); } protected virtual LocalisableString Format(T count) From 4ddf05602f1f117f8ab0248c937a2487e76f59a3 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 29 Jul 2023 11:05:15 -0700 Subject: [PATCH 28/90] Update `BreakInfoLine` to formatting standards --- osu.Game/Screens/Play/Break/BreakInfoLine.cs | 34 ++++++++++++-------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/osu.Game/Screens/Play/Break/BreakInfoLine.cs b/osu.Game/Screens/Play/Break/BreakInfoLine.cs index 3357963fac..147650ca07 100644 --- a/osu.Game/Screens/Play/Break/BreakInfoLine.cs +++ b/osu.Game/Screens/Play/Break/BreakInfoLine.cs @@ -21,21 +21,30 @@ namespace osu.Game.Screens.Play.Break public Bindable Current = new Bindable(); - private readonly OsuSpriteText text; - private readonly OsuSpriteText valueText; + private readonly LocalisableString name; + + private OsuSpriteText valueText = null!; public BreakInfoLine(LocalisableString name) { + this.name = name; + AutoSizeAxes = Axes.Y; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { Children = new Drawable[] { - text = new OsuSpriteText + new OsuSpriteText { Anchor = Anchor.Centre, Origin = Anchor.CentreRight, Text = name, Font = OsuFont.GetFont(size: 17), - Margin = new MarginPadding { Right = margin } + Margin = new MarginPadding { Right = margin }, + Colour = colours.Yellow, }, valueText = new OsuSpriteText { @@ -43,11 +52,17 @@ namespace osu.Game.Screens.Play.Break Origin = Anchor.CentreLeft, Text = @"-", Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 17), - Margin = new MarginPadding { Left = margin } + Margin = new MarginPadding { Left = margin }, + Colour = colours.YellowLight, } }; + } - Current.ValueChanged += text => valueText.Text = Format(text.NewValue); + protected override void LoadComplete() + { + base.LoadComplete(); + + Current.BindValueChanged(text => valueText.Text = Format(text.NewValue), true); } protected virtual LocalisableString Format(T count) @@ -57,13 +72,6 @@ namespace osu.Game.Screens.Play.Break return count.ToString() ?? string.Empty; } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - text.Colour = colours.Yellow; - valueText.Colour = colours.YellowLight; - } } public partial class PercentageBreakInfoLine : BreakInfoLine From 72005bef7c037977b084f8c5b8eb60a516610573 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Jul 2023 15:10:58 +0900 Subject: [PATCH 29/90] Fix skin editor crashing if the same component is provided twice --- osu.Game/Overlays/SkinEditor/SkinEditor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/SkinEditor/SkinEditor.cs b/osu.Game/Overlays/SkinEditor/SkinEditor.cs index 2b23ce290f..8179d58ddf 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditor.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditor.cs @@ -356,7 +356,7 @@ namespace osu.Game.Overlays.SkinEditor { new SettingsDropdown { - Items = availableTargets.Select(t => t.Lookup), + Items = availableTargets.Select(t => t.Lookup).Distinct(), Current = selectedTarget, } } From d78cc6085194de5f321f8a22354f7d9ddc73696b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Aug 2023 07:12:40 +0900 Subject: [PATCH 30/90] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 7f15d9fafd..651e5b1fe6 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -10,7 +10,7 @@ true - +