From 345f10311935da5f49e7f230acb82e3348af8fc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 23 Jul 2022 18:01:11 +0200 Subject: [PATCH] Migrate mod preset column to use realm --- .../UserInterface/TestSceneModPresetColumn.cs | 61 ++++++++++++++++--- .../UserInterface/TestSceneModPresetPanel.cs | 3 +- osu.Game/Database/RealmAccess.cs | 3 +- osu.Game/Overlays/Mods/ModPresetColumn.cs | 55 +++++++++++------ osu.Game/Overlays/Mods/ModPresetPanel.cs | 11 ++-- 5 files changed, 99 insertions(+), 34 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs index f6209e1b42..f86072dbc0 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs @@ -5,10 +5,14 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; using osu.Game.Overlays; using osu.Game.Overlays.Mods; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Mania.Mods; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; @@ -16,29 +20,54 @@ namespace osu.Game.Tests.Visual.UserInterface { public class TestSceneModPresetColumn : OsuTestScene { + protected override bool UseFreshStoragePerRun => true; + + [Resolved] + private RulesetStore rulesets { get; set; } = null!; + [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); + [BackgroundDependencyLoader] + private void load() + { + Dependencies.Cache(Realm); + } + + [SetUpSteps] + public void SetUpSteps() + { + AddStep("reset storage", () => + { + Realm.Write(realm => + { + realm.RemoveAll(); + realm.Add(createTestPresets()); + }); + }); + } + [Test] public void TestBasicAppearance() { - ModPresetColumn modPresetColumn = null!; - + AddStep("set osu! ruleset", () => Ruleset.Value = rulesets.GetRuleset(0)); AddStep("create content", () => Child = new Container { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding(30), - Child = modPresetColumn = new ModPresetColumn + Child = new ModPresetColumn { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Presets = createTestPresets().ToArray() } }); - AddStep("change presets", () => modPresetColumn.Presets = createTestPresets().Skip(1).ToArray()); + AddUntilStep("3 panels visible", () => this.ChildrenOfType().Count() == 3); + + AddStep("change ruleset to mania", () => Ruleset.Value = rulesets.GetRuleset(3)); + AddUntilStep("1 panel visible", () => this.ChildrenOfType().Count() == 1); } - private static IEnumerable createTestPresets() => new[] + private IEnumerable createTestPresets() => new[] { new ModPreset { @@ -48,7 +77,8 @@ namespace osu.Game.Tests.Visual.UserInterface { new OsuModHardRock(), new OsuModDoubleTime() - } + }, + Ruleset = rulesets.GetRuleset(0).AsNonNull() }, new ModPreset { @@ -60,7 +90,8 @@ namespace osu.Game.Tests.Visual.UserInterface { ApproachRate = { Value = 0 } } - } + }, + Ruleset = rulesets.GetRuleset(0).AsNonNull() }, new ModPreset { @@ -70,7 +101,19 @@ namespace osu.Game.Tests.Visual.UserInterface { new OsuModFlashlight(), new OsuModSpinIn() - } + }, + Ruleset = rulesets.GetRuleset(0).AsNonNull() + }, + new ModPreset + { + Name = "Different ruleset", + Description = "Just to shake things up", + Mods = new Mod[] + { + new ManiaModKey4(), + new ManiaModFadeIn() + }, + Ruleset = rulesets.GetRuleset(3).AsNonNull() } }; } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetPanel.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetPanel.cs index 62e63d47bc..dd3c7000a2 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetPanel.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetPanel.cs @@ -7,6 +7,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Database; using osu.Game.Overlays; using osu.Game.Overlays.Mods; using osu.Game.Rulesets.Mods; @@ -31,7 +32,7 @@ namespace osu.Game.Tests.Visual.UserInterface Anchor = Anchor.Centre, Origin = Anchor.Centre, Spacing = new Vector2(0, 5), - ChildrenEnumerable = createTestPresets().Select(preset => new ModPresetPanel(preset)) + ChildrenEnumerable = createTestPresets().Select(preset => new ModPresetPanel(preset.ToLiveUnmanaged())) }); } diff --git a/osu.Game/Database/RealmAccess.cs b/osu.Game/Database/RealmAccess.cs index 1a0c03af7d..5f0ec67c71 100644 --- a/osu.Game/Database/RealmAccess.cs +++ b/osu.Game/Database/RealmAccess.cs @@ -66,8 +66,9 @@ namespace osu.Game.Database /// 19 2022-07-19 Added DateSubmitted and DateRanked to BeatmapSetInfo. /// 20 2022-07-21 Added LastAppliedDifficultyVersion to RulesetInfo, changed default value of BeatmapInfo.StarRating to -1. /// 21 2022-07-27 Migrate collections to realm (BeatmapCollection). + /// 22 2022-07-31 Added ModPreset. /// - private const int schema_version = 21; + private const int schema_version = 22; /// /// Lock object which is held during sections, blocking realm retrieval during blocking periods. diff --git a/osu.Game/Overlays/Mods/ModPresetColumn.cs b/osu.Game/Overlays/Mods/ModPresetColumn.cs index 1eea8383f8..bed4cff0ea 100644 --- a/osu.Game/Overlays/Mods/ModPresetColumn.cs +++ b/osu.Game/Overlays/Mods/ModPresetColumn.cs @@ -7,31 +7,24 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Localisation; +using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osuTK; +using Realms; namespace osu.Game.Overlays.Mods { public class ModPresetColumn : ModSelectColumn { - private IReadOnlyList presets = Array.Empty(); + [Resolved] + private RealmAccess realm { get; set; } = null!; - /// - /// Sets the collection of available mod presets. - /// - public IReadOnlyList Presets - { - get => presets; - set - { - presets = value; - - if (IsLoaded) - asyncLoadPanels(); - } - } + [Resolved] + private IBindable ruleset { get; set; } = null!; [BackgroundDependencyLoader] private void load(OsuColour colours) @@ -44,7 +37,20 @@ namespace osu.Game.Overlays.Mods { base.LoadComplete(); - asyncLoadPanels(); + ruleset.BindValueChanged(_ => rulesetChanged(), true); + } + + private IDisposable? presetSubscription; + + private void rulesetChanged() + { + presetSubscription?.Dispose(); + presetSubscription = realm.RegisterForNotifications(r => + r.All() + .Filter($"{nameof(ModPreset.Ruleset)}.{nameof(RulesetInfo.ShortName)} == $0" + + $" && {nameof(ModPreset.DeletePending)} == false", ruleset.Value.ShortName) + .OrderBy(preset => preset.Name), + (presets, _, _) => asyncLoadPanels(presets)); } private CancellationTokenSource? cancellationTokenSource; @@ -52,11 +58,17 @@ namespace osu.Game.Overlays.Mods private Task? latestLoadTask; internal bool ItemsLoaded => latestLoadTask == null; - private void asyncLoadPanels() + private void asyncLoadPanels(IReadOnlyList presets) { cancellationTokenSource?.Cancel(); - var panels = presets.Select(preset => new ModPresetPanel(preset) + if (!presets.Any()) + { + ItemsFlow.Clear(); + return; + } + + var panels = presets.Select(preset => new ModPresetPanel(preset.ToLive(realm)) { Shear = Vector2.Zero }); @@ -73,5 +85,12 @@ namespace osu.Game.Overlays.Mods latestLoadTask = null; }); } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + presetSubscription?.Dispose(); + } } } diff --git a/osu.Game/Overlays/Mods/ModPresetPanel.cs b/osu.Game/Overlays/Mods/ModPresetPanel.cs index 47e2f25538..a00729d9fd 100644 --- a/osu.Game/Overlays/Mods/ModPresetPanel.cs +++ b/osu.Game/Overlays/Mods/ModPresetPanel.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Cursor; +using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Rulesets.Mods; @@ -11,16 +12,16 @@ namespace osu.Game.Overlays.Mods { public class ModPresetPanel : ModSelectPanel, IHasCustomTooltip { - public readonly ModPreset Preset; + public readonly Live Preset; public override BindableBool Active { get; } = new BindableBool(); - public ModPresetPanel(ModPreset preset) + public ModPresetPanel(Live preset) { Preset = preset; - Title = preset.Name; - Description = preset.Description; + Title = preset.Value.Name; + Description = preset.Value.Description; } [BackgroundDependencyLoader] @@ -29,7 +30,7 @@ namespace osu.Game.Overlays.Mods AccentColour = colours.Orange1; } - public ModPreset TooltipContent => Preset; + public ModPreset TooltipContent => Preset.Value; public ITooltip GetCustomTooltip() => new ModPresetTooltip(ColourProvider); } }