From 7bab48762190b888dda9bb40c2c228397c0b1ac4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 Nov 2021 16:17:50 +0900 Subject: [PATCH 1/8] Remove usage of `ToBeatmapInfo` in `APIScoreInfo.CreateScoreInfo` --- osu.Game/Online/API/Requests/Responses/APIScoreInfo.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIScoreInfo.cs b/osu.Game/Online/API/Requests/Responses/APIScoreInfo.cs index 5395fe0429..82f56d27fd 100644 --- a/osu.Game/Online/API/Requests/Responses/APIScoreInfo.cs +++ b/osu.Game/Online/API/Requests/Responses/APIScoreInfo.cs @@ -98,7 +98,7 @@ namespace osu.Game.Online.API.Requests.Responses { TotalScore = TotalScore, MaxCombo = MaxCombo, - BeatmapInfo = Beatmap?.ToBeatmapInfo(rulesets), + BeatmapInfo = beatmap, User = User, Accuracy = Accuracy, OnlineScoreID = OnlineID, @@ -111,9 +111,6 @@ namespace osu.Game.Online.API.Requests.Responses Mods = modInstances, }; - if (beatmap != null) - scoreInfo.BeatmapInfo = beatmap; - if (Statistics != null) { foreach (var kvp in Statistics) From 08d94f864ff7bf50fbf0c9d251fe9a99c7a19675 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 1 Nov 2021 15:43:34 +0900 Subject: [PATCH 2/8] Update `ScoresContainer` to not use `ToBeatmapInfo` --- osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 4a00c8b4a0..3891d68d35 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -66,7 +66,10 @@ namespace osu.Game.Overlays.BeatmapSet.Scores if (value?.Scores.Any() != true) return; - scoreManager.OrderByTotalScoreAsync(value.Scores.Select(s => s.CreateScoreInfo(rulesets, Beatmap.Value.ToBeatmapInfo(rulesets))).ToArray(), loadCancellationSource.Token) + // TODO: temporary. should be removed once `OrderByTotalScore` can accept `IScoreInfo`. + var beatmapInfo = new BeatmapInfo { MaxCombo = Beatmap.Value.MaxCombo }; + + scoreManager.OrderByTotalScoreAsync(value.Scores.Select(s => s.CreateScoreInfo(rulesets, beatmapInfo)).ToArray(), loadCancellationSource.Token) .ContinueWith(ordered => Schedule(() => { if (loadCancellationSource.IsCancellationRequested) @@ -78,7 +81,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores scoreTable.Show(); var userScore = value.UserScore; - var userScoreInfo = userScore?.Score.CreateScoreInfo(rulesets, Beatmap.Value.ToBeatmapInfo(rulesets)); + var userScoreInfo = userScore?.Score.CreateScoreInfo(rulesets, beatmapInfo); topScoresContainer.Add(new DrawableTopScore(topScore)); From eb17d897a36166e39b0ec714d23901dae3479582 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 1 Nov 2021 15:37:38 +0900 Subject: [PATCH 3/8] Finally, remove the `To*` methods as they have no usages --- .../API/Requests/Responses/APIBeatmap.cs | 28 ------------------- .../API/Requests/Responses/APIBeatmapSet.cs | 22 --------------- 2 files changed, 50 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs index 653b011f73..2560502173 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs @@ -81,34 +81,6 @@ namespace osu.Game.Online.API.Requests.Responses public double BPM { get; set; } - public virtual BeatmapInfo ToBeatmapInfo(RulesetStore rulesets) - { - var set = BeatmapSet?.ToBeatmapSet(rulesets); - - return new BeatmapInfo - { - Metadata = set?.Metadata ?? new BeatmapMetadata(), - Ruleset = rulesets.GetRuleset(RulesetID), - StarDifficulty = StarRating, - OnlineBeatmapID = OnlineID, - Version = DifficultyName, - // this is actually an incorrect mapping (Length is calculated as drain length in lazer's import process, see BeatmapManager.calculateLength). - Length = Length, - Status = Status, - MD5Hash = Checksum, - BeatmapSet = set, - MaxCombo = MaxCombo, - BaseDifficulty = new BeatmapDifficulty - { - DrainRate = DrainRate, - CircleSize = CircleSize, - ApproachRate = ApproachRate, - OverallDifficulty = OverallDifficulty, - }, - OnlineInfo = this, - }; - } - #region Implementation of IBeatmapInfo public IBeatmapMetadataInfo Metadata => (BeatmapSet as IBeatmapSetInfo)?.Metadata ?? new BeatmapMetadata(); diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index c41271ad5c..47536879b2 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -3,11 +3,9 @@ using System; using System.Collections.Generic; -using System.Linq; using Newtonsoft.Json; using osu.Game.Beatmaps; using osu.Game.Database; -using osu.Game.Rulesets; using osu.Game.Users; #nullable enable @@ -121,26 +119,6 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"beatmaps")] public APIBeatmap[] Beatmaps { get; set; } = Array.Empty(); - public virtual BeatmapSetInfo ToBeatmapSet(RulesetStore rulesets) - { - var beatmapSet = new BeatmapSetInfo - { - OnlineBeatmapSetID = OnlineID, - Metadata = metadata, - Status = Status, - }; - - beatmapSet.Beatmaps = Beatmaps.Select(b => - { - var beatmap = b.ToBeatmapInfo(rulesets); - beatmap.BeatmapSet = beatmapSet; - beatmap.Metadata = beatmapSet.Metadata; - return beatmap; - }).ToList(); - - return beatmapSet; - } - private BeatmapMetadata metadata => new BeatmapMetadata { Title = Title, From 9f9ef570ee86edcf32a6af143a2a1f15e1e838e2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 Nov 2021 14:40:22 +0900 Subject: [PATCH 4/8] Also propagate `Status` in temporary `BeatmapInfo` usage --- .../Overlays/BeatmapSet/Scores/ScoresContainer.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 3891d68d35..69739b3352 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -66,8 +67,16 @@ namespace osu.Game.Overlays.BeatmapSet.Scores if (value?.Scores.Any() != true) return; + var apiBeatmap = Beatmap.Value; + + Debug.Assert(apiBeatmap != null); + // TODO: temporary. should be removed once `OrderByTotalScore` can accept `IScoreInfo`. - var beatmapInfo = new BeatmapInfo { MaxCombo = Beatmap.Value.MaxCombo }; + var beatmapInfo = new BeatmapInfo + { + MaxCombo = apiBeatmap.MaxCombo, + Status = apiBeatmap.Status + }; scoreManager.OrderByTotalScoreAsync(value.Scores.Select(s => s.CreateScoreInfo(rulesets, beatmapInfo)).ToArray(), loadCancellationSource.Token) .ContinueWith(ordered => Schedule(() => @@ -77,7 +86,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores var topScore = ordered.Result.First(); - scoreTable.DisplayScores(ordered.Result, topScore.BeatmapInfo?.Status.GrantsPerformancePoints() == true); + scoreTable.DisplayScores(ordered.Result, apiBeatmap.Status.GrantsPerformancePoints()); scoreTable.Show(); var userScore = value.UserScore; From b90f44493ca2cedbe985b72ec56d738e3d069307 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 Nov 2021 16:27:13 +0900 Subject: [PATCH 5/8] Remove importer inheritance from `IModelManager` Now only exists in legacy implementations, to reduce inheritance complexity of interfaces which are going to be used going forwards. --- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- osu.Game/Database/ArchiveModelManager.cs | 2 +- osu.Game/Database/IModelManager.cs | 2 +- osu.Game/Scoring/ScoreManager.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 7a9f3e0a45..c68088a5e2 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -29,7 +29,7 @@ namespace osu.Game.Beatmaps /// Handles general operations related to global beatmap management. /// [ExcludeFromDynamicCompile] - public class BeatmapManager : IModelDownloader, IModelManager, IModelFileManager, IWorkingBeatmapCache, IDisposable + public class BeatmapManager : IModelDownloader, IModelManager, IModelFileManager, IModelImporter, IWorkingBeatmapCache, IDisposable { private readonly BeatmapModelManager beatmapModelManager; private readonly BeatmapModelDownloader beatmapModelDownloader; diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs index 4e40e52051..d2f9ee1dc1 100644 --- a/osu.Game/Database/ArchiveModelManager.cs +++ b/osu.Game/Database/ArchiveModelManager.cs @@ -30,7 +30,7 @@ namespace osu.Game.Database /// /// The model type. /// The associated file join type. - public abstract class ArchiveModelManager : IModelManager, IModelFileManager + public abstract class ArchiveModelManager : IModelImporter, IModelManager, IModelFileManager where TModel : class, IHasFiles, IHasPrimaryKey, ISoftDelete where TFileModel : class, INamedFileInfo, IHasPrimaryKey, new() { diff --git a/osu.Game/Database/IModelManager.cs b/osu.Game/Database/IModelManager.cs index f5e401cdfb..0be927322d 100644 --- a/osu.Game/Database/IModelManager.cs +++ b/osu.Game/Database/IModelManager.cs @@ -14,7 +14,7 @@ namespace osu.Game.Database /// Represents a model manager that publishes events when s are added or removed. /// /// The model type. - public interface IModelManager : IModelImporter + public interface IModelManager where TModel : class { /// diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index 253591eb56..380d2590bf 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -25,7 +25,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Scoring { - public class ScoreManager : IModelManager, IModelFileManager, IModelDownloader + public class ScoreManager : IModelManager, IModelImporter, IModelFileManager, IModelDownloader { private readonly Scheduler scheduler; private readonly Func difficulties; From 1fe9bca819bd4e7ee984c8756b7bc253e17a3098 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 Nov 2021 16:46:40 +0900 Subject: [PATCH 6/8] Change `ModelDownloader`'s requirement to an `IModelImporter` rather than `IModelManager` --- .../TestSceneOnlinePlayBeatmapAvailabilityTracker.cs | 6 +++--- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- osu.Game/Beatmaps/BeatmapModelDownloader.cs | 4 ++-- osu.Game/Database/ModelDownloader.cs | 10 +++++----- osu.Game/Scoring/ScoreModelDownloader.cs | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs index 5e7ce3abf5..70e62cc087 100644 --- a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs +++ b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs @@ -168,15 +168,15 @@ namespace osu.Game.Tests.Online return new TestBeatmapModelManager(this, storage, contextFactory, rulesets, api, host); } - protected override BeatmapModelDownloader CreateBeatmapModelDownloader(IBeatmapModelManager manager, IAPIProvider api, GameHost host) + protected override BeatmapModelDownloader CreateBeatmapModelDownloader(IModelImporter manager, IAPIProvider api, GameHost host) { return new TestBeatmapModelDownloader(manager, api, host); } internal class TestBeatmapModelDownloader : BeatmapModelDownloader { - public TestBeatmapModelDownloader(IBeatmapModelManager modelManager, IAPIProvider apiProvider, GameHost gameHost) - : base(modelManager, apiProvider, gameHost) + public TestBeatmapModelDownloader(IModelImporter importer, IAPIProvider apiProvider, GameHost gameHost) + : base(importer, apiProvider, gameHost) { } diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index c68088a5e2..7e19057fb3 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -54,7 +54,7 @@ namespace osu.Game.Beatmaps } } - protected virtual BeatmapModelDownloader CreateBeatmapModelDownloader(IBeatmapModelManager modelManager, IAPIProvider api, GameHost host) + protected virtual BeatmapModelDownloader CreateBeatmapModelDownloader(IModelImporter modelManager, IAPIProvider api, GameHost host) { return new BeatmapModelDownloader(modelManager, api, host); } diff --git a/osu.Game/Beatmaps/BeatmapModelDownloader.cs b/osu.Game/Beatmaps/BeatmapModelDownloader.cs index 001726e741..e708190b0e 100644 --- a/osu.Game/Beatmaps/BeatmapModelDownloader.cs +++ b/osu.Game/Beatmaps/BeatmapModelDownloader.cs @@ -16,8 +16,8 @@ namespace osu.Game.Beatmaps public override ArchiveDownloadRequest GetExistingDownload(BeatmapSetInfo model) => CurrentDownloads.Find(r => r.Model.OnlineID == model.OnlineID); - public BeatmapModelDownloader(IBeatmapModelManager beatmapModelManager, IAPIProvider api, GameHost host = null) - : base(beatmapModelManager, api, host) + public BeatmapModelDownloader(IModelImporter beatmapImporter, IAPIProvider api, GameHost host = null) + : base(beatmapImporter, api, host) { } } diff --git a/osu.Game/Database/ModelDownloader.cs b/osu.Game/Database/ModelDownloader.cs index 12bf5e9ce7..a2a4209f1f 100644 --- a/osu.Game/Database/ModelDownloader.cs +++ b/osu.Game/Database/ModelDownloader.cs @@ -27,14 +27,14 @@ namespace osu.Game.Database private readonly Bindable>> downloadFailed = new Bindable>>(); - private readonly IModelManager modelManager; + private readonly IModelImporter importer; private readonly IAPIProvider api; protected readonly List> CurrentDownloads = new List>(); - protected ModelDownloader(IModelManager modelManager, IAPIProvider api, IIpcHost importHost = null) + protected ModelDownloader(IModelImporter importer, IAPIProvider api, IIpcHost importHost = null) { - this.modelManager = modelManager; + this.importer = importer; this.api = api; } @@ -68,7 +68,7 @@ namespace osu.Game.Database Task.Factory.StartNew(async () => { // This gets scheduled back to the update thread, but we want the import to run in the background. - var imported = await modelManager.Import(notification, new ImportTask(filename)).ConfigureAwait(false); + var imported = await importer.Import(notification, new ImportTask(filename)).ConfigureAwait(false); // for now a failed import will be marked as a failed download for simplicity. if (!imported.Any()) @@ -103,7 +103,7 @@ namespace osu.Game.Database notification.State = ProgressNotificationState.Cancelled; if (!(error is OperationCanceledException)) - Logger.Error(error, $"{modelManager.HumanisedModelName.Titleize()} download failed!"); + Logger.Error(error, $"{importer.HumanisedModelName.Titleize()} download failed!"); } } diff --git a/osu.Game/Scoring/ScoreModelDownloader.cs b/osu.Game/Scoring/ScoreModelDownloader.cs index 52355585a9..bd14493ab7 100644 --- a/osu.Game/Scoring/ScoreModelDownloader.cs +++ b/osu.Game/Scoring/ScoreModelDownloader.cs @@ -10,7 +10,7 @@ namespace osu.Game.Scoring { public class ScoreModelDownloader : ModelDownloader { - public ScoreModelDownloader(ScoreModelManager scoreManager, IAPIProvider api, IIpcHost importHost = null) + public ScoreModelDownloader(IModelImporter scoreManager, IAPIProvider api, IIpcHost importHost = null) : base(scoreManager, api, importHost) { } From 99df37f32dca7102579e6b7acecaa451ba8854cf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 Nov 2021 16:51:48 +0900 Subject: [PATCH 7/8] Add input generic type to `IModelDownloader` --- osu.Game/Database/IModelDownloader.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Database/IModelDownloader.cs b/osu.Game/Database/IModelDownloader.cs index a5573b2190..8c1e454f0b 100644 --- a/osu.Game/Database/IModelDownloader.cs +++ b/osu.Game/Database/IModelDownloader.cs @@ -11,8 +11,9 @@ namespace osu.Game.Database /// Represents a that can download new models from an external source. /// /// The model type. - public interface IModelDownloader : IPostNotifications - where TModel : class + /// The model's interface type. + public interface IModelDownloader : IPostNotifications + where TModel : class, T { /// /// Fired when a download begins. @@ -32,7 +33,7 @@ namespace osu.Game.Database /// The to be downloaded. /// Whether this download should be optimised for slow connections. Generally means extras are not included in the download bundle.. /// Whether the download was started. - bool Download(TModel model, bool minimiseDownloadSize); + bool Download(T model, bool minimiseDownloadSize); /// /// Gets an existing download request if it exists. From 6c385ccd29bd7686a012519e5f369846c1419b1c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 Nov 2021 17:37:05 +0900 Subject: [PATCH 8/8] Move second generic to `abstract` model downloader rather than interface type --- ...eneOnlinePlayBeatmapAvailabilityTracker.cs | 6 ++-- osu.Game/Beatmaps/BeatmapManager.cs | 25 +++----------- osu.Game/Beatmaps/BeatmapModelDownloader.cs | 6 ++-- osu.Game/Database/IModelDownloader.cs | 29 ++++++++-------- osu.Game/Database/ModelDownloader.cs | 33 ++++++++++--------- .../API/Requests/DownloadBeatmapSetRequest.cs | 6 ++-- .../API/Requests/DownloadReplayRequest.cs | 6 ++-- osu.Game/Online/BeatmapDownloadTracker.cs | 12 +++---- osu.Game/Online/ScoreDownloadTracker.cs | 14 ++++---- osu.Game/Scoring/ScoreManager.cs | 14 ++++---- osu.Game/Scoring/ScoreModelDownloader.cs | 8 ++--- 11 files changed, 70 insertions(+), 89 deletions(-) diff --git a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs index 70e62cc087..e3e2304990 100644 --- a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs +++ b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs @@ -180,7 +180,7 @@ namespace osu.Game.Tests.Online { } - protected override ArchiveDownloadRequest CreateDownloadRequest(BeatmapSetInfo set, bool minimiseDownloadSize) + protected override ArchiveDownloadRequest CreateDownloadRequest(IBeatmapSetInfo set, bool minimiseDownloadSize) => new TestDownloadRequest(set); } @@ -202,12 +202,12 @@ namespace osu.Game.Tests.Online } } - private class TestDownloadRequest : ArchiveDownloadRequest + private class TestDownloadRequest : ArchiveDownloadRequest { public new void SetProgress(float progress) => base.SetProgress(progress); public new void TriggerSuccess(string filename) => base.TriggerSuccess(filename); - public TestDownloadRequest(BeatmapSetInfo model) + public TestDownloadRequest(IBeatmapSetInfo model) : base(model) { } diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 7e19057fb3..e0e5b5e63d 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -29,7 +29,7 @@ namespace osu.Game.Beatmaps /// Handles general operations related to global beatmap management. /// [ExcludeFromDynamicCompile] - public class BeatmapManager : IModelDownloader, IModelManager, IModelFileManager, IModelImporter, IWorkingBeatmapCache, IDisposable + public class BeatmapManager : IModelDownloader, IModelManager, IModelFileManager, IModelImporter, IWorkingBeatmapCache, IDisposable { private readonly BeatmapModelManager beatmapModelManager; private readonly BeatmapModelDownloader beatmapModelDownloader; @@ -246,33 +246,16 @@ namespace osu.Game.Beatmaps #region Implementation of IModelDownloader - public IBindable>> DownloadBegan => beatmapModelDownloader.DownloadBegan; + public IBindable>> DownloadBegan => beatmapModelDownloader.DownloadBegan; - public IBindable>> DownloadFailed => beatmapModelDownloader.DownloadFailed; + public IBindable>> DownloadFailed => beatmapModelDownloader.DownloadFailed; - // Temporary method until this class supports IBeatmapSetInfo or otherwise. public bool Download(IBeatmapSetInfo model, bool minimiseDownloadSize = false) - { - return beatmapModelDownloader.Download(new BeatmapSetInfo - { - OnlineBeatmapSetID = model.OnlineID, - Metadata = new BeatmapMetadata - { - Title = model.Metadata?.Title ?? string.Empty, - Artist = model.Metadata?.Artist ?? string.Empty, - TitleUnicode = model.Metadata?.TitleUnicode ?? string.Empty, - ArtistUnicode = model.Metadata?.ArtistUnicode ?? string.Empty, - Author = new User { Username = model.Metadata?.Author }, - } - }, minimiseDownloadSize); - } - - public bool Download(BeatmapSetInfo model, bool minimiseDownloadSize = false) { return beatmapModelDownloader.Download(model, minimiseDownloadSize); } - public ArchiveDownloadRequest GetExistingDownload(BeatmapSetInfo model) + public ArchiveDownloadRequest GetExistingDownload(IBeatmapSetInfo model) { return beatmapModelDownloader.GetExistingDownload(model); } diff --git a/osu.Game/Beatmaps/BeatmapModelDownloader.cs b/osu.Game/Beatmaps/BeatmapModelDownloader.cs index e708190b0e..a170edc9f8 100644 --- a/osu.Game/Beatmaps/BeatmapModelDownloader.cs +++ b/osu.Game/Beatmaps/BeatmapModelDownloader.cs @@ -8,12 +8,12 @@ using osu.Game.Online.API.Requests; namespace osu.Game.Beatmaps { - public class BeatmapModelDownloader : ModelDownloader + public class BeatmapModelDownloader : ModelDownloader { - protected override ArchiveDownloadRequest CreateDownloadRequest(BeatmapSetInfo set, bool minimiseDownloadSize) => + protected override ArchiveDownloadRequest CreateDownloadRequest(IBeatmapSetInfo set, bool minimiseDownloadSize) => new DownloadBeatmapSetRequest(set, minimiseDownloadSize); - public override ArchiveDownloadRequest GetExistingDownload(BeatmapSetInfo model) + public override ArchiveDownloadRequest GetExistingDownload(IBeatmapSetInfo model) => CurrentDownloads.Find(r => r.Model.OnlineID == model.OnlineID); public BeatmapModelDownloader(IModelImporter beatmapImporter, IAPIProvider api, GameHost host = null) diff --git a/osu.Game/Database/IModelDownloader.cs b/osu.Game/Database/IModelDownloader.cs index 8c1e454f0b..3c57a277ba 100644 --- a/osu.Game/Database/IModelDownloader.cs +++ b/osu.Game/Database/IModelDownloader.cs @@ -10,36 +10,35 @@ namespace osu.Game.Database /// /// Represents a that can download new models from an external source. /// - /// The model type. - /// The model's interface type. - public interface IModelDownloader : IPostNotifications - where TModel : class, T + /// The item's interface type. + public interface IModelDownloader : IPostNotifications + where T : class { /// - /// Fired when a download begins. + /// Fired when a download begins. /// This is NOT run on the update thread and should be scheduled. /// - IBindable>> DownloadBegan { get; } + IBindable>> DownloadBegan { get; } /// - /// Fired when a download is interrupted, either due to user cancellation or failure. + /// Fired when a download is interrupted, either due to user cancellation or failure. /// This is NOT run on the update thread and should be scheduled. /// - IBindable>> DownloadFailed { get; } + IBindable>> DownloadFailed { get; } /// - /// Begin a download for the requested . + /// Begin a download for the requested . /// - /// The to be downloaded. + /// The to be downloaded. /// Whether this download should be optimised for slow connections. Generally means extras are not included in the download bundle.. /// Whether the download was started. - bool Download(T model, bool minimiseDownloadSize); + bool Download(T item, bool minimiseDownloadSize); /// - /// Gets an existing download request if it exists. + /// Gets an existing download request if it exists. /// - /// The whose request is wanted. - /// The object if it exists, otherwise null. - ArchiveDownloadRequest GetExistingDownload(TModel model); + /// The whose request is wanted. + /// The object if it exists, otherwise null. + ArchiveDownloadRequest GetExistingDownload(T item); } } diff --git a/osu.Game/Database/ModelDownloader.cs b/osu.Game/Database/ModelDownloader.cs index a2a4209f1f..e44ae21ed6 100644 --- a/osu.Game/Database/ModelDownloader.cs +++ b/osu.Game/Database/ModelDownloader.cs @@ -14,23 +14,24 @@ using osu.Game.Overlays.Notifications; namespace osu.Game.Database { - public abstract class ModelDownloader : IModelDownloader - where TModel : class, IHasPrimaryKey, ISoftDelete, IEquatable + public abstract class ModelDownloader : IModelDownloader + where TModel : class, IHasPrimaryKey, ISoftDelete, IEquatable, T + where T : class { public Action PostNotification { protected get; set; } - public IBindable>> DownloadBegan => downloadBegan; + public IBindable>> DownloadBegan => downloadBegan; - private readonly Bindable>> downloadBegan = new Bindable>>(); + private readonly Bindable>> downloadBegan = new Bindable>>(); - public IBindable>> DownloadFailed => downloadFailed; + public IBindable>> DownloadFailed => downloadFailed; - private readonly Bindable>> downloadFailed = new Bindable>>(); + private readonly Bindable>> downloadFailed = new Bindable>>(); private readonly IModelImporter importer; private readonly IAPIProvider api; - protected readonly List> CurrentDownloads = new List>(); + protected readonly List> CurrentDownloads = new List>(); protected ModelDownloader(IModelImporter importer, IAPIProvider api, IIpcHost importHost = null) { @@ -39,14 +40,14 @@ namespace osu.Game.Database } /// - /// Creates the download request for this . + /// Creates the download request for this . /// - /// The to be downloaded. + /// The to be downloaded. /// Whether this download should be optimised for slow connections. Generally means extras are not included in the download bundle. /// The request object. - protected abstract ArchiveDownloadRequest CreateDownloadRequest(TModel model, bool minimiseDownloadSize); + protected abstract ArchiveDownloadRequest CreateDownloadRequest(T model, bool minimiseDownloadSize); - public bool Download(TModel model, bool minimiseDownloadSize = false) + public bool Download(T model, bool minimiseDownloadSize = false) { if (!canDownload(model)) return false; @@ -72,7 +73,7 @@ namespace osu.Game.Database // for now a failed import will be marked as a failed download for simplicity. if (!imported.Any()) - downloadFailed.Value = new WeakReference>(request); + downloadFailed.Value = new WeakReference>(request); CurrentDownloads.Remove(request); }, TaskCreationOptions.LongRunning); @@ -91,14 +92,14 @@ namespace osu.Game.Database api.PerformAsync(request); - downloadBegan.Value = new WeakReference>(request); + downloadBegan.Value = new WeakReference>(request); return true; void triggerFailure(Exception error) { CurrentDownloads.Remove(request); - downloadFailed.Value = new WeakReference>(request); + downloadFailed.Value = new WeakReference>(request); notification.State = ProgressNotificationState.Cancelled; @@ -107,9 +108,9 @@ namespace osu.Game.Database } } - public abstract ArchiveDownloadRequest GetExistingDownload(TModel model); + public abstract ArchiveDownloadRequest GetExistingDownload(T model); - private bool canDownload(TModel model) => GetExistingDownload(model) == null && api != null; + private bool canDownload(T model) => GetExistingDownload(model) == null && api != null; private class DownloadNotification : ProgressNotification { diff --git a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs index 2898955de7..5254dc3cf8 100644 --- a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs +++ b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs @@ -6,11 +6,11 @@ using osu.Game.Beatmaps; namespace osu.Game.Online.API.Requests { - public class DownloadBeatmapSetRequest : ArchiveDownloadRequest + public class DownloadBeatmapSetRequest : ArchiveDownloadRequest { private readonly bool noVideo; - public DownloadBeatmapSetRequest(BeatmapSetInfo set, bool noVideo) + public DownloadBeatmapSetRequest(IBeatmapSetInfo set, bool noVideo) : base(set) { this.noVideo = noVideo; @@ -25,6 +25,6 @@ namespace osu.Game.Online.API.Requests protected override string FileExtension => ".osz"; - protected override string Target => $@"beatmapsets/{Model.OnlineBeatmapSetID}/download{(noVideo ? "?noVideo=1" : "")}"; + protected override string Target => $@"beatmapsets/{Model.OnlineID}/download{(noVideo ? "?noVideo=1" : "")}"; } } diff --git a/osu.Game/Online/API/Requests/DownloadReplayRequest.cs b/osu.Game/Online/API/Requests/DownloadReplayRequest.cs index 6fd052653d..77174f0bb5 100644 --- a/osu.Game/Online/API/Requests/DownloadReplayRequest.cs +++ b/osu.Game/Online/API/Requests/DownloadReplayRequest.cs @@ -5,15 +5,15 @@ using osu.Game.Scoring; namespace osu.Game.Online.API.Requests { - public class DownloadReplayRequest : ArchiveDownloadRequest + public class DownloadReplayRequest : ArchiveDownloadRequest { - public DownloadReplayRequest(ScoreInfo score) + public DownloadReplayRequest(IScoreInfo score) : base(score) { } protected override string FileExtension => ".osr"; - protected override string Target => $@"scores/{Model.Ruleset.ShortName}/{Model.OnlineScoreID}/download"; + protected override string Target => $@"scores/{Model.Ruleset.ShortName}/{Model.OnlineID}/download"; } } diff --git a/osu.Game/Online/BeatmapDownloadTracker.cs b/osu.Game/Online/BeatmapDownloadTracker.cs index 4a7d0b660a..12cbcdbec7 100644 --- a/osu.Game/Online/BeatmapDownloadTracker.cs +++ b/osu.Game/Online/BeatmapDownloadTracker.cs @@ -16,7 +16,7 @@ namespace osu.Game.Online [Resolved(CanBeNull = true)] protected BeatmapManager? Manager { get; private set; } - private ArchiveDownloadRequest? attachedRequest; + private ArchiveDownloadRequest? attachedRequest; public BeatmapDownloadTracker(IBeatmapSetInfo trackedItem) : base(trackedItem) @@ -25,8 +25,8 @@ namespace osu.Game.Online private IBindable>? managerUpdated; private IBindable>? managerRemoved; - private IBindable>>? managerDownloadBegan; - private IBindable>>? managerDownloadFailed; + private IBindable>>? managerDownloadBegan; + private IBindable>>? managerDownloadFailed; [BackgroundDependencyLoader(true)] private void load() @@ -52,7 +52,7 @@ namespace osu.Game.Online managerRemoved.BindValueChanged(itemRemoved); } - private void downloadBegan(ValueChangedEvent>> weakRequest) + private void downloadBegan(ValueChangedEvent>> weakRequest) { if (weakRequest.NewValue.TryGetTarget(out var request)) { @@ -64,7 +64,7 @@ namespace osu.Game.Online } } - private void downloadFailed(ValueChangedEvent>> weakRequest) + private void downloadFailed(ValueChangedEvent>> weakRequest) { if (weakRequest.NewValue.TryGetTarget(out var request)) { @@ -76,7 +76,7 @@ namespace osu.Game.Online } } - private void attachDownload(ArchiveDownloadRequest? request) + private void attachDownload(ArchiveDownloadRequest? request) { if (attachedRequest != null) { diff --git a/osu.Game/Online/ScoreDownloadTracker.cs b/osu.Game/Online/ScoreDownloadTracker.cs index e679071ac1..9ea6d5b79a 100644 --- a/osu.Game/Online/ScoreDownloadTracker.cs +++ b/osu.Game/Online/ScoreDownloadTracker.cs @@ -16,7 +16,7 @@ namespace osu.Game.Online [Resolved(CanBeNull = true)] protected ScoreManager? Manager { get; private set; } - private ArchiveDownloadRequest? attachedRequest; + private ArchiveDownloadRequest? attachedRequest; public ScoreDownloadTracker(ScoreInfo trackedItem) : base(trackedItem) @@ -25,8 +25,8 @@ namespace osu.Game.Online private IBindable>? managerUpdated; private IBindable>? managerRemoved; - private IBindable>>? managerDownloadBegan; - private IBindable>>? managerDownloadFailed; + private IBindable>>? managerDownloadBegan; + private IBindable>>? managerDownloadFailed; [BackgroundDependencyLoader(true)] private void load() @@ -56,7 +56,7 @@ namespace osu.Game.Online managerRemoved.BindValueChanged(itemRemoved); } - private void downloadBegan(ValueChangedEvent>> weakRequest) + private void downloadBegan(ValueChangedEvent>> weakRequest) { if (weakRequest.NewValue.TryGetTarget(out var request)) { @@ -68,7 +68,7 @@ namespace osu.Game.Online } } - private void downloadFailed(ValueChangedEvent>> weakRequest) + private void downloadFailed(ValueChangedEvent>> weakRequest) { if (weakRequest.NewValue.TryGetTarget(out var request)) { @@ -80,7 +80,7 @@ namespace osu.Game.Online } } - private void attachDownload(ArchiveDownloadRequest? request) + private void attachDownload(ArchiveDownloadRequest? request) { if (attachedRequest != null) { @@ -144,7 +144,7 @@ namespace osu.Game.Online } } - private bool checkEquality(ScoreInfo x, ScoreInfo y) => x.OnlineScoreID == y.OnlineScoreID; + private bool checkEquality(IScoreInfo x, IScoreInfo y) => x.OnlineID == y.OnlineID; #region Disposal diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index 380d2590bf..676baf511a 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -25,7 +25,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Scoring { - public class ScoreManager : IModelManager, IModelImporter, IModelFileManager, IModelDownloader + public class ScoreManager : IModelManager, IModelImporter, IModelFileManager, IModelDownloader { private readonly Scheduler scheduler; private readonly Func difficulties; @@ -350,16 +350,14 @@ namespace osu.Game.Scoring #region Implementation of IModelDownloader - public IBindable>> DownloadBegan => scoreModelDownloader.DownloadBegan; + public IBindable>> DownloadBegan => scoreModelDownloader.DownloadBegan; - public IBindable>> DownloadFailed => scoreModelDownloader.DownloadFailed; + public IBindable>> DownloadFailed => scoreModelDownloader.DownloadFailed; - public bool Download(ScoreInfo model, bool minimiseDownloadSize) - { - return scoreModelDownloader.Download(model, minimiseDownloadSize); - } + public bool Download(IScoreInfo model, bool minimiseDownloadSize) => + scoreModelDownloader.Download(model, minimiseDownloadSize); - public ArchiveDownloadRequest GetExistingDownload(ScoreInfo model) + public ArchiveDownloadRequest GetExistingDownload(IScoreInfo model) { return scoreModelDownloader.GetExistingDownload(model); } diff --git a/osu.Game/Scoring/ScoreModelDownloader.cs b/osu.Game/Scoring/ScoreModelDownloader.cs index bd14493ab7..6c63e2aa71 100644 --- a/osu.Game/Scoring/ScoreModelDownloader.cs +++ b/osu.Game/Scoring/ScoreModelDownloader.cs @@ -8,16 +8,16 @@ using osu.Game.Online.API.Requests; namespace osu.Game.Scoring { - public class ScoreModelDownloader : ModelDownloader + public class ScoreModelDownloader : ModelDownloader { public ScoreModelDownloader(IModelImporter scoreManager, IAPIProvider api, IIpcHost importHost = null) : base(scoreManager, api, importHost) { } - protected override ArchiveDownloadRequest CreateDownloadRequest(ScoreInfo score, bool minimiseDownload) => new DownloadReplayRequest(score); + protected override ArchiveDownloadRequest CreateDownloadRequest(IScoreInfo score, bool minimiseDownload) => new DownloadReplayRequest(score); - public override ArchiveDownloadRequest GetExistingDownload(ScoreInfo model) - => CurrentDownloads.Find(r => r.Model.OnlineScoreID == model.OnlineScoreID); + public override ArchiveDownloadRequest GetExistingDownload(IScoreInfo model) + => CurrentDownloads.Find(r => r.Model.OnlineID == model.OnlineID); } }