1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-13 17:43:21 +08:00

use Live<TModel>

Use RealmAccess only when needed
This commit is contained in:
cdwcgt 2023-04-09 22:15:00 +09:00
parent 1f4da35c8d
commit de21b4a2f7
No known key found for this signature in database
GPG Key ID: 144396D01095C3A2
10 changed files with 42 additions and 35 deletions

View File

@ -119,10 +119,7 @@ namespace osu.Game.Tests.Skins.IO
var import1 = await loadSkinIntoOsu(osu, new ImportTask(createOskWithIni("name 1", "author 1"), "custom.osk"));
assertCorrectMetadata(import1, "name 1 [custom]", "author 1", osu);
await import1.PerformRead(async s =>
{
await new LegacySkinExporter(osu.Dependencies.Get<Storage>(), osu.Dependencies.Get<RealmAccess>()).ExportToStreamAsync(s, exportStream);
});
await new LegacySkinExporter(osu.Dependencies.Get<Storage>()).ExportToStreamAsync(import1, exportStream);
string exportFilename = import1.GetDisplayString();
@ -203,7 +200,7 @@ namespace osu.Game.Tests.Skins.IO
Assert.IsFalse(s.Protected);
Assert.AreEqual(typeof(ArgonSkin), s.CreateInstance(skinManager).GetType());
await new LegacySkinExporter(osu.Dependencies.Get<Storage>(), osu.Dependencies.Get<RealmAccess>()).ExportToStreamAsync(s, exportStream);
await new LegacySkinExporter(osu.Dependencies.Get<Storage>()).ExportToStreamAsync(skinManager.CurrentSkinInfo.Value, exportStream);
Assert.Greater(exportStream.Length, 0);
});
@ -236,7 +233,7 @@ namespace osu.Game.Tests.Skins.IO
Assert.IsFalse(s.Protected);
Assert.AreEqual(typeof(DefaultLegacySkin), s.CreateInstance(skinManager).GetType());
await new LegacySkinExporter(osu.Dependencies.Get<Storage>(), osu.Dependencies.Get<RealmAccess>()).ExportToStreamAsync(s, exportStream);
await new LegacySkinExporter(osu.Dependencies.Get<Storage>()).ExportToStreamAsync(skinManager.CurrentSkinInfo.Value, exportStream);
Assert.Greater(exportStream.Length, 0);
});

View File

@ -79,7 +79,7 @@ namespace osu.Game.Beatmaps
workingBeatmapCache = CreateWorkingBeatmapCache(audioManager, gameResources, userResources, defaultBeatmap, host);
beatmapExporter = new LegacyBeatmapExporter(storage, realm)
beatmapExporter = new LegacyBeatmapExporter(storage)
{
PostNotification = obj => PostNotification?.Invoke(obj)
};
@ -400,7 +400,7 @@ namespace osu.Game.Beatmaps
public Task<Live<BeatmapSetInfo>?> ImportAsUpdate(ProgressNotification notification, ImportTask importTask, BeatmapSetInfo original) =>
beatmapImporter.ImportAsUpdate(notification, importTask, original);
public Task Export(BeatmapSetInfo beatmap) => beatmapExporter.ExportAsync(beatmap);
public Task Export(BeatmapSetInfo beatmap) => beatmapExporter.ExportAsync(beatmap, Realm);
private void updateHashAndMarkDirty(BeatmapSetInfo setInfo)
{

View File

@ -20,8 +20,8 @@ namespace osu.Game.Database
public abstract class LegacyArchiveExporter<TModel> : LegacyModelExporter<TModel>
where TModel : RealmObject, IHasNamedFiles, IHasGuidPrimaryKey
{
protected LegacyArchiveExporter(Storage storage, RealmAccess realm)
: base(storage, realm)
protected LegacyArchiveExporter(Storage storage)
: base(storage)
{
}

View File

@ -8,8 +8,8 @@ namespace osu.Game.Database
{
public class LegacyBeatmapExporter : LegacyArchiveExporter<BeatmapSetInfo>
{
public LegacyBeatmapExporter(Storage storage, RealmAccess realm)
: base(storage, realm)
public LegacyBeatmapExporter(Storage storage)
: base(storage)
{
}

View File

@ -31,24 +31,35 @@ namespace osu.Game.Database
private readonly Storage exportStorage;
protected virtual string GetFilename(TModel item) => item.GetDisplayString();
private readonly RealmAccess realmAccess;
public Action<Notification>? PostNotification { get; set; }
// Store the model being exporting.
private static readonly List<TModel> exporting_models = new List<TModel>();
private static readonly List<Live<TModel>> exporting_models = new List<Live<TModel>>();
/// <summary>
/// Construct exporter.
/// Create a new exporter for each export, otherwise it will cause confusing notifications.
/// </summary>
/// <param name="storage">Storage for storing exported files. Basically it is used to provide export stream</param>
/// <param name="realm">The RealmAccess used to provide the exported file.</param>
protected LegacyModelExporter(Storage storage, RealmAccess realm)
protected LegacyModelExporter(Storage storage)
{
exportStorage = storage.GetStorageForDirectory(@"exports");
UserFileStorage = storage.GetStorageForDirectory(@"files");
realmAccess = realm;
}
/// <summary>
/// Export the model to default folder.
/// </summary>
/// <param name="model">The model should export.</param>
/// <param name="realm">Realm that convert model to Live.</param>
/// <param name="cancellationToken">
/// The Cancellation token that can cancel the exporting.
/// If specified CancellationToken, then use it. Otherwise use PostNotification's CancellationToken.
/// </param>
/// <returns></returns>
public Task<bool> ExportAsync(TModel model, RealmAccess realm, CancellationToken cancellationToken = default)
{
return ExportAsync(model.ToLive(realm), cancellationToken);
}
/// <summary>
@ -60,7 +71,7 @@ namespace osu.Game.Database
/// If specified CancellationToken, then use it. Otherwise use PostNotification's CancellationToken.
/// </param>
/// <returns></returns>
public async Task<bool> ExportAsync(TModel model, CancellationToken cancellationToken = default)
public async Task<bool> ExportAsync(Live<TModel> model, CancellationToken cancellationToken = default)
{
// check if the model is being exporting already
if (!exporting_models.Contains(model))
@ -73,7 +84,8 @@ namespace osu.Game.Database
return false;
}
string itemFilename = GetFilename(model).GetValidFilename();
string itemFilename = model.PerformRead(s => GetFilename(s).GetValidFilename());
IEnumerable<string> existingExports =
exportStorage
.GetFiles(string.Empty, $"{itemFilename}*{FileExtension}")
@ -128,15 +140,13 @@ namespace osu.Game.Database
/// <param name="notification">The notification will displayed to the user</param>
/// <param name="cancellationToken">The Cancellation token that can cancel the exporting.</param>
/// <returns>Whether the export was successful</returns>
public Task<bool> ExportToStreamAsync(TModel model, Stream stream, ProgressNotification? notification = null, CancellationToken cancellationToken = default)
public Task<bool> ExportToStreamAsync(Live<TModel> model, Stream stream, ProgressNotification? notification = null, CancellationToken cancellationToken = default)
{
Guid id = model.ID;
return Task.Run(() =>
{
realmAccess.Run(r =>
model.PerformRead(s =>
{
TModel refetchModel = r.Find<TModel>(id);
ExportToStream(refetchModel, stream, notification, cancellationToken);
ExportToStream(s, stream, notification, cancellationToken);
});
}, cancellationToken).ContinueWith(t =>
{

View File

@ -13,8 +13,7 @@ namespace osu.Game.Database
{
public class LegacyScoreExporter : LegacyModelExporter<ScoreInfo>
{
public LegacyScoreExporter(Storage storage, RealmAccess realm)
: base(storage, realm)
public LegacyScoreExporter(Storage storage) : base(storage)
{
}
@ -28,7 +27,7 @@ namespace osu.Game.Database
protected override string FileExtension => ".osr";
protected override void ExportToStream(ScoreInfo model, Stream stream, ProgressNotification notification, CancellationToken cancellationToken = default)
protected override void ExportToStream(ScoreInfo model, Stream stream, ProgressNotification? notification, CancellationToken cancellationToken = default)
{
var file = model.Files.SingleOrDefault();
if (file == null)

View File

@ -8,8 +8,7 @@ namespace osu.Game.Database
{
public class LegacySkinExporter : LegacyArchiveExporter<SkinInfo>
{
public LegacySkinExporter(Storage storage, RealmAccess realm)
: base(storage, realm)
public LegacySkinExporter(Storage storage) : base(storage)
{
}

View File

@ -159,7 +159,7 @@ namespace osu.Game.Overlays.Settings.Sections
{
try
{
skins.CurrentSkinInfo.Value.PerformRead(s => skins.ExportSkin(s));
skins.ExportCurrentSkin();
}
catch (Exception e)
{

View File

@ -50,7 +50,7 @@ namespace osu.Game.Scoring
PostNotification = obj => PostNotification?.Invoke(obj)
};
scoreExporter = new LegacyScoreExporter(storage, realm)
scoreExporter = new LegacyScoreExporter(storage)
{
PostNotification = obj => PostNotification?.Invoke(obj)
};
@ -193,7 +193,7 @@ namespace osu.Game.Scoring
public Task<IEnumerable<Live<ScoreInfo>>> Import(ProgressNotification notification, ImportTask[] tasks, ImportParameters parameters = default) => scoreImporter.Import(notification, tasks);
public Task Export(ScoreInfo score) => scoreExporter.ExportAsync(score);
public Task Export(ScoreInfo score) => scoreExporter.ExportAsync(score, Realm);
public Task<Live<ScoreInfo>> ImportAsUpdate(ProgressNotification notification, ImportTask task, ScoreInfo original) => scoreImporter.ImportAsUpdate(notification, task, original);

View File

@ -123,7 +123,7 @@ namespace osu.Game.Skinning
SourceChanged?.Invoke();
};
skinExporter = new LegacySkinExporter(storage, realm)
skinExporter = new LegacySkinExporter(storage)
{
PostNotification = obj => PostNotification?.Invoke(obj)
};
@ -305,7 +305,9 @@ namespace osu.Game.Skinning
public Task<Live<SkinInfo>> Import(ImportTask task, ImportParameters parameters = default, CancellationToken cancellationToken = default) =>
skinImporter.Import(task, parameters, cancellationToken);
public Task ExportSkin(SkinInfo skin) => skinExporter.ExportAsync(skin);
public Task ExportCurrentSkin() => ExportSkin(CurrentSkinInfo.Value);
public Task ExportSkin(Live<SkinInfo> skin) => skinExporter.ExportAsync(skin);
#endregion