1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-28 06:03:08 +08:00

Create a generic base archive download manager class

This commit is contained in:
naoey 2019-06-11 18:29:33 +05:30
parent 5c2c4f0ada
commit b4de51b612
No known key found for this signature in database
GPG Key ID: 670DA9BE3DF7EE60
2 changed files with 140 additions and 0 deletions

View File

@ -0,0 +1,117 @@
using osu.Framework.Logging;
using osu.Framework.Platform;
using osu.Game.Online.API;
using osu.Game.Overlays.Notifications;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace osu.Game.Database
{
public abstract class ArchiveDownloadModelManager<TModel, TFileModel, TDownloadRequestModel> : ArchiveModelManager<TModel, TFileModel>
where TModel : class, IHasFiles<TFileModel>, IHasPrimaryKey, ISoftDelete
where TFileModel : INamedFileInfo, new()
where TDownloadRequestModel : ArchiveDownloadModelRequest<TModel>
{
public event Action<TDownloadRequestModel> DownloadBegan;
public event Action<TDownloadRequestModel> DownloadFailed;
private readonly IAPIProvider api;
private readonly List<TDownloadRequestModel> currentDownloads = new List<TDownloadRequestModel>();
protected ArchiveDownloadModelManager(Storage storage, IDatabaseContextFactory contextFactory, IAPIProvider api, MutableDatabaseBackedStoreWithFileIncludes<TModel, TFileModel> modelStore, IIpcHost importHost = null)
:base(storage, contextFactory, modelStore, importHost)
{
this.api = api;
}
protected abstract TDownloadRequestModel CreateDownloadRequest(TModel model);
public bool Download(TModel model)
{
var existing = GetExistingDownload(model);
if (existing != null || api == null) return false;
DownloadNotification notification = new DownloadNotification
{
Text = $"Downloading {model}",
};
var request = CreateDownloadRequest(model);
request.DownloadProgressed += progress =>
{
notification.State = ProgressNotificationState.Active;
notification.Progress = progress;
};
request.Success += filename =>
{
Task.Factory.StartNew(() =>
{
Import(notification, filename);
currentDownloads.Remove(request);
}, TaskCreationOptions.LongRunning);
};
request.Failure += error =>
{
DownloadFailed?.Invoke(request);
if (error is OperationCanceledException) return;
notification.State = ProgressNotificationState.Cancelled;
// TODO: implement a Name for every model that we can use in this message
Logger.Error(error, "Download failed!");
currentDownloads.Remove(request);
};
notification.CancelRequested += () =>
{
request.Cancel();
currentDownloads.Remove(request);
notification.State = ProgressNotificationState.Cancelled;
return true;
};
currentDownloads.Add(request);
PostNotification?.Invoke(notification);
Task.Factory.StartNew(() =>
{
try
{
request.Perform(api);
}
catch
{
}
}, TaskCreationOptions.LongRunning);
DownloadBegan?.Invoke(request);
return true;
}
public TDownloadRequestModel GetExistingDownload(TModel model) => currentDownloads.Find(r => r.Info.Equals(model));
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

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace osu.Game.Online.API
{
public abstract class ArchiveDownloadModelRequest<TModel> : APIDownloadRequest
where TModel : class
{
public readonly TModel Info;
public float Progress;
public event Action<float> DownloadProgressed;
protected ArchiveDownloadModelRequest(TModel model)
{
Info = model;
Progressed += (current, total) => DownloadProgressed?.Invoke(Progress = (float)current / total);
}
}
}