1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-12 11:42:54 +08:00

Remove RealmArchiveModelManager from hierarchy

This commit is contained in:
Dean Herbert 2022-06-16 18:53:13 +09:00
parent 8a5755ca52
commit f3984d98e6
10 changed files with 69 additions and 165 deletions

View File

@ -38,7 +38,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using (var importer = new BeatmapImporter(realm, storage))
using (var importer = new BeatmapImporter(storage, realm))
using (new RealmRulesetStore(realm, storage))
{
Live<BeatmapSetInfo>? beatmapSet;
@ -82,7 +82,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using (var importer = new BeatmapImporter(realm, storage))
using (var importer = new BeatmapImporter(storage, realm))
using (new RealmRulesetStore(realm, storage))
{
Live<BeatmapSetInfo>? beatmapSet;
@ -141,7 +141,9 @@ namespace osu.Game.Tests.Database
{
BeatmapSetInfo? detachedSet = null;
using (var importer = new BeatmapImporter(realm, storage))
var manager = new ModelManager<BeatmapSetInfo>(storage, realm);
using (var importer = new BeatmapImporter(storage, realm))
using (new RealmRulesetStore(realm, storage))
{
Task.Run(async () =>
@ -160,7 +162,7 @@ namespace osu.Game.Tests.Database
}).WaitSafely();
Debug.Assert(detachedSet != null);
importer.AddFile(detachedSet, new MemoryStream(), "test");
manager.AddFile(detachedSet, new MemoryStream(), "test");
}
});
}
@ -170,7 +172,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using (var importer = new BeatmapImporter(realm, storage))
using (var importer = new BeatmapImporter(storage, realm))
using (new RealmRulesetStore(realm, storage))
{
Live<BeatmapSetInfo>? imported;
@ -202,7 +204,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
await LoadOszIntoStore(importer, realm.Realm);
@ -214,7 +216,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
var imported = await LoadOszIntoStore(importer, realm.Realm);
@ -232,7 +234,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
var imported = await LoadOszIntoStore(importer, realm.Realm);
@ -246,7 +248,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
string? tempPath = TestResources.GetTestBeatmapForImport();
@ -276,7 +278,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
var imported = await LoadOszIntoStore(importer, realm.Realm);
@ -296,7 +298,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
string? temp = TestResources.GetTestBeatmapForImport();
@ -345,7 +347,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
string? temp = TestResources.GetTestBeatmapForImport();
@ -396,7 +398,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
string? temp = TestResources.GetTestBeatmapForImport();
@ -444,7 +446,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
string? temp = TestResources.GetTestBeatmapForImport();
@ -492,7 +494,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
var imported = await LoadOszIntoStore(importer, realm.Realm);
@ -527,7 +529,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
var progressNotification = new ImportProgressNotification();
@ -565,7 +567,7 @@ namespace osu.Game.Tests.Database
Interlocked.Increment(ref loggedExceptionCount);
};
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
var imported = await LoadOszIntoStore(importer, realm.Realm);
@ -617,7 +619,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
var imported = await LoadOszIntoStore(importer, realm.Realm, batchImport: true);
@ -644,7 +646,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realmFactory, storage) =>
{
using var importer = new BeatmapImporter(realmFactory, storage);
using var importer = new BeatmapImporter(storage, realmFactory);
using var store = new RealmRulesetStore(realmFactory, storage);
var imported = await LoadOszIntoStore(importer, realmFactory.Realm);
@ -676,7 +678,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
var imported = await LoadOszIntoStore(importer, realm.Realm);
@ -703,7 +705,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
var imported = await LoadOszIntoStore(importer, realm.Realm);
@ -729,7 +731,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealm((realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
var metadata = new BeatmapMetadata
@ -777,7 +779,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
string? temp = TestResources.GetTestBeatmapForImport();
@ -794,7 +796,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
string? temp = TestResources.GetTestBeatmapForImport();
@ -830,7 +832,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
string? temp = TestResources.GetTestBeatmapForImport();
@ -872,7 +874,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
string? temp = TestResources.GetTestBeatmapForImport();
@ -923,7 +925,7 @@ namespace osu.Game.Tests.Database
{
RunTestWithRealmAsync(async (realm, storage) =>
{
using var importer = new BeatmapImporter(realm, storage);
using var importer = new BeatmapImporter(storage, realm);
using var store = new RealmRulesetStore(realm, storage);
string? temp = TestResources.GetTestBeatmapForImport();

View File

@ -220,7 +220,7 @@ namespace osu.Game.Tests.Online
private readonly TestBeatmapManager testBeatmapManager;
public TestBeatmapImporter(TestBeatmapManager testBeatmapManager, Storage storage, RealmAccess databaseAccess, BeatmapOnlineLookupQueue beatmapOnlineLookupQueue)
: base(databaseAccess, storage, beatmapOnlineLookupQueue)
: base(storage, databaseAccess, beatmapOnlineLookupQueue)
{
this.testBeatmapManager = testBeatmapManager;
}

View File

@ -32,7 +32,7 @@ namespace osu.Game.Beatmaps
/// Handles the storage and retrieval of Beatmaps/WorkingBeatmaps.
/// </summary>
[ExcludeFromDynamicCompile]
public class BeatmapImporter : RealmArchiveModelManager<BeatmapSetInfo>, IDisposable
public class BeatmapImporter : RealmArchiveModelImporter<BeatmapSetInfo>, IDisposable
{
public override IEnumerable<string> HandledExtensions => new[] { ".osz" };
@ -40,7 +40,7 @@ namespace osu.Game.Beatmaps
private readonly BeatmapOnlineLookupQueue? onlineLookupQueue;
public BeatmapImporter(RealmAccess realm, Storage storage, BeatmapOnlineLookupQueue? onlineLookupQueue = null)
public BeatmapImporter(Storage storage, RealmAccess realm, BeatmapOnlineLookupQueue? onlineLookupQueue = null)
: base(storage, realm)
{
this.onlineLookupQueue = onlineLookupQueue;
@ -165,11 +165,6 @@ namespace osu.Game.Beatmaps
existing.DateAdded = DateTimeOffset.UtcNow;
}
public override bool IsAvailableLocally(BeatmapSetInfo model)
{
return Realm.Run(realm => realm.All<BeatmapSetInfo>().Any(s => s.OnlineID == model.OnlineID));
}
public override string HumanisedModelName => "beatmap";
protected override BeatmapSetInfo? CreateModel(ArchiveReader reader)

View File

@ -36,7 +36,7 @@ namespace osu.Game.Beatmaps
/// Handles general operations related to global beatmap management.
/// </summary>
[ExcludeFromDynamicCompile]
public class BeatmapManager : IModelManager<BeatmapSetInfo>, IModelFileManager<BeatmapSetInfo, RealmNamedFileUsage>, IModelImporter<BeatmapSetInfo>, IWorkingBeatmapCache, IDisposable
public class BeatmapManager : ModelManager<BeatmapSetInfo>, IModelImporter<BeatmapSetInfo>, IWorkingBeatmapCache, IDisposable
{
public ITrackStore BeatmapTrackStore { get; }
@ -49,6 +49,7 @@ namespace osu.Game.Beatmaps
public BeatmapManager(Storage storage, RealmAccess realm, RulesetStore rulesets, IAPIProvider? api, AudioManager audioManager, IResourceStore<byte[]> gameResources, GameHost? host = null,
WorkingBeatmap? defaultBeatmap = null, bool performOnlineLookups = false)
: base(storage, realm)
{
this.realm = realm;
@ -75,7 +76,7 @@ namespace osu.Game.Beatmaps
}
protected virtual BeatmapImporter CreateBeatmapImporter(Storage storage, RealmAccess realm, RulesetStore rulesets, BeatmapOnlineLookupQueue? onlineLookupQueue) =>
new BeatmapImporter(realm, storage, onlineLookupQueue);
new BeatmapImporter(storage, realm, onlineLookupQueue);
/// <summary>
/// Create a new beatmap set, backed by a <see cref="BeatmapSetInfo"/> model,
@ -272,15 +273,6 @@ namespace osu.Game.Beatmaps
/// </summary>
public IWorkingBeatmap DefaultBeatmap => workingBeatmapCache.DefaultBeatmap;
/// <summary>
/// Fired when a notification should be presented to the user.
/// </summary>
public Action<Notification>? PostNotification
{
get => beatmapImporter.PostNotification;
set => beatmapImporter.PostNotification = value;
}
/// <summary>
/// Saves an <see cref="IBeatmap"/> file against a given <see cref="BeatmapInfo"/>.
/// </summary>
@ -356,7 +348,7 @@ namespace osu.Game.Beatmaps
if (filter != null)
items = items.Where(filter);
beatmapImporter.Delete(items.ToList(), silent);
Delete(items.ToList(), silent);
});
}
@ -407,23 +399,9 @@ namespace osu.Game.Beatmaps
public void UndeleteAll()
{
realm.Run(r => beatmapImporter.Undelete(r.All<BeatmapSetInfo>().Where(s => s.DeletePending).ToList()));
realm.Run(r => Undelete(r.All<BeatmapSetInfo>().Where(s => s.DeletePending).ToList()));
}
#region Implementation of IModelManager<BeatmapSetInfo>
public bool IsAvailableLocally(BeatmapSetInfo model) => beatmapImporter.IsAvailableLocally(model);
public bool Delete(BeatmapSetInfo item) => beatmapImporter.Delete(item);
public void Delete(List<BeatmapSetInfo> items, bool silent = false) => beatmapImporter.Delete(items, silent);
public void Undelete(List<BeatmapSetInfo> items, bool silent = false) => beatmapImporter.Undelete(items, silent);
public void Undelete(BeatmapSetInfo item) => beatmapImporter.Undelete(item);
#endregion
#region Implementation of ICanAcceptFiles
public Task Import(params string[] paths) => beatmapImporter.Import(paths);
@ -479,25 +457,6 @@ namespace osu.Game.Beatmaps
#endregion
#region Implementation of IModelFileManager<in BeatmapSetInfo,in BeatmapSetFileInfo>
public void ReplaceFile(BeatmapSetInfo model, RealmNamedFileUsage file, Stream contents)
{
beatmapImporter.ReplaceFile(model, file, contents);
}
public void DeleteFile(BeatmapSetInfo model, RealmNamedFileUsage file)
{
beatmapImporter.DeleteFile(model, file);
}
public void AddFile(BeatmapSetInfo model, Stream contents, string filename)
{
beatmapImporter.AddFile(model, contents, filename);
}
#endregion
#region Implementation of IDisposable
public void Dispose()

View File

@ -12,7 +12,7 @@ using SharpCompress.Common;
namespace osu.Game.Database
{
/// <summary>
/// An encapsulated import task to be imported to an <see cref="RealmArchiveModelManager{TModel}"/>.
/// An encapsulated import task to be imported to an <see cref="RealmArchiveModelImporter{TModel}"/>.
/// </summary>
public class ImportTask
{

View File

@ -15,18 +15,17 @@ using Realms;
namespace osu.Game.Database
{
/// <summary>
/// Class which adds all the missing pieces bridging the gap between <see cref="RealmArchiveModelImporter{TModel}"/> and (legacy) ArchiveModelManager.
/// </summary>
public abstract class RealmArchiveModelManager<TModel> : RealmArchiveModelImporter<TModel>, IModelManager<TModel>, IModelFileManager<TModel, RealmNamedFileUsage>
public class ModelManager<TModel> : IModelManager<TModel>, IModelFileManager<TModel, RealmNamedFileUsage>
where TModel : RealmObject, IHasRealmFiles, IHasGuidPrimaryKey, ISoftDelete
{
protected RealmAccess Realm;
private readonly RealmFileStore realmFileStore;
protected RealmArchiveModelManager(Storage storage, RealmAccess realm)
: base(storage, realm)
public ModelManager(Storage storage, RealmAccess realm)
{
realmFileStore = new RealmFileStore(realm, storage);
Realm = realm;
}
public void DeleteFile(TModel item, RealmNamedFileUsage file) =>
@ -62,7 +61,7 @@ namespace osu.Game.Database
/// <summary>
/// Delete a file from within an ongoing realm transaction.
/// </summary>
protected void DeleteFile(TModel item, RealmNamedFileUsage file, Realm realm)
public void DeleteFile(TModel item, RealmNamedFileUsage file, Realm realm)
{
item.Files.Remove(file);
}
@ -70,7 +69,7 @@ namespace osu.Game.Database
/// <summary>
/// Replace a file from within an ongoing realm transaction.
/// </summary>
protected void ReplaceFile(RealmNamedFileUsage file, Stream contents, Realm realm)
public void ReplaceFile(RealmNamedFileUsage file, Stream contents, Realm realm)
{
file.File = realmFileStore.Add(contents, realm);
}
@ -78,7 +77,7 @@ namespace osu.Game.Database
/// <summary>
/// Add a file from within an ongoing realm transaction. If the file already exists, it is overwritten.
/// </summary>
protected void AddFile(TModel item, Stream contents, string filename, Realm realm)
public void AddFile(TModel item, Stream contents, string filename, Realm realm)
{
var existing = item.Files.FirstOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase));
@ -200,6 +199,9 @@ namespace osu.Game.Database
});
}
public abstract bool IsAvailableLocally(TModel model);
// TODO: implement
public virtual bool IsAvailableLocally(TModel model) => true;
public Action<Notification>? PostNotification { get; set; }
public string HumanisedModelName { get; set; } = "wang";
}
}

View File

@ -19,7 +19,7 @@ using Realms;
namespace osu.Game.Scoring
{
public class ScoreImporter : RealmArchiveModelManager<ScoreInfo>
public class ScoreImporter : RealmArchiveModelImporter<ScoreInfo>
{
public override IEnumerable<string> HandledExtensions => new[] { ".osr" };
@ -70,10 +70,5 @@ namespace osu.Game.Scoring
if (string.IsNullOrEmpty(model.StatisticsJson))
model.StatisticsJson = JsonConvert.SerializeObject(model.Statistics);
}
public override bool IsAvailableLocally(ScoreInfo model)
{
return Realm.Run(realm => realm.All<ScoreInfo>().Any(s => s.OnlineID == model.OnlineID));
}
}
}

View File

@ -22,7 +22,7 @@ using osu.Game.Rulesets.Scoring;
namespace osu.Game.Scoring
{
public class ScoreManager : IModelManager<ScoreInfo>, IModelImporter<ScoreInfo>
public class ScoreManager : ModelManager<ScoreInfo>, IModelImporter<ScoreInfo>
{
private readonly RealmAccess realm;
private readonly Scheduler scheduler;
@ -32,6 +32,7 @@ namespace osu.Game.Scoring
public ScoreManager(RulesetStore rulesets, Func<BeatmapManager> beatmaps, Storage storage, RealmAccess realm, Scheduler scheduler,
Func<BeatmapDifficultyCache> difficulties = null, OsuConfigManager configManager = null)
: base(storage, realm)
{
this.realm = realm;
this.scheduler = scheduler;
@ -227,22 +228,6 @@ namespace osu.Game.Scoring
}
}
#region Implementation of IPostNotifications
public Action<Notification> PostNotification
{
set => scoreImporter.PostNotification = value;
}
#endregion
#region Implementation of IModelManager<ScoreInfo>
public bool Delete(ScoreInfo item)
{
return scoreImporter.Delete(item);
}
public void Delete([CanBeNull] Expression<Func<ScoreInfo, bool>> filter = null, bool silent = false)
{
realm.Run(r =>
@ -253,7 +238,7 @@ namespace osu.Game.Scoring
if (filter != null)
items = items.Where(filter);
scoreImporter.Delete(items.ToList(), silent);
Delete(items.ToList(), silent);
});
}
@ -262,16 +247,10 @@ namespace osu.Game.Scoring
realm.Run(r =>
{
var beatmapScores = r.Find<BeatmapInfo>(beatmap.ID).Scores.ToList();
scoreImporter.Delete(beatmapScores, silent);
Delete(beatmapScores, silent);
});
}
public void Delete(List<ScoreInfo> items, bool silent = false) => scoreImporter.Delete(items, silent);
public void Undelete(List<ScoreInfo> items, bool silent = false) => scoreImporter.Undelete(items, silent);
public void Undelete(ScoreInfo item) => scoreImporter.Undelete(item);
public Task Import(params string[] paths) => scoreImporter.Import(paths);
public Task Import(params ImportTask[] tasks) => scoreImporter.Import(tasks);
@ -282,10 +261,6 @@ namespace osu.Game.Scoring
public Live<ScoreInfo> Import(ScoreInfo item, ArchiveReader archive = null, bool batchImport = false, CancellationToken cancellationToken = default) => scoreImporter.Import(item, archive, batchImport, cancellationToken);
public bool IsAvailableLocally(ScoreInfo model) => scoreImporter.IsAvailableLocally(model);
#endregion
#region Implementation of IPresentImports<ScoreInfo>
public Action<IEnumerable<Live<ScoreInfo>>> PostImport

View File

@ -20,17 +20,21 @@ using Realms;
namespace osu.Game.Skinning
{
public class SkinImporter : RealmArchiveModelManager<SkinInfo>
public class SkinImporter : RealmArchiveModelImporter<SkinInfo>
{
private const string skin_info_file = "skininfo.json";
private readonly IStorageResourceProvider skinResources;
private readonly ModelManager<SkinInfo> modelManager;
public SkinImporter(Storage storage, RealmAccess realm, IStorageResourceProvider skinResources)
: base(storage, realm)
{
this.skinResources = skinResources;
modelManager = new ModelManager<SkinInfo>(storage, realm);
// can be removed 20220420.
populateMissingHashes();
}
@ -154,7 +158,7 @@ namespace osu.Game.Skinning
sw.WriteLine(line);
}
ReplaceFile(existingFile, stream, realm);
modelManager.ReplaceFile(existingFile, stream, realm);
// can be removed 20220502.
if (!ensureIniWasUpdated(item))
@ -184,7 +188,7 @@ namespace osu.Game.Skinning
sw.WriteLine(line);
}
AddFile(item, stream, @"skin.ini", realm);
modelManager.AddFile(item, stream, @"skin.ini", realm);
}
item.Hash = ComputeHash(item);
@ -216,7 +220,7 @@ namespace osu.Game.Skinning
}
catch (Exception e)
{
Delete(skin);
modelManager.Delete(skin);
Logger.Error(e, $"Existing skin {skin} has been deleted during hash recomputation due to being invalid");
}
}
@ -234,7 +238,7 @@ namespace osu.Game.Skinning
using (var streamContent = new MemoryStream(Encoding.UTF8.GetBytes(skinInfoJson)))
{
AddFile(s, streamContent, skin_info_file, s.Realm);
modelManager.AddFile(s, streamContent, skin_info_file, s.Realm);
}
// Then serialise each of the drawable component groups into respective files.
@ -249,16 +253,14 @@ namespace osu.Game.Skinning
var oldFile = s.Files.FirstOrDefault(f => f.Filename == filename);
if (oldFile != null)
ReplaceFile(oldFile, streamContent, s.Realm);
modelManager.ReplaceFile(oldFile, streamContent, s.Realm);
else
AddFile(s, streamContent, filename, s.Realm);
modelManager.AddFile(s, streamContent, filename, s.Realm);
}
}
s.Hash = ComputeHash(s);
});
}
public override bool IsAvailableLocally(SkinInfo model) => true; // skins do not have online download support yet.
}
}

View File

@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
@ -24,7 +23,6 @@ using osu.Game.Audio;
using osu.Game.Database;
using osu.Game.IO;
using osu.Game.IO.Archives;
using osu.Game.Models;
using osu.Game.Overlays.Notifications;
using osu.Game.Utils;
@ -38,7 +36,7 @@ namespace osu.Game.Skinning
/// For gameplay components, see <see cref="RulesetSkinProvidingContainer"/> which adds extra legacy and toggle logic that may affect the lookup process.
/// </remarks>
[ExcludeFromDynamicCompile]
public class SkinManager : ISkinSource, IStorageResourceProvider, IModelImporter<SkinInfo>, IModelManager<SkinInfo>, IModelFileManager<SkinInfo, RealmNamedFileUsage>
public class SkinManager : ModelManager<SkinInfo>, ISkinSource, IStorageResourceProvider, IModelImporter<SkinInfo>
{
private readonly AudioManager audio;
@ -71,6 +69,7 @@ namespace osu.Game.Skinning
public Skin DefaultLegacySkin { get; }
public SkinManager(Storage storage, RealmAccess realm, GameHost host, IResourceStore<byte[]> resources, AudioManager audio, Scheduler scheduler)
: base(storage, realm)
{
this.realm = realm;
this.audio = audio;
@ -258,11 +257,6 @@ namespace osu.Game.Skinning
#region Implementation of IModelImporter<SkinInfo>
public Action<Notification> PostNotification
{
set => skinImporter.PostNotification = value;
}
public Action<IEnumerable<Live<SkinInfo>>> PostImport
{
set => skinImporter.PostImport = value;
@ -283,8 +277,6 @@ namespace osu.Game.Skinning
#endregion
#region Implementation of IModelManager<SkinInfo>
public void Delete([CanBeNull] Expression<Func<SkinInfo, bool>> filter = null, bool silent = false)
{
realm.Run(r =>
@ -300,26 +292,8 @@ namespace osu.Game.Skinning
if (items.Any(s => s.ID == currentUserSkin))
scheduler.Add(() => CurrentSkinInfo.Value = Skinning.DefaultSkin.CreateInfo().ToLiveUnmanaged());
skinImporter.Delete(items.ToList(), silent);
Delete(items.ToList(), silent);
});
}
public bool Delete(SkinInfo item) => skinImporter.Delete(item);
public void Delete(List<SkinInfo> items, bool silent = false) => skinImporter.Delete(items, silent);
public void Undelete(List<SkinInfo> items, bool silent = false) => skinImporter.Undelete(items, silent);
public void Undelete(SkinInfo item) => skinImporter.Undelete(item);
public bool IsAvailableLocally(SkinInfo model) => skinImporter.IsAvailableLocally(model);
public void ReplaceFile(SkinInfo model, RealmNamedFileUsage file, Stream contents) => skinImporter.ReplaceFile(model, file, contents);
public void DeleteFile(SkinInfo model, RealmNamedFileUsage file) => skinImporter.DeleteFile(model, file);
public void AddFile(SkinInfo model, Stream contents, string filename) => skinImporter.AddFile(model, contents, filename);
#endregion
}
}