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

Make BeatmapManager inherit from new base class

This commit is contained in:
naoey 2019-06-11 19:36:08 +05:30
parent b4de51b612
commit 341d137f5c
No known key found for this signature in database
GPG Key ID: 670DA9BE3DF7EE60
5 changed files with 25 additions and 133 deletions

View File

@ -27,7 +27,7 @@ namespace osu.Game.Beatmaps
/// <summary> /// <summary>
/// Handles the storage and retrieval of Beatmaps/WorkingBeatmaps. /// Handles the storage and retrieval of Beatmaps/WorkingBeatmaps.
/// </summary> /// </summary>
public partial class BeatmapManager : ArchiveModelManager<BeatmapSetInfo, BeatmapSetFileInfo> public partial class BeatmapManager : ArchiveDownloadModelManager<BeatmapSetInfo, BeatmapSetFileInfo, DownloadBeatmapSetRequest>
{ {
/// <summary> /// <summary>
/// Fired when a single difficulty has been hidden. /// Fired when a single difficulty has been hidden.
@ -39,16 +39,6 @@ namespace osu.Game.Beatmaps
/// </summary> /// </summary>
public event Action<BeatmapInfo> BeatmapRestored; public event Action<BeatmapInfo> BeatmapRestored;
/// <summary>
/// Fired when a beatmap download begins.
/// </summary>
public event Action<DownloadBeatmapSetRequest> BeatmapDownloadBegan;
/// <summary>
/// Fired when a beatmap download is interrupted, due to user cancellation or other failures.
/// </summary>
public event Action<DownloadBeatmapSetRequest> BeatmapDownloadFailed;
/// <summary> /// <summary>
/// A default representation of a WorkingBeatmap to use when no beatmap is available. /// A default representation of a WorkingBeatmap to use when no beatmap is available.
/// </summary> /// </summary>
@ -74,7 +64,7 @@ namespace osu.Game.Beatmaps
public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, AudioManager audioManager, GameHost host = null, public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, AudioManager audioManager, GameHost host = null,
WorkingBeatmap defaultBeatmap = null) WorkingBeatmap defaultBeatmap = null)
: base(storage, contextFactory, new BeatmapStore(contextFactory), host) : base(storage, contextFactory, api, new BeatmapStore(contextFactory), host)
{ {
this.rulesets = rulesets; this.rulesets = rulesets;
this.api = api; this.api = api;
@ -88,6 +78,8 @@ namespace osu.Game.Beatmaps
beatmaps.BeatmapRestored += b => BeatmapRestored?.Invoke(b); beatmaps.BeatmapRestored += b => BeatmapRestored?.Invoke(b);
} }
protected override DownloadBeatmapSetRequest CreateDownloadRequest(BeatmapSetInfo set) => new DownloadBeatmapSetRequest(set, false);
protected override void Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive) protected override void Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive)
{ {
if (archive != null) if (archive != null)
@ -153,87 +145,6 @@ namespace osu.Game.Beatmaps
void resetIds() => beatmapSet.Beatmaps.ForEach(b => b.OnlineBeatmapID = null); void resetIds() => beatmapSet.Beatmaps.ForEach(b => b.OnlineBeatmapID = null);
} }
/// <summary>
/// Downloads a beatmap.
/// This will post notifications tracking progress.
/// </summary>
/// <param name="beatmapSetInfo">The <see cref="BeatmapSetInfo"/> to be downloaded.</param>
/// <param name="noVideo">Whether the beatmap should be downloaded without video. Defaults to false.</param>
/// <returns>Downloading can happen</returns>
public bool Download(BeatmapSetInfo beatmapSetInfo, bool noVideo = false)
{
var existing = GetExistingDownload(beatmapSetInfo);
if (existing != null || api == null) return false;
var downloadNotification = new DownloadNotification
{
Text = $"Downloading {beatmapSetInfo}",
};
var request = new DownloadBeatmapSetRequest(beatmapSetInfo, noVideo);
request.DownloadProgressed += progress =>
{
downloadNotification.State = ProgressNotificationState.Active;
downloadNotification.Progress = progress;
};
request.Success += filename =>
{
Task.Factory.StartNew(() =>
{
// This gets scheduled back to the update thread, but we want the import to run in the background.
Import(downloadNotification, filename);
currentDownloads.Remove(request);
}, TaskCreationOptions.LongRunning);
};
request.Failure += error =>
{
BeatmapDownloadFailed?.Invoke(request);
if (error is OperationCanceledException) return;
downloadNotification.State = ProgressNotificationState.Cancelled;
Logger.Error(error, "Beatmap download failed!");
currentDownloads.Remove(request);
};
downloadNotification.CancelRequested += () =>
{
request.Cancel();
currentDownloads.Remove(request);
downloadNotification.State = ProgressNotificationState.Cancelled;
return true;
};
currentDownloads.Add(request);
PostNotification?.Invoke(downloadNotification);
// don't run in the main api queue as this is a long-running task.
Task.Factory.StartNew(() =>
{
try
{
request.Perform(api);
}
catch
{
// no need to handle here as exceptions will filter down to request.Failure above.
}
}, TaskCreationOptions.LongRunning);
BeatmapDownloadBegan?.Invoke(request);
return true;
}
/// <summary>
/// Get an existing download request if it exists.
/// </summary>
/// <param name="beatmap">The <see cref="BeatmapSetInfo"/> whose download request is wanted.</param>
/// <returns>The <see cref="DownloadBeatmapSetRequest"/> object if it exists, or null.</returns>
public DownloadBeatmapSetRequest GetExistingDownload(BeatmapSetInfo beatmap) => currentDownloads.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID);
/// <summary> /// <summary>
/// Delete a beatmap difficulty. /// Delete a beatmap difficulty.
/// </summary> /// </summary>
@ -439,21 +350,5 @@ namespace osu.Game.Beatmaps
protected override Texture GetBackground() => null; protected override Texture GetBackground() => null;
protected override Track GetTrack() => null; protected override Track GetTrack() => null;
} }
private class DownloadNotification : ProgressNotification
{
public override bool IsImportant => false;
protected override Notification CreateCompletionNotification() => new SilencedProgressCompletionNotification
{
Activated = CompletionClickAction,
Text = CompletionText
};
private class SilencedProgressCompletionNotification : ProgressCompletionNotification
{
public override bool IsImportant => false;
}
}
} }
} }

View File

@ -31,17 +31,26 @@ namespace osu.Game.Database
public bool Download(TModel model) public bool Download(TModel model)
{ {
var existing = GetExistingDownload(model); if (!canDownload(model)) return false;
if (existing != null || api == null) return false;
DownloadNotification notification = new DownloadNotification
{
Text = $"Downloading {model}",
};
var request = CreateDownloadRequest(model); var request = CreateDownloadRequest(model);
performDownloadWithRequest(request);
return true;
}
public TDownloadRequestModel GetExistingDownload(TModel model) => currentDownloads.Find(r => r.Info.Equals(model));
private bool canDownload(TModel model) => GetExistingDownload(model) == null && api != null;
private void performDownloadWithRequest(TDownloadRequestModel request)
{
DownloadNotification notification = new DownloadNotification
{
Text = $"Downloading {request.Info}",
};
request.DownloadProgressed += progress => request.DownloadProgressed += progress =>
{ {
notification.State = ProgressNotificationState.Active; notification.State = ProgressNotificationState.Active;
@ -92,12 +101,8 @@ namespace osu.Game.Database
}, TaskCreationOptions.LongRunning); }, TaskCreationOptions.LongRunning);
DownloadBegan?.Invoke(request); DownloadBegan?.Invoke(request);
return true;
} }
public TDownloadRequestModel GetExistingDownload(TModel model) => currentDownloads.Find(r => r.Info.Equals(model));
private class DownloadNotification : ProgressNotification private class DownloadNotification : ProgressNotification
{ {
public override bool IsImportant => false; public override bool IsImportant => false;

View File

@ -1,6 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Text;
namespace osu.Game.Online.API namespace osu.Game.Online.API
{ {

View File

@ -2,26 +2,20 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using System;
namespace osu.Game.Online.API.Requests namespace osu.Game.Online.API.Requests
{ {
public class DownloadBeatmapSetRequest : APIDownloadRequest public class DownloadBeatmapSetRequest : ArchiveDownloadModelRequest<BeatmapSetInfo>
{ {
public readonly BeatmapSetInfo BeatmapSet; public readonly BeatmapSetInfo BeatmapSet;
public float Progress;
public event Action<float> DownloadProgressed;
private readonly bool noVideo; private readonly bool noVideo;
public DownloadBeatmapSetRequest(BeatmapSetInfo set, bool noVideo) public DownloadBeatmapSetRequest(BeatmapSetInfo set, bool noVideo)
: base(set)
{ {
this.noVideo = noVideo; this.noVideo = noVideo;
BeatmapSet = set; BeatmapSet = set;
Progressed += (current, total) => DownloadProgressed?.Invoke(Progress = (float)current / total);
} }
protected override string Target => $@"beatmapsets/{BeatmapSet.OnlineBeatmapSetID}/download{(noVideo ? "?noVideo=1" : "")}"; protected override string Target => $@"beatmapsets/{BeatmapSet.OnlineBeatmapSetID}/download{(noVideo ? "?noVideo=1" : "")}";

View File

@ -47,7 +47,7 @@ namespace osu.Game.Overlays.Direct
attachDownload(beatmaps.GetExistingDownload(setInfo.NewValue)); attachDownload(beatmaps.GetExistingDownload(setInfo.NewValue));
}, true); }, true);
beatmaps.BeatmapDownloadBegan += download => beatmaps.DownloadBegan += download =>
{ {
if (download.BeatmapSet.OnlineBeatmapSetID == BeatmapSet.Value?.OnlineBeatmapSetID) if (download.BeatmapSet.OnlineBeatmapSetID == BeatmapSet.Value?.OnlineBeatmapSetID)
attachDownload(download); attachDownload(download);
@ -65,7 +65,7 @@ namespace osu.Game.Overlays.Direct
if (beatmaps != null) if (beatmaps != null)
{ {
beatmaps.BeatmapDownloadBegan -= attachDownload; beatmaps.DownloadBegan -= attachDownload;
beatmaps.ItemAdded -= setAdded; beatmaps.ItemAdded -= setAdded;
} }