1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 05:02:55 +08:00

Merge pull request #15919 from peppy/i-ruleset-store

Add `IRulesetStore` to allow for transitional usage in upcoming manager classes
This commit is contained in:
Dean Herbert 2021-12-05 00:01:40 +09:00 committed by GitHub
commit 70e818ff8f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 125 additions and 61 deletions

View File

@ -45,9 +45,9 @@ namespace osu.Game.Tests.Database
{
var rulesets = new RealmRulesetStore(realmFactory, storage);
Assert.IsTrue((rulesets.AvailableRulesets.First() as RealmRuleset)?.IsManaged == false);
Assert.IsTrue((rulesets.GetRuleset(0) as RealmRuleset)?.IsManaged == false);
Assert.IsTrue((rulesets.GetRuleset("mania") as RealmRuleset)?.IsManaged == false);
Assert.IsFalse(rulesets.AvailableRulesets.First().IsManaged);
Assert.IsFalse(rulesets.GetRuleset(0)?.IsManaged);
Assert.IsFalse(rulesets.GetRuleset("mania")?.IsManaged);
});
}
}

View File

@ -20,7 +20,7 @@ namespace osu.Game.Tests.Visual.Menus
private TestToolbar toolbar;
[Resolved]
private RulesetStore rulesets { get; set; }
private IRulesetStore rulesets { get; set; }
[SetUp]
public void SetUp() => Schedule(() =>

View File

@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.Online
}
[Resolved]
private RulesetStore rulesets { get; set; }
private IRulesetStore rulesets { get; set; }
[Test]
public void TestMultipleRulesetsBeatmapSet()

View File

@ -30,7 +30,7 @@ namespace osu.Game.Tests.Visual.Online
}
[Resolved]
private RulesetStore rulesets { get; set; }
private IRulesetStore rulesets { get; set; }
[Test]
public void TestLoading()

View File

@ -24,7 +24,7 @@ namespace osu.Game.Tests.Visual.Online
private TestUserListPanel evast;
[Resolved]
private RulesetStore rulesetStore { get; set; }
private IRulesetStore rulesetStore { get; set; }
[SetUp]
public void SetUp() => Schedule(() =>

View File

@ -6,12 +6,17 @@ using osu.Framework.Graphics;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Tests.Visual;
using osu.Game.Tournament.Components;
namespace osu.Game.Tournament.Tests.Components
{
public class TestSceneTournamentBeatmapPanel : TournamentTestScene
{
/// <remarks>
/// Warning: the below API instance is actually the online API, rather than the dummy API provided by the test.
/// It cannot be trivially replaced because setting <see cref="OsuTestScene.UseOnlineAPI"/> to <see langword="true"/> causes <see cref="OsuTestScene.API"/> to no longer be usable.
/// </remarks>
[Resolved]
private IAPIProvider api { get; set; }

View File

@ -19,7 +19,7 @@ namespace osu.Game.Tournament.Tests.Components
private IAPIProvider api { get; set; }
[Resolved]
private RulesetStore rulesets { get; set; }
private IRulesetStore rulesets { get; set; }
private FillFlowContainer<TournamentBeatmapPanel> fillFlow;

View File

@ -21,7 +21,7 @@ namespace osu.Game.Tournament.Components
private readonly string modAcronym;
[Resolved]
private RulesetStore rulesets { get; set; }
private IRulesetStore rulesets { get; set; }
public TournamentModIcon(string modAcronym)
{

View File

@ -28,7 +28,7 @@ namespace osu.Game.Tournament.IPC
protected IAPIProvider API { get; private set; }
[Resolved]
protected RulesetStore Rulesets { get; private set; }
protected IRulesetStore Rulesets { get; private set; }
[Resolved]
private GameHost host { get; set; }

View File

@ -25,7 +25,7 @@ namespace osu.Game.Beatmaps
private IAPIProvider api { get; set; }
[Resolved]
private RulesetStore rulesets { get; set; }
private IRulesetStore rulesets { get; set; }
[Resolved]
private Bindable<RulesetInfo> ruleset { get; set; }
@ -35,7 +35,7 @@ namespace osu.Game.Beatmaps
/// </summary>
private int? requestedUserId;
private readonly Dictionary<RulesetInfo, double> recommendedDifficultyMapping = new Dictionary<RulesetInfo, double>();
private readonly Dictionary<IRulesetInfo, double> recommendedDifficultyMapping = new Dictionary<IRulesetInfo, double>();
private readonly IBindable<APIState> apiState = new Bindable<APIState>();
@ -101,7 +101,7 @@ namespace osu.Game.Beatmaps
/// Rulesets ordered descending by their respective recommended difficulties.
/// The currently selected ruleset will always be first.
/// </returns>
private IEnumerable<RulesetInfo> orderedRulesets
private IEnumerable<IRulesetInfo> orderedRulesets
{
get
{

View File

@ -86,7 +86,7 @@ namespace osu.Game.Beatmaps.Drawables
}
[Resolved]
private RulesetStore rulesets { get; set; }
private IRulesetStore rulesets { get; set; }
[BackgroundDependencyLoader]
private void load(OsuColour colours)

View File

@ -50,6 +50,8 @@ namespace osu.Game.Models
public bool Equals(RealmRuleset? other) => other != null && OnlineID == other.OnlineID && Available == other.Available && Name == other.Name && InstantiationInfo == other.InstantiationInfo;
public bool Equals(IRulesetInfo? other) => other is RealmRuleset b && Equals(b);
public override string ToString() => Name;
public RealmRuleset Clone() => new RealmRuleset

View File

@ -9,7 +9,7 @@ namespace osu.Game.Online.API.Requests
public class GetUserRequest : APIRequest<APIUser>
{
public readonly string Lookup;
public readonly RulesetInfo Ruleset;
public readonly IRulesetInfo Ruleset;
private readonly LookupType lookupType;
/// <summary>
@ -24,7 +24,7 @@ namespace osu.Game.Online.API.Requests
/// </summary>
/// <param name="userId">The user to get.</param>
/// <param name="ruleset">The ruleset to get the user's info for.</param>
public GetUserRequest(long? userId = null, RulesetInfo ruleset = null)
public GetUserRequest(long? userId = null, IRulesetInfo ruleset = null)
{
Lookup = userId.ToString();
lookupType = LookupType.Id;
@ -36,7 +36,7 @@ namespace osu.Game.Online.API.Requests
/// </summary>
/// <param name="username">The user to get.</param>
/// <param name="ruleset">The ruleset to get the user's info for.</param>
public GetUserRequest(string username = null, RulesetInfo ruleset = null)
public GetUserRequest(string username = null, IRulesetInfo ruleset = null)
{
Lookup = username;
lookupType = LookupType.Username;

View File

@ -118,7 +118,7 @@ namespace osu.Game.Online.Multiplayer
protected IAPIProvider API { get; private set; } = null!;
[Resolved]
protected RulesetStore Rulesets { get; private set; } = null!;
protected IRulesetStore Rulesets { get; private set; } = null!;
[Resolved]
private UserLookupCache userLookupCache { get; set; } = null!;
@ -733,6 +733,9 @@ namespace osu.Game.Online.Multiplayer
var apiBeatmap = await GetAPIBeatmap(item.BeatmapID).ConfigureAwait(false);
var ruleset = Rulesets.GetRuleset(item.RulesetID);
Debug.Assert(ruleset != null);
var rulesetInstance = ruleset.CreateInstance();
var playlistItem = new PlaylistItem

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Diagnostics;
using System.Linq;
using Newtonsoft.Json;
using osu.Framework.Bindables;
@ -85,11 +86,13 @@ namespace osu.Game.Online.Rooms
public void MarkInvalid() => valid.Value = false;
public void MapObjects(RulesetStore rulesets)
public void MapObjects(IRulesetStore rulesets)
{
Beatmap.Value ??= apiBeatmap;
Ruleset.Value ??= rulesets.GetRuleset(RulesetID);
Debug.Assert(Ruleset.Value != null);
Ruleset rulesetInstance = Ruleset.Value.CreateInstance();
if (allowedModsBacking != null)

View File

@ -196,6 +196,7 @@ namespace osu.Game
runMigrations();
dependencies.Cache(RulesetStore = new RulesetStore(contextFactory, Storage));
dependencies.CacheAs<IRulesetStore>(RulesetStore);
dependencies.Cache(realmFactory = new RealmContextFactory(Storage, "client", contextFactory));

View File

@ -47,7 +47,7 @@ namespace osu.Game.Overlays.BeatmapSet
}
[Resolved]
private RulesetStore rulesets { get; set; }
private IRulesetStore rulesets { get; set; }
private void onRulesetChanged(ValueChangedEvent<IRulesetInfo> ruleset)
{
@ -57,8 +57,13 @@ namespace osu.Game.Overlays.BeatmapSet
if (ruleset.NewValue == null)
return;
var rulesetInstance = rulesets.GetRuleset(ruleset.NewValue.OnlineID)?.CreateInstance();
if (rulesetInstance == null)
return;
modsContainer.Add(new ModButton(new ModNoMod()));
modsContainer.AddRange(rulesets.GetRuleset(ruleset.NewValue.OnlineID).CreateInstance().AllMods.Where(m => m.UserPlayable).Select(m => new ModButton(m)));
modsContainer.AddRange(rulesetInstance.AllMods.Where(m => m.UserPlayable).Select(m => new ModButton(m)));
modsContainer.ForEach(button =>
{

View File

@ -1,21 +1,20 @@
// 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 osuTK;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Online.API;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Framework.Localisation;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osuTK;
namespace osu.Game.Overlays.Profile.Sections
{
@ -24,9 +23,6 @@ namespace osu.Game.Overlays.Profile.Sections
[Resolved]
private IAPIProvider api { get; set; }
[Resolved]
protected RulesetStore Rulesets { get; private set; }
protected int VisiblePages;
protected int ItemsPerPage;

View File

@ -25,7 +25,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent
private IAPIProvider api { get; set; }
[Resolved]
private RulesetStore rulesets { get; set; }
private IRulesetStore rulesets { get; set; }
private readonly APIRecentActivity activity;

View File

@ -1,21 +1,21 @@
// 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 osu.Framework.Graphics;
using osu.Framework.Bindables;
using osu.Game.Rulesets;
using osu.Framework.Graphics.Containers;
using osu.Game.Online.API.Requests.Responses;
using osuTK;
using osu.Framework.Allocation;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Overlays.Rankings.Tables;
using System.Linq;
using System.Threading;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps.Drawables.Cards;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.Rankings.Tables;
using osu.Game.Rulesets;
using osuTK;
namespace osu.Game.Overlays.Rankings
{

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 osu.Game.Database;
#nullable enable
@ -10,7 +11,7 @@ namespace osu.Game.Rulesets
/// <summary>
/// A representation of a ruleset's metadata.
/// </summary>
public interface IRulesetInfo : IHasOnlineID<int>
public interface IRulesetInfo : IHasOnlineID<int>, IEquatable<IRulesetInfo>
{
/// <summary>
/// The user-exposed name of this ruleset.

View File

@ -0,0 +1,31 @@
// 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.Collections.Generic;
#nullable enable
namespace osu.Game.Rulesets
{
public interface IRulesetStore
{
/// <summary>
/// Retrieve a ruleset using a known ID.
/// </summary>
/// <param name="id">The ruleset's internal ID.</param>
/// <returns>A ruleset, if available, else null.</returns>
IRulesetInfo? GetRuleset(int id);
/// <summary>
/// Retrieve a ruleset using a known short name.
/// </summary>
/// <param name="shortName">The ruleset's short name.</param>
/// <returns>A ruleset, if available, else null.</returns>
IRulesetInfo? GetRuleset(string shortName);
/// <summary>
/// All available rulesets.
/// </summary>
IEnumerable<IRulesetInfo> AvailableRulesets { get; }
}
}

View File

@ -49,6 +49,8 @@ namespace osu.Game.Rulesets
public override bool Equals(object obj) => obj is RulesetInfo rulesetInfo && Equals(rulesetInfo);
public bool Equals(IRulesetInfo other) => other is RulesetInfo b && Equals(b);
[SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode")]
public override int GetHashCode()
{

View File

@ -13,7 +13,7 @@ using osu.Game.Database;
namespace osu.Game.Rulesets
{
public class RulesetStore : DatabaseBackedStore, IDisposable
public class RulesetStore : DatabaseBackedStore, IRulesetStore, IDisposable
{
private const string ruleset_library_prefix = "osu.Game.Rulesets";
@ -236,5 +236,13 @@ namespace osu.Game.Rulesets
{
AppDomain.CurrentDomain.AssemblyResolve -= resolveRulesetDependencyAssembly;
}
#region Implementation of IRulesetStore
IRulesetInfo IRulesetStore.GetRuleset(int id) => GetRuleset(id);
IRulesetInfo IRulesetStore.GetRuleset(string shortName) => GetRuleset(shortName);
IEnumerable<IRulesetInfo> IRulesetStore.AvailableRulesets => AvailableRulesets;
#endregion
}
}

View File

@ -27,7 +27,7 @@ namespace osu.Game.Screens.OnlinePlay.Components
private readonly Bindable<Room> joinedRoom = new Bindable<Room>();
[Resolved]
private RulesetStore rulesets { get; set; }
private IRulesetStore rulesets { get; set; }
[Resolved]
private IAPIProvider api { get; set; }

View File

@ -35,7 +35,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
private IAPIProvider api { get; set; }
[Resolved]
private RulesetStore rulesets { get; set; }
private IRulesetStore rulesets { get; set; }
private SpriteIcon crown;
@ -185,9 +185,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
const double fade_time = 50;
// Todo: Should use the room's selected item to determine ruleset.
var ruleset = rulesets.GetRuleset(0).CreateInstance();
var ruleset = rulesets.GetRuleset(0)?.CreateInstance();
int? currentModeRank = User.User?.RulesetsStatistics?.GetValueOrDefault(ruleset.ShortName)?.GlobalRank;
int? currentModeRank = ruleset != null ? User.User?.RulesetsStatistics?.GetValueOrDefault(ruleset.ShortName)?.GlobalRank : null;
userRankText.Text = currentModeRank != null ? $"#{currentModeRank.Value:N0}" : string.Empty;
userStateDisplay.UpdateStatus(User.State, User.BeatmapAvailability);

View File

@ -27,7 +27,6 @@ using osu.Game.Screens.OnlinePlay.Match.Components;
using osu.Game.Screens.Spectate;
using osu.Game.Users;
using osuTK;
using APIUser = osu.Game.Online.API.Requests.Responses.APIUser;
namespace osu.Game.Screens.Play
{

View File

@ -18,7 +18,7 @@ using osu.Game.Rulesets;
namespace osu.Game.Stores
{
public class RealmRulesetStore : IDisposable
public class RealmRulesetStore : IRulesetStore, IDisposable
{
private readonly RealmContextFactory realmFactory;
@ -29,9 +29,9 @@ namespace osu.Game.Stores
/// <summary>
/// All available rulesets.
/// </summary>
public IEnumerable<IRulesetInfo> AvailableRulesets => availableRulesets;
public IEnumerable<RealmRuleset> AvailableRulesets => availableRulesets;
private readonly List<IRulesetInfo> availableRulesets = new List<IRulesetInfo>();
private readonly List<RealmRuleset> availableRulesets = new List<RealmRuleset>();
public RealmRulesetStore(RealmContextFactory realmFactory, Storage? storage = null)
{
@ -64,14 +64,14 @@ namespace osu.Game.Stores
/// </summary>
/// <param name="id">The ruleset's internal ID.</param>
/// <returns>A ruleset, if available, else null.</returns>
public IRulesetInfo? GetRuleset(int id) => AvailableRulesets.FirstOrDefault(r => r.OnlineID == id);
public RealmRuleset? GetRuleset(int id) => AvailableRulesets.FirstOrDefault(r => r.OnlineID == id);
/// <summary>
/// Retrieve a ruleset using a known short name.
/// </summary>
/// <param name="shortName">The ruleset's short name.</param>
/// <returns>A ruleset, if available, else null.</returns>
public IRulesetInfo? GetRuleset(string shortName) => AvailableRulesets.FirstOrDefault(r => r.ShortName == shortName);
public RealmRuleset? GetRuleset(string shortName) => AvailableRulesets.FirstOrDefault(r => r.ShortName == shortName);
private Assembly? resolveRulesetDependencyAssembly(object? sender, ResolveEventArgs args)
{
@ -258,5 +258,13 @@ namespace osu.Game.Stores
{
AppDomain.CurrentDomain.AssemblyResolve -= resolveRulesetDependencyAssembly;
}
#region Implementation of IRulesetStore
IRulesetInfo? IRulesetStore.GetRuleset(int id) => GetRuleset(id);
IRulesetInfo? IRulesetStore.GetRuleset(string shortName) => GetRuleset(shortName);
IEnumerable<IRulesetInfo> IRulesetStore.AvailableRulesets => AvailableRulesets;
#endregion
}
}

View File

@ -29,9 +29,9 @@ namespace osu.Game.Users
{
public IBeatmapInfo BeatmapInfo { get; }
public RulesetInfo Ruleset { get; }
public IRulesetInfo Ruleset { get; }
protected InGame(IBeatmapInfo beatmapInfo, RulesetInfo ruleset)
protected InGame(IBeatmapInfo beatmapInfo, IRulesetInfo ruleset)
{
BeatmapInfo = beatmapInfo;
Ruleset = ruleset;
@ -42,7 +42,7 @@ namespace osu.Game.Users
public class InMultiplayerGame : InGame
{
public InMultiplayerGame(IBeatmapInfo beatmapInfo, RulesetInfo ruleset)
public InMultiplayerGame(IBeatmapInfo beatmapInfo, IRulesetInfo ruleset)
: base(beatmapInfo, ruleset)
{
}
@ -52,7 +52,7 @@ namespace osu.Game.Users
public class InPlaylistGame : InGame
{
public InPlaylistGame(IBeatmapInfo beatmapInfo, RulesetInfo ruleset)
public InPlaylistGame(IBeatmapInfo beatmapInfo, IRulesetInfo ruleset)
: base(beatmapInfo, ruleset)
{
}
@ -60,7 +60,7 @@ namespace osu.Game.Users
public class InSoloGame : InGame
{
public InSoloGame(IBeatmapInfo beatmapInfo, RulesetInfo ruleset)
public InSoloGame(IBeatmapInfo beatmapInfo, IRulesetInfo ruleset)
: base(beatmapInfo, ruleset)
{
}