1
0
mirror of https://github.com/ppy/osu.git synced 2026-06-01 18:09:58 +08:00

Merge branch 'ppy:master' into rotate

This commit is contained in:
dnfd1
2025-10-09 08:52:21 -07:00
committed by GitHub
Unverified
34 changed files with 354 additions and 41 deletions
+7 -7
View File
@@ -24,7 +24,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealm((realm, storage) =>
{
var rulesets = new RealmRulesetStore(realm, storage);
using var rulesets = new RealmRulesetStore(realm, storage);
Assert.AreEqual(4, rulesets.AvailableRulesets.Count());
Assert.AreEqual(4, realm.Realm.All<RulesetInfo>().Count());
@@ -36,8 +36,8 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealm((realm, storage) =>
{
var rulesets = new RealmRulesetStore(realm, storage);
var rulesets2 = new RealmRulesetStore(realm, storage);
using var rulesets = new RealmRulesetStore(realm, storage);
using var rulesets2 = new RealmRulesetStore(realm, storage);
Assert.AreEqual(4, rulesets.AvailableRulesets.Count());
Assert.AreEqual(4, rulesets2.AvailableRulesets.Count());
@@ -52,7 +52,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealm((realm, storage) =>
{
var rulesets = new RealmRulesetStore(realm, storage);
using var rulesets = new RealmRulesetStore(realm, storage);
Assert.IsFalse(rulesets.AvailableRulesets.First().IsManaged);
Assert.IsFalse(rulesets.GetRuleset(0)?.IsManaged);
@@ -79,7 +79,7 @@ namespace osu.Game.Tests.Database
Assert.That(realm.Run(r => r.Find<RulesetInfo>(rulesetShortName)!.Available), Is.True);
// Availability is updated on construction of a RealmRulesetStore
_ = new RealmRulesetStore(realm, storage);
using var _ = new RealmRulesetStore(realm, storage);
Assert.That(realm.Run(r => r.Find<RulesetInfo>(rulesetShortName)!.Available), Is.False);
});
@@ -104,13 +104,13 @@ namespace osu.Game.Tests.Database
Assert.That(realm.Run(r => r.Find<RulesetInfo>(rulesetShortName)!.Available), Is.True);
// Availability is updated on construction of a RealmRulesetStore
_ = new RealmRulesetStore(realm, storage);
using var _ = new RealmRulesetStore(realm, storage);
Assert.That(realm.Run(r => r.Find<RulesetInfo>(rulesetShortName)!.Available), Is.False);
// Simulate the ruleset getting updated
LoadTestRuleset.Version = Ruleset.CURRENT_RULESET_API_VERSION;
_ = new RealmRulesetStore(realm, storage);
using var __ = new RealmRulesetStore(realm, storage);
Assert.That(realm.Run(r => r.Find<RulesetInfo>(rulesetShortName)!.Available), Is.True);
});
@@ -257,6 +257,14 @@ namespace osu.Game.Tests.Visual.Gameplay
AddUntilStep("score in database", () => Realm.Run(r => r.Find<ScoreInfo>(Player.Score.ScoreInfo.ID) != null));
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
private class CustomRuleset : OsuRuleset, ILegacyRuleset
{
public override string Description => "custom";
@@ -6,6 +6,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Platform;
using osu.Framework.Screens;
using osu.Framework.Testing;
@@ -36,6 +37,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
private BeatmapManager beatmaps = null!;
private BeatmapSetInfo importedSet = null!;
private RulesetStore rulesets = null!;
private TestMultiplayerComponents multiplayerComponents = null!;
@@ -46,7 +48,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
BeatmapStore beatmapStore;
Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
Dependencies.CacheAs(beatmapStore = new RealmDetachedBeatmapStore());
Dependencies.Cache(Realm);
@@ -115,5 +117,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddUntilStep("wait for player", () => multiplayerComponents.CurrentScreen is Player player && player.IsLoaded);
AddStep("exit player", () => multiplayerComponents.MultiplayerScreen.MakeCurrent());
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
}
}
@@ -8,6 +8,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
@@ -37,13 +38,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestSceneDrawableRoomPlaylist : MultiplayerTestScene
{
private RulesetStore rulesets = null!;
private TestPlaylist playlist = null!;
private BeatmapManager manager = null!;
[BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio)
{
Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm);
}
@@ -436,6 +438,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddUntilStep("wait for items to load", () => playlist.ItemMap.Values.All(i => i.IsLoaded));
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
private partial class TestPlaylist : DrawableRoomPlaylist
{
public new IReadOnlyDictionary<PlaylistItem, RearrangeableListItem<PlaylistItem>> ItemMap => base.ItemMap;
@@ -51,6 +51,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestSceneMultiplayer : ScreenTestScene
{
private RulesetStore rulesets = null!;
private BeatmapManager beatmaps = null!;
private BeatmapSetInfo importedSet = null!;
private BeatmapSetInfo importedSet2 = null!;
@@ -67,7 +68,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
BeatmapStore beatmapStore;
Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, API, audio, Resources, host, Beatmap.Default));
Dependencies.CacheAs(beatmapStore = new RealmDetachedBeatmapStore());
Dependencies.Cache(Realm);
@@ -1247,5 +1248,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddUntilStep("wait for join", () => multiplayerClient.RoomJoined);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
}
}
@@ -8,6 +8,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Extensions.TypeExtensions;
using osu.Framework.Platform;
using osu.Framework.Screens;
@@ -170,6 +171,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
.All(b => b.Mod.GetType() != type));
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
private partial class TestMultiplayerMatchSongSelect : MultiplayerMatchSongSelect
{
public new Bindable<IReadOnlyList<Mod>> Mods => base.Mods;
@@ -7,6 +7,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Platform;
@@ -44,6 +45,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
public partial class TestSceneMultiplayerMatchSubScreen : MultiplayerTestScene
{
private MultiplayerMatchSubScreen screen = null!;
private RulesetStore rulesets = null!;
private BeatmapManager beatmaps = null!;
private BeatmapSetInfo importedSet = null!;
private Room room = null!;
@@ -51,7 +53,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio)
{
Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm);
Dependencies.CacheAs<BeatmapStore>(new RealmDetachedBeatmapStore());
@@ -462,6 +464,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddAssert("settings still open", () => this.ChildrenOfType<MultiplayerMatchSettingsOverlay>().Single().State.Value, () => Is.EqualTo(Visibility.Visible));
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
private partial class TestMultiplayerMatchSubScreen : MultiplayerMatchSubScreen
{
[Resolved(canBeNull: true)]
@@ -7,6 +7,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Platform;
using osu.Framework.Testing;
@@ -28,6 +29,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
public partial class TestSceneMultiplayerPlaylist : MultiplayerTestScene
{
private MultiplayerPlaylist list = null!;
private RulesetStore rulesets = null!;
private BeatmapManager beatmaps = null!;
private BeatmapSetInfo importedSet = null!;
private BeatmapInfo importedBeatmap = null!;
@@ -35,7 +37,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio)
{
Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm);
}
@@ -290,5 +292,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
.Single()
.Items.Any(i => i.ID == playlistItemId);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
}
}
@@ -7,6 +7,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Platform;
@@ -26,6 +27,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
public partial class TestSceneMultiplayerQueueList : MultiplayerTestScene
{
private MultiplayerQueueList playlist = null!;
private RulesetStore rulesets = null!;
private BeatmapManager beatmaps = null!;
private BeatmapSetInfo importedSet = null!;
private BeatmapInfo importedBeatmap = null!;
@@ -34,7 +36,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio)
{
Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, API, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm);
}
@@ -168,5 +170,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
var button = playlist.ChildrenOfType<DrawableRoomPlaylistItem.PlaylistRemoveButton>().ElementAtOrDefault(index);
return (button?.Alpha > 0) == visible;
});
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
}
}
@@ -6,6 +6,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
@@ -32,12 +33,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
private Room room = null!;
private BeatmapSetInfo importedSet = null!;
private RulesetStore rulesets = null!;
private BeatmapManager beatmaps = null!;
[BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio)
{
Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm);
@@ -162,5 +164,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
private void assertReadyButtonEnablement(bool shouldBeEnabled)
=> AddUntilStep($"ready button {(shouldBeEnabled ? "is" : "is not")} enabled", () => startControl.ChildrenOfType<MultiplayerReadyButton>().Single().Enabled.Value == shouldBeEnabled);
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
}
}
@@ -7,6 +7,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Platform;
@@ -31,6 +32,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestScenePlaylistsSongSelect : OnlinePlayTestScene
{
private RulesetStore rulesets = null!;
private BeatmapManager manager = null!;
private TestPlaylistsSongSelect songSelect = null!;
private Room room = null!;
@@ -40,7 +42,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
BeatmapStore beatmapStore;
Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
Dependencies.CacheAs(beatmapStore = new RealmDetachedBeatmapStore());
Dependencies.Cache(Realm);
@@ -189,6 +191,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddAssert("mod select visible", () => this.ChildrenOfType<FreeModSelectOverlay>().Single().State.Value, () => Is.EqualTo(Visibility.Visible));
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
private partial class TestPlaylistsSongSelect : PlaylistsSongSelect
{
public new MatchBeatmapDetailArea BeatmapDetails => (MatchBeatmapDetailArea)base.BeatmapDetails;
@@ -7,6 +7,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Platform;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
@@ -27,6 +28,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestSceneTeamVersus : ScreenTestScene
{
private RulesetStore rulesets = null!;
private BeatmapManager beatmaps = null!;
private BeatmapSetInfo importedSet = null!;
@@ -37,7 +39,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio)
{
Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm);
}
@@ -182,5 +184,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddUntilStep("wait for join", () => multiplayerClient.RoomJoined);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
}
}
@@ -7,6 +7,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Platform;
using osu.Framework.Testing;
@@ -25,6 +26,7 @@ namespace osu.Game.Tests.Visual.Playlists
{
public partial class TestSceneAddPlaylistToCollectionButton : OsuManualInputManagerTestScene
{
private RulesetStore rulesets = null!;
private BeatmapManager manager = null!;
private BeatmapSetInfo importedBeatmap = null!;
private Room room = null!;
@@ -33,7 +35,7 @@ namespace osu.Game.Tests.Visual.Playlists
[BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio)
{
Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, API, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm);
@@ -112,5 +114,13 @@ namespace osu.Game.Tests.Visual.Playlists
}
];
});
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
}
}
@@ -8,6 +8,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Platform;
using osu.Framework.Screens;
using osu.Framework.Testing;
@@ -32,6 +33,7 @@ namespace osu.Game.Tests.Visual.Playlists
{
public partial class TestScenePlaylistsRoomCreation : OnlinePlayTestScene
{
private RulesetStore rulesets = null!;
private BeatmapManager manager = null!;
private TestPlaylistsRoomSubScreen match = null!;
private BeatmapSetInfo importedBeatmap = null!;
@@ -40,7 +42,7 @@ namespace osu.Game.Tests.Visual.Playlists
[BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio)
{
Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, API, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm);
}
@@ -220,6 +222,14 @@ namespace osu.Game.Tests.Visual.Playlists
});
});
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
private partial class TestPlaylistsRoomSubScreen : PlaylistsRoomSubScreen
{
public new Bindable<PlaylistItem?> SelectedItem => base.SelectedItem;
@@ -11,6 +11,7 @@ using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Platform;
@@ -38,6 +39,7 @@ namespace osu.Game.Tests.Visual.Playlists
{
public partial class TestScenePlaylistsRoomSubScreen : OnlinePlayTestScene
{
private RulesetStore rulesets = null!;
private BeatmapManager beatmaps = null!;
private BeatmapSetInfo importedSet = null!;
@@ -46,7 +48,7 @@ namespace osu.Game.Tests.Visual.Playlists
{
BeatmapStore beatmapStore;
Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, API, audio, Resources, host, Beatmap.Default));
Dependencies.CacheAs(beatmapStore = new RealmDetachedBeatmapStore());
Dependencies.Cache(Realm);
@@ -579,6 +581,14 @@ namespace osu.Game.Tests.Visual.Playlists
AddUntilStep("mods set", () => SelectedMods.Value.Count == 1 && SelectedMods.Value.OfType<OsuModDoubleTime>().Any());
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
private partial class TestPlaylistsScreen : OsuScreen
{
public TestPlaylistsScreen(PlaylistsRoomSubScreen screen)
@@ -7,6 +7,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Platform;
using osu.Framework.Testing;
@@ -531,5 +532,13 @@ namespace osu.Game.Tests.Visual.Ranking
AddAssert("only one score with ID 12345", () => this.ChildrenOfType<ScorePanel>().Count(s => s.Score.OnlineID == 12345), () => Is.EqualTo(1));
AddUntilStep("user best position preserved", () => this.ChildrenOfType<ScorePanel>().Any(p => p.ScorePosition.Value == 133_337));
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesetStore.IsNotNull())
rulesetStore.Dispose();
}
}
}
@@ -12,6 +12,7 @@ using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
@@ -219,8 +220,15 @@ namespace osu.Game.Tests.Visual.Ranking
Tags =
[
new APITag { Id = 1, Name = "song representation/simple", Description = "Accessible and straightforward map design.", },
new APITag { Id = 2, Name = "style/clean", Description = "Visually uncluttered and organised patterns, often involving few overlaps and equal visual spacing between objects.", },
new APITag { Id = 3, Name = "aim/aim control", Description = "Patterns with velocity or direction changes which strongly go against a player's natural movement pattern.", },
new APITag
{
Id = 2, Name = "style/clean",
Description = "Visually uncluttered and organised patterns, often involving few overlaps and equal visual spacing between objects.",
},
new APITag
{
Id = 3, Name = "aim/aim control", Description = "Patterns with velocity or direction changes which strongly go against a player's natural movement pattern.",
},
new APITag { Id = 4, Name = "tap/bursts", Description = "Patterns requiring continuous movement and alternating, typically 9 notes or less.", },
]
}), 500);
@@ -403,6 +411,14 @@ namespace osu.Game.Tests.Visual.Ranking
return hitEvents;
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesetStore.IsNotNull())
rulesetStore?.Dispose();
}
private class TestRuleset : Ruleset
{
public override IEnumerable<Mod> GetModsFor(ModType type)
@@ -7,6 +7,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
@@ -28,6 +29,7 @@ namespace osu.Game.Tests.Visual.SongSelect
{
public partial class TestSceneCollectionDropdown : OsuManualInputManagerTestScene
{
private RulesetStore rulesets = null!;
private BeatmapManager beatmapManager = null!;
private CollectionDropdown dropdown = null!;
@@ -37,7 +39,7 @@ namespace osu.Game.Tests.Visual.SongSelect
[BackgroundDependencyLoader]
private void load(GameHost host)
{
Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, null, Audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm);
@@ -269,5 +271,13 @@ namespace osu.Game.Tests.Visual.SongSelect
CollectionFilterMenuItem item = dropdown.ChildrenOfType<CollectionDropdown>().Single().ItemSource.ElementAt(index);
return dropdown.ChildrenOfType<Menu.DrawableMenuItem>().Single(i => i.Item.Text.Value == item.CollectionName);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
}
}
@@ -5,6 +5,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
@@ -27,13 +28,14 @@ namespace osu.Game.Tests.Visual.SongSelect
protected override Container<Drawable> Content { get; } = new Container { RelativeSizeAxes = Axes.Both };
private DialogOverlay dialogOverlay = null!;
private RulesetStore rulesets = null!;
private BeatmapManager beatmapManager = null!;
private ManageCollectionsDialog dialog = null!;
[BackgroundDependencyLoader]
private void load(GameHost host)
{
Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, null, Audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm);
@@ -379,5 +381,13 @@ namespace osu.Game.Tests.Visual.SongSelect
private void assertCollectionName(int index, string name)
=> AddUntilStep($"item {index + 1} has correct name",
() => dialog.ChildrenOfType<DrawableCollectionList>().Single().OrderedItems.ElementAtOrDefault(index)?.ChildrenOfType<TextBox>().First().Text == name);
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
}
}
@@ -6,6 +6,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Platform;
using osu.Framework.Testing;
@@ -211,5 +212,13 @@ namespace osu.Game.Tests.Visual.SongSelect
AddUntilStep("No rank displayed", () => topLocalRank.DisplayedRank, () => Is.Null);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
}
}
@@ -190,5 +190,13 @@ namespace osu.Game.Tests.Visual.SongSelectV2
}
protected void WaitForSuspension() => AddUntilStep("wait for not current", () => !SongSelect.AsNonNull().IsCurrentScreen());
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (Rulesets.IsNotNull())
Rulesets.Dispose();
}
}
}
@@ -151,5 +151,13 @@ namespace osu.Game.Tests.Visual.SongSelectV2
},
});
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesetStore.IsNotNull())
rulesetStore.Dispose();
}
}
}
@@ -578,5 +578,13 @@ namespace osu.Game.Tests.Visual.SongSelectV2
},
};
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesetStore.IsNotNull())
rulesetStore.Dispose();
}
}
}
@@ -7,6 +7,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
@@ -29,6 +30,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
{
public partial class TestSceneCollectionDropdown : OsuManualInputManagerTestScene
{
private RulesetStore rulesets = null!;
private BeatmapManager beatmapManager = null!;
private CollectionDropdown dropdown = null!;
@@ -38,7 +40,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
[BackgroundDependencyLoader]
private void load(GameHost host)
{
Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, null, Audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm);
@@ -260,5 +262,13 @@ namespace osu.Game.Tests.Visual.SongSelectV2
CollectionFilterMenuItem item = dropdown.ChildrenOfType<CollectionDropdown>().Single().ItemSource.ElementAt(index);
return dropdown.ChildrenOfType<Menu.DrawableMenuItem>().Single(i => i.Item.Text.Value == item.CollectionName);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
}
}
@@ -9,6 +9,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Platform;
@@ -37,6 +38,7 @@ namespace osu.Game.Tests.Visual.UserInterface
private readonly ContextMenuContainer contextMenuContainer;
private readonly BeatmapLeaderboard leaderboard;
private RulesetStore rulesets = null!;
private BeatmapManager beatmapManager;
private ScoreManager scoreManager;
@@ -71,7 +73,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
dependencies.Cache(new RealmRulesetStore(Realm));
dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default));
dependencies.Cache(scoreManager = new ScoreManager(dependencies.Get<RulesetStore>(), () => beatmapManager, LocalStorage, Realm, API));
Dependencies.Cache(Realm);
@@ -151,7 +153,8 @@ namespace osu.Game.Tests.Visual.UserInterface
AddStep("click delete option", () =>
{
InputManager.MoveMouseTo(contextMenuContainer.ChildrenOfType<DrawableOsuMenuItem>().First(i => string.Equals(i.Item.Text.Value.ToString(), "delete", System.StringComparison.OrdinalIgnoreCase)));
InputManager.MoveMouseTo(contextMenuContainer.ChildrenOfType<DrawableOsuMenuItem>()
.First(i => string.Equals(i.Item.Text.Value.ToString(), "delete", System.StringComparison.OrdinalIgnoreCase)));
InputManager.Click(MouseButton.Left);
});
@@ -178,5 +181,13 @@ namespace osu.Game.Tests.Visual.UserInterface
AddUntilStep("wait for fetch", () => leaderboard.Scores.Any());
AddUntilStep("score removed from leaderboard", () => leaderboard.Scores.All(s => s.OnlineID != importedScores[0].OnlineID));
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
}
}
@@ -469,5 +469,13 @@ namespace osu.Game.Tests.Visual.UserInterface
Ruleset = rulesets.GetRuleset(3).AsNonNull()
}
};
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
}
}
@@ -7,6 +7,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
@@ -1057,6 +1058,14 @@ namespace osu.Game.Tests.Visual.UserInterface
private ModPanel getPanelForMod(Type modType)
=> modSelectOverlay.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.GetType() == modType);
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesetStore.IsNotNull())
rulesetStore.Dispose();
}
private partial class TestModSelectOverlay : UserModSelectOverlay
{
public TestModSelectOverlay()
@@ -5,6 +5,7 @@ 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.Platform;
@@ -21,6 +22,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{
protected override bool UseFreshStoragePerRun => true;
private RulesetStore rulesets = null!;
private BeatmapManager beatmapManager = null!;
private const int item_count = 20;
@@ -30,7 +32,7 @@ namespace osu.Game.Tests.Visual.UserInterface
[BackgroundDependencyLoader]
private void load(GameHost host)
{
Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, null, Audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm);
}
@@ -62,5 +64,13 @@ namespace osu.Game.Tests.Visual.UserInterface
// Ensure all the initial imports are present before running any tests.
Realm.Run(r => r.Refresh());
});
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (rulesets.IsNotNull())
rulesets.Dispose();
}
}
}
@@ -280,8 +280,6 @@ namespace osu.Game.Beatmaps.Drawables.Cards
}
createStatistics();
Action = () => beatmapSetOverlay?.FetchAndShowBeatmapSet(BeatmapSet.OnlineID);
}
private LocalisableString createArtistText()
+36 -1
View File
@@ -82,6 +82,34 @@ namespace osu.Game.Database
return;
}
if (changes.InsertedIndices.Length == 1 && changes.DeletedIndices.Length == 1)
{
lock (detachedBeatmapSets)
{
var deletedSet = detachedBeatmapSets[changes.DeletedIndices[0]];
var insertedSet = sender[changes.InsertedIndices[0]];
// this handles beatmap updates using a heuristic that a beatmap update will preserve the online ID.
// it relies on the fact that updates are performed by removing the old set and adding a new one, in a single transaction.
// instead of removing the old set and adding a new one to the collection too, which would trigger consumers' logic related to set removals,
// move the deleted set to the index occupied by the new one and then replace it in-place.
// due to this, the operation can be presented to consumer in a manner that permits them to actually handle this as a replace operation
// and not trigger any set removal logic that may result in selections changing or similar undesirable side effects.
if (deletedSet.OnlineID == insertedSet.OnlineID)
{
pendingOperations.Enqueue(new OperationArgs
{
Type = OperationType.MoveAndReplace,
BeatmapSet = insertedSet.Detach(),
Index = changes.DeletedIndices[0],
NewIndex = changes.InsertedIndices[0],
});
return;
}
}
}
foreach (int i in changes.DeletedIndices.OrderDescending())
{
pendingOperations.Enqueue(new OperationArgs
@@ -138,6 +166,11 @@ namespace osu.Game.Database
detachedBeatmapSets.ReplaceRange(op.Index, 1, new[] { op.BeatmapSet! });
break;
case OperationType.MoveAndReplace:
detachedBeatmapSets.Move(op.Index, op.NewIndex!.Value);
detachedBeatmapSets.ReplaceRange(op.NewIndex!.Value, 1, [op.BeatmapSet!]);
break;
case OperationType.Remove:
detachedBeatmapSets.RemoveAt(op.Index);
break;
@@ -160,13 +193,15 @@ namespace osu.Game.Database
public OperationType Type;
public BeatmapSetInfo? BeatmapSet;
public int Index;
public int? NewIndex;
}
private enum OperationType
{
Insert,
Update,
Remove
Remove,
MoveAndReplace,
}
}
}
+12 -1
View File
@@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
@@ -77,6 +78,8 @@ namespace osu.Game.Overlays.Toolbar
protected readonly Container BackgroundContent;
private IDisposable? realmSubscription;
[Resolved]
private RealmAccess realm { get; set; } = null!;
@@ -184,7 +187,8 @@ namespace osu.Game.Overlays.Toolbar
{
if (Hotkey != null)
{
realm.SubscribeToPropertyChanged(r => r.All<RealmKeyBinding>().FirstOrDefault(rkb => rkb.RulesetName == null && rkb.ActionInt == (int)Hotkey.Value), kb => kb.KeyCombinationString, updateKeyBindingTooltip);
realmSubscription = realm.SubscribeToPropertyChanged(r => r.All<RealmKeyBinding>().FirstOrDefault(rkb => rkb.RulesetName == null && rkb.ActionInt == (int)Hotkey.Value),
kb => kb.KeyCombinationString, updateKeyBindingTooltip);
}
}
@@ -234,6 +238,13 @@ namespace osu.Game.Overlays.Toolbar
? $" ({keyBindingString})"
: string.Empty;
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
realmSubscription?.Dispose();
}
}
public partial class OpaqueBackground : Container
+9 -6
View File
@@ -237,26 +237,29 @@ namespace osu.Game.Screens.Select
private void beatmapSetsChanged(object? beatmaps, NotifyCollectionChangedEventArgs changed)
{
IEnumerable<BeatmapSetInfo>? oldBeatmapSets = changed.OldItems?.Cast<BeatmapSetInfo>();
HashSet<Guid> oldBeatmapSetIDs = oldBeatmapSets?.Select(s => s.ID).ToHashSet() ?? [];
IEnumerable<BeatmapSetInfo>? newBeatmapSets = changed.NewItems?.Cast<BeatmapSetInfo>();
HashSet<Guid> newBeatmapSetIDs = newBeatmapSets?.Select(s => s.ID).ToHashSet() ?? [];
switch (changed.Action)
{
case NotifyCollectionChangedAction.Add:
HashSet<Guid> newBeatmapSetIDs = newBeatmapSets!.Select(s => s.ID).ToHashSet();
setsRequiringRemoval.RemoveWhere(s => newBeatmapSetIDs.Contains(s.ID));
setsRequiringUpdate.AddRange(newBeatmapSets!);
break;
case NotifyCollectionChangedAction.Remove:
IEnumerable<BeatmapSetInfo> oldBeatmapSets = changed.OldItems!.Cast<BeatmapSetInfo>();
HashSet<Guid> oldBeatmapSetIDs = oldBeatmapSets.Select(s => s.ID).ToHashSet();
setsRequiringUpdate.RemoveWhere(s => oldBeatmapSetIDs.Contains(s.ID));
setsRequiringRemoval.AddRange(oldBeatmapSets);
setsRequiringRemoval.AddRange(oldBeatmapSets!);
break;
case NotifyCollectionChangedAction.Replace:
setsRequiringUpdate.RemoveWhere(s => oldBeatmapSetIDs.Contains(s.ID));
setsRequiringRemoval.AddRange(oldBeatmapSets!);
setsRequiringRemoval.RemoveWhere(s => newBeatmapSetIDs.Contains(s.ID));
setsRequiringUpdate.AddRange(newBeatmapSets!);
break;
@@ -32,9 +32,6 @@ namespace osu.Game.Tests.Visual.OnlinePlay
protected override Container<Drawable> Content => content;
[Resolved]
private RulesetStore rulesets { get; set; } = null!;
private readonly Container content;
private readonly Container drawableDependenciesContainer;
private DelegatedDependencyContainer dependencies = null!;
@@ -100,7 +97,11 @@ namespace osu.Game.Tests.Visual.OnlinePlay
Room[] rooms = new Room[count];
// Can't reference Osu ruleset project here.
ruleset ??= rulesets.GetRuleset(0)!;
if (ruleset == null)
{
using var assemblyRulesetStore = new AssemblyRulesetStore();
ruleset = assemblyRulesetStore.GetRuleset(0)!;
}
for (int i = 0; i < count; i++)
{
+3
View File
@@ -332,6 +332,9 @@ namespace osu.Game.Tests.Visual
if (MusicController?.TrackLoaded == true)
MusicController.Stop();
if (realm?.IsValueCreated == true)
Realm.Dispose();
RecycleLocalStorage(true);
}