Migrate mod preset column to use realm

This commit is contained in:
Bartłomiej Dach
2022-07-23 18:01:11 +02:00
parent cbabc4886c
commit 345f103119
5 changed files with 99 additions and 34 deletions

View File

@ -5,10 +5,14 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.Mods; using osu.Game.Overlays.Mods;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mania.Mods;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Osu.Mods;
@ -16,29 +20,54 @@ namespace osu.Game.Tests.Visual.UserInterface
{ {
public class TestSceneModPresetColumn : OsuTestScene public class TestSceneModPresetColumn : OsuTestScene
{ {
protected override bool UseFreshStoragePerRun => true;
[Resolved]
private RulesetStore rulesets { get; set; } = null!;
[Cached] [Cached]
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); 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<ModPreset>();
realm.Add(createTestPresets());
});
});
}
[Test] [Test]
public void TestBasicAppearance() public void TestBasicAppearance()
{ {
ModPresetColumn modPresetColumn = null!; AddStep("set osu! ruleset", () => Ruleset.Value = rulesets.GetRuleset(0));
AddStep("create content", () => Child = new Container AddStep("create content", () => Child = new Container
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding(30), Padding = new MarginPadding(30),
Child = modPresetColumn = new ModPresetColumn Child = new ModPresetColumn
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
Presets = createTestPresets().ToArray()
} }
}); });
AddStep("change presets", () => modPresetColumn.Presets = createTestPresets().Skip(1).ToArray()); AddUntilStep("3 panels visible", () => this.ChildrenOfType<ModPresetPanel>().Count() == 3);
AddStep("change ruleset to mania", () => Ruleset.Value = rulesets.GetRuleset(3));
AddUntilStep("1 panel visible", () => this.ChildrenOfType<ModPresetPanel>().Count() == 1);
} }
private static IEnumerable<ModPreset> createTestPresets() => new[] private IEnumerable<ModPreset> createTestPresets() => new[]
{ {
new ModPreset new ModPreset
{ {
@ -48,7 +77,8 @@ namespace osu.Game.Tests.Visual.UserInterface
{ {
new OsuModHardRock(), new OsuModHardRock(),
new OsuModDoubleTime() new OsuModDoubleTime()
} },
Ruleset = rulesets.GetRuleset(0).AsNonNull()
}, },
new ModPreset new ModPreset
{ {
@ -60,7 +90,8 @@ namespace osu.Game.Tests.Visual.UserInterface
{ {
ApproachRate = { Value = 0 } ApproachRate = { Value = 0 }
} }
} },
Ruleset = rulesets.GetRuleset(0).AsNonNull()
}, },
new ModPreset new ModPreset
{ {
@ -70,7 +101,19 @@ namespace osu.Game.Tests.Visual.UserInterface
{ {
new OsuModFlashlight(), new OsuModFlashlight(),
new OsuModSpinIn() 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()
} }
}; };
} }

View File

@ -7,6 +7,7 @@ using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Database;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.Mods; using osu.Game.Overlays.Mods;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
@ -31,7 +32,7 @@ namespace osu.Game.Tests.Visual.UserInterface
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
Spacing = new Vector2(0, 5), Spacing = new Vector2(0, 5),
ChildrenEnumerable = createTestPresets().Select(preset => new ModPresetPanel(preset)) ChildrenEnumerable = createTestPresets().Select(preset => new ModPresetPanel(preset.ToLiveUnmanaged()))
}); });
} }

View File

@ -66,8 +66,9 @@ namespace osu.Game.Database
/// 19 2022-07-19 Added DateSubmitted and DateRanked to BeatmapSetInfo. /// 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. /// 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). /// 21 2022-07-27 Migrate collections to realm (BeatmapCollection).
/// 22 2022-07-31 Added ModPreset.
/// </summary> /// </summary>
private const int schema_version = 21; private const int schema_version = 22;
/// <summary> /// <summary>
/// Lock object which is held during <see cref="BlockAllOperations"/> sections, blocking realm retrieval during blocking periods. /// Lock object which is held during <see cref="BlockAllOperations"/> sections, blocking realm retrieval during blocking periods.

View File

@ -7,31 +7,24 @@ using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Game.Database;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Localisation; using osu.Game.Localisation;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osuTK; using osuTK;
using Realms;
namespace osu.Game.Overlays.Mods namespace osu.Game.Overlays.Mods
{ {
public class ModPresetColumn : ModSelectColumn public class ModPresetColumn : ModSelectColumn
{ {
private IReadOnlyList<ModPreset> presets = Array.Empty<ModPreset>(); [Resolved]
private RealmAccess realm { get; set; } = null!;
/// <summary> [Resolved]
/// Sets the collection of available mod presets. private IBindable<RulesetInfo> ruleset { get; set; } = null!;
/// </summary>
public IReadOnlyList<ModPreset> Presets
{
get => presets;
set
{
presets = value;
if (IsLoaded)
asyncLoadPanels();
}
}
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours)
@ -44,7 +37,20 @@ namespace osu.Game.Overlays.Mods
{ {
base.LoadComplete(); base.LoadComplete();
asyncLoadPanels(); ruleset.BindValueChanged(_ => rulesetChanged(), true);
}
private IDisposable? presetSubscription;
private void rulesetChanged()
{
presetSubscription?.Dispose();
presetSubscription = realm.RegisterForNotifications(r =>
r.All<ModPreset>()
.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; private CancellationTokenSource? cancellationTokenSource;
@ -52,11 +58,17 @@ namespace osu.Game.Overlays.Mods
private Task? latestLoadTask; private Task? latestLoadTask;
internal bool ItemsLoaded => latestLoadTask == null; internal bool ItemsLoaded => latestLoadTask == null;
private void asyncLoadPanels() private void asyncLoadPanels(IReadOnlyList<ModPreset> presets)
{ {
cancellationTokenSource?.Cancel(); 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 Shear = Vector2.Zero
}); });
@ -73,5 +85,12 @@ namespace osu.Game.Overlays.Mods
latestLoadTask = null; latestLoadTask = null;
}); });
} }
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
presetSubscription?.Dispose();
}
} }
} }

View File

@ -4,6 +4,7 @@
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Cursor;
using osu.Game.Database;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
@ -11,16 +12,16 @@ namespace osu.Game.Overlays.Mods
{ {
public class ModPresetPanel : ModSelectPanel, IHasCustomTooltip<ModPreset> public class ModPresetPanel : ModSelectPanel, IHasCustomTooltip<ModPreset>
{ {
public readonly ModPreset Preset; public readonly Live<ModPreset> Preset;
public override BindableBool Active { get; } = new BindableBool(); public override BindableBool Active { get; } = new BindableBool();
public ModPresetPanel(ModPreset preset) public ModPresetPanel(Live<ModPreset> preset)
{ {
Preset = preset; Preset = preset;
Title = preset.Name; Title = preset.Value.Name;
Description = preset.Description; Description = preset.Value.Description;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -29,7 +30,7 @@ namespace osu.Game.Overlays.Mods
AccentColour = colours.Orange1; AccentColour = colours.Orange1;
} }
public ModPreset TooltipContent => Preset; public ModPreset TooltipContent => Preset.Value;
public ITooltip<ModPreset> GetCustomTooltip() => new ModPresetTooltip(ColourProvider); public ITooltip<ModPreset> GetCustomTooltip() => new ModPresetTooltip(ColourProvider);
} }
} }