mirror of
https://github.com/osukey/osukey.git
synced 2025-05-30 09:57:21 +09:00
Merge pull request #18734 from peppy/bmm-cleanup-2
Remove `RealmArchiveModelManager` from hierarchy
This commit is contained in:
commit
d8657ee9e1
@ -38,7 +38,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using (var importer = new BeatmapImporter(realm, storage))
|
using (var importer = new BeatmapImporter(storage, realm))
|
||||||
using (new RealmRulesetStore(realm, storage))
|
using (new RealmRulesetStore(realm, storage))
|
||||||
{
|
{
|
||||||
Live<BeatmapSetInfo>? beatmapSet;
|
Live<BeatmapSetInfo>? beatmapSet;
|
||||||
@ -82,7 +82,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using (var importer = new BeatmapImporter(realm, storage))
|
using (var importer = new BeatmapImporter(storage, realm))
|
||||||
using (new RealmRulesetStore(realm, storage))
|
using (new RealmRulesetStore(realm, storage))
|
||||||
{
|
{
|
||||||
Live<BeatmapSetInfo>? beatmapSet;
|
Live<BeatmapSetInfo>? beatmapSet;
|
||||||
@ -141,7 +141,9 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
BeatmapSetInfo? detachedSet = null;
|
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))
|
using (new RealmRulesetStore(realm, storage))
|
||||||
{
|
{
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
@ -160,7 +162,7 @@ namespace osu.Game.Tests.Database
|
|||||||
}).WaitSafely();
|
}).WaitSafely();
|
||||||
|
|
||||||
Debug.Assert(detachedSet != null);
|
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) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using (var importer = new BeatmapImporter(realm, storage))
|
using (var importer = new BeatmapImporter(storage, realm))
|
||||||
using (new RealmRulesetStore(realm, storage))
|
using (new RealmRulesetStore(realm, storage))
|
||||||
{
|
{
|
||||||
Live<BeatmapSetInfo>? imported;
|
Live<BeatmapSetInfo>? imported;
|
||||||
@ -202,7 +204,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
await LoadOszIntoStore(importer, realm.Realm);
|
await LoadOszIntoStore(importer, realm.Realm);
|
||||||
@ -214,7 +216,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
var imported = await LoadOszIntoStore(importer, realm.Realm);
|
var imported = await LoadOszIntoStore(importer, realm.Realm);
|
||||||
@ -232,7 +234,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
var imported = await LoadOszIntoStore(importer, realm.Realm);
|
var imported = await LoadOszIntoStore(importer, realm.Realm);
|
||||||
@ -246,7 +248,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? tempPath = TestResources.GetTestBeatmapForImport();
|
string? tempPath = TestResources.GetTestBeatmapForImport();
|
||||||
@ -276,7 +278,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
var imported = await LoadOszIntoStore(importer, realm.Realm);
|
var imported = await LoadOszIntoStore(importer, realm.Realm);
|
||||||
@ -296,7 +298,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? temp = TestResources.GetTestBeatmapForImport();
|
string? temp = TestResources.GetTestBeatmapForImport();
|
||||||
@ -345,7 +347,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? temp = TestResources.GetTestBeatmapForImport();
|
string? temp = TestResources.GetTestBeatmapForImport();
|
||||||
@ -396,7 +398,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? temp = TestResources.GetTestBeatmapForImport();
|
string? temp = TestResources.GetTestBeatmapForImport();
|
||||||
@ -444,7 +446,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? temp = TestResources.GetTestBeatmapForImport();
|
string? temp = TestResources.GetTestBeatmapForImport();
|
||||||
@ -492,7 +494,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
var imported = await LoadOszIntoStore(importer, realm.Realm);
|
var imported = await LoadOszIntoStore(importer, realm.Realm);
|
||||||
@ -527,7 +529,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
var progressNotification = new ImportProgressNotification();
|
var progressNotification = new ImportProgressNotification();
|
||||||
@ -565,7 +567,7 @@ namespace osu.Game.Tests.Database
|
|||||||
Interlocked.Increment(ref loggedExceptionCount);
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
var imported = await LoadOszIntoStore(importer, realm.Realm);
|
var imported = await LoadOszIntoStore(importer, realm.Realm);
|
||||||
@ -617,7 +619,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
var imported = await LoadOszIntoStore(importer, realm.Realm, batchImport: true);
|
var imported = await LoadOszIntoStore(importer, realm.Realm, batchImport: true);
|
||||||
@ -644,7 +646,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realmFactory, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realmFactory, storage);
|
||||||
|
|
||||||
var imported = await LoadOszIntoStore(importer, realmFactory.Realm);
|
var imported = await LoadOszIntoStore(importer, realmFactory.Realm);
|
||||||
@ -676,7 +678,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
var imported = await LoadOszIntoStore(importer, realm.Realm);
|
var imported = await LoadOszIntoStore(importer, realm.Realm);
|
||||||
@ -703,7 +705,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
var imported = await LoadOszIntoStore(importer, realm.Realm);
|
var imported = await LoadOszIntoStore(importer, realm.Realm);
|
||||||
@ -729,7 +731,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealm((realm, storage) =>
|
RunTestWithRealm((realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapImporter(realm, storage);
|
using var importer = new BeatmapImporter(storage, realm);
|
||||||
using var store = new RealmRulesetStore(realm, storage);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
var metadata = new BeatmapMetadata
|
var metadata = new BeatmapMetadata
|
||||||
@ -777,7 +779,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? temp = TestResources.GetTestBeatmapForImport();
|
string? temp = TestResources.GetTestBeatmapForImport();
|
||||||
@ -794,7 +796,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? temp = TestResources.GetTestBeatmapForImport();
|
string? temp = TestResources.GetTestBeatmapForImport();
|
||||||
@ -830,7 +832,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? temp = TestResources.GetTestBeatmapForImport();
|
string? temp = TestResources.GetTestBeatmapForImport();
|
||||||
@ -872,7 +874,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? temp = TestResources.GetTestBeatmapForImport();
|
string? temp = TestResources.GetTestBeatmapForImport();
|
||||||
@ -923,7 +925,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
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);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? temp = TestResources.GetTestBeatmapForImport();
|
string? temp = TestResources.GetTestBeatmapForImport();
|
||||||
|
@ -220,7 +220,7 @@ namespace osu.Game.Tests.Online
|
|||||||
private readonly TestBeatmapManager testBeatmapManager;
|
private readonly TestBeatmapManager testBeatmapManager;
|
||||||
|
|
||||||
public TestBeatmapImporter(TestBeatmapManager testBeatmapManager, Storage storage, RealmAccess databaseAccess, BeatmapOnlineLookupQueue beatmapOnlineLookupQueue)
|
public TestBeatmapImporter(TestBeatmapManager testBeatmapManager, Storage storage, RealmAccess databaseAccess, BeatmapOnlineLookupQueue beatmapOnlineLookupQueue)
|
||||||
: base(databaseAccess, storage, beatmapOnlineLookupQueue)
|
: base(storage, databaseAccess, beatmapOnlineLookupQueue)
|
||||||
{
|
{
|
||||||
this.testBeatmapManager = testBeatmapManager;
|
this.testBeatmapManager = testBeatmapManager;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ namespace osu.Game.Beatmaps
|
|||||||
/// Handles the storage and retrieval of Beatmaps/WorkingBeatmaps.
|
/// Handles the storage and retrieval of Beatmaps/WorkingBeatmaps.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ExcludeFromDynamicCompile]
|
[ExcludeFromDynamicCompile]
|
||||||
public class BeatmapImporter : RealmArchiveModelManager<BeatmapSetInfo>, IDisposable
|
public class BeatmapImporter : RealmArchiveModelImporter<BeatmapSetInfo>, IDisposable
|
||||||
{
|
{
|
||||||
public override IEnumerable<string> HandledExtensions => new[] { ".osz" };
|
public override IEnumerable<string> HandledExtensions => new[] { ".osz" };
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
private readonly BeatmapOnlineLookupQueue? onlineLookupQueue;
|
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)
|
: base(storage, realm)
|
||||||
{
|
{
|
||||||
this.onlineLookupQueue = onlineLookupQueue;
|
this.onlineLookupQueue = onlineLookupQueue;
|
||||||
@ -165,11 +165,6 @@ namespace osu.Game.Beatmaps
|
|||||||
existing.DateAdded = DateTimeOffset.UtcNow;
|
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";
|
public override string HumanisedModelName => "beatmap";
|
||||||
|
|
||||||
protected override BeatmapSetInfo? CreateModel(ArchiveReader reader)
|
protected override BeatmapSetInfo? CreateModel(ArchiveReader reader)
|
||||||
|
@ -36,7 +36,7 @@ namespace osu.Game.Beatmaps
|
|||||||
/// Handles general operations related to global beatmap management.
|
/// Handles general operations related to global beatmap management.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ExcludeFromDynamicCompile]
|
[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; }
|
public ITrackStore BeatmapTrackStore { get; }
|
||||||
|
|
||||||
@ -45,13 +45,10 @@ namespace osu.Game.Beatmaps
|
|||||||
private readonly WorkingBeatmapCache workingBeatmapCache;
|
private readonly WorkingBeatmapCache workingBeatmapCache;
|
||||||
private readonly BeatmapOnlineLookupQueue? onlineBeatmapLookupQueue;
|
private readonly BeatmapOnlineLookupQueue? onlineBeatmapLookupQueue;
|
||||||
|
|
||||||
private readonly RealmAccess realm;
|
|
||||||
|
|
||||||
public BeatmapManager(Storage storage, RealmAccess realm, RulesetStore rulesets, IAPIProvider? api, AudioManager audioManager, IResourceStore<byte[]> gameResources, GameHost? host = null,
|
public BeatmapManager(Storage storage, RealmAccess realm, RulesetStore rulesets, IAPIProvider? api, AudioManager audioManager, IResourceStore<byte[]> gameResources, GameHost? host = null,
|
||||||
WorkingBeatmap? defaultBeatmap = null, bool performOnlineLookups = false)
|
WorkingBeatmap? defaultBeatmap = null, bool performOnlineLookups = false)
|
||||||
|
: base(storage, realm)
|
||||||
{
|
{
|
||||||
this.realm = realm;
|
|
||||||
|
|
||||||
if (performOnlineLookups)
|
if (performOnlineLookups)
|
||||||
{
|
{
|
||||||
if (api == null)
|
if (api == null)
|
||||||
@ -65,6 +62,8 @@ namespace osu.Game.Beatmaps
|
|||||||
BeatmapTrackStore = audioManager.GetTrackStore(userResources);
|
BeatmapTrackStore = audioManager.GetTrackStore(userResources);
|
||||||
|
|
||||||
beatmapImporter = CreateBeatmapImporter(storage, realm, rulesets, onlineBeatmapLookupQueue);
|
beatmapImporter = CreateBeatmapImporter(storage, realm, rulesets, onlineBeatmapLookupQueue);
|
||||||
|
beatmapImporter.PostNotification = obj => PostNotification?.Invoke(obj);
|
||||||
|
|
||||||
workingBeatmapCache = CreateWorkingBeatmapCache(audioManager, gameResources, userResources, defaultBeatmap, host);
|
workingBeatmapCache = CreateWorkingBeatmapCache(audioManager, gameResources, userResources, defaultBeatmap, host);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +74,7 @@ namespace osu.Game.Beatmaps
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected virtual BeatmapImporter CreateBeatmapImporter(Storage storage, RealmAccess realm, RulesetStore rulesets, BeatmapOnlineLookupQueue? onlineLookupQueue) =>
|
protected virtual BeatmapImporter CreateBeatmapImporter(Storage storage, RealmAccess realm, RulesetStore rulesets, BeatmapOnlineLookupQueue? onlineLookupQueue) =>
|
||||||
new BeatmapImporter(realm, storage, onlineLookupQueue);
|
new BeatmapImporter(storage, realm, onlineLookupQueue);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new beatmap set, backed by a <see cref="BeatmapSetInfo"/> model,
|
/// Create a new beatmap set, backed by a <see cref="BeatmapSetInfo"/> model,
|
||||||
@ -191,7 +190,7 @@ namespace osu.Game.Beatmaps
|
|||||||
/// <param name="beatmapInfo">The beatmap difficulty to hide.</param>
|
/// <param name="beatmapInfo">The beatmap difficulty to hide.</param>
|
||||||
public void Hide(BeatmapInfo beatmapInfo)
|
public void Hide(BeatmapInfo beatmapInfo)
|
||||||
{
|
{
|
||||||
realm.Run(r =>
|
Realm.Run(r =>
|
||||||
{
|
{
|
||||||
using (var transaction = r.BeginWrite())
|
using (var transaction = r.BeginWrite())
|
||||||
{
|
{
|
||||||
@ -210,7 +209,7 @@ namespace osu.Game.Beatmaps
|
|||||||
/// <param name="beatmapInfo">The beatmap difficulty to restore.</param>
|
/// <param name="beatmapInfo">The beatmap difficulty to restore.</param>
|
||||||
public void Restore(BeatmapInfo beatmapInfo)
|
public void Restore(BeatmapInfo beatmapInfo)
|
||||||
{
|
{
|
||||||
realm.Run(r =>
|
Realm.Run(r =>
|
||||||
{
|
{
|
||||||
using (var transaction = r.BeginWrite())
|
using (var transaction = r.BeginWrite())
|
||||||
{
|
{
|
||||||
@ -225,7 +224,7 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
public void RestoreAll()
|
public void RestoreAll()
|
||||||
{
|
{
|
||||||
realm.Run(r =>
|
Realm.Run(r =>
|
||||||
{
|
{
|
||||||
using (var transaction = r.BeginWrite())
|
using (var transaction = r.BeginWrite())
|
||||||
{
|
{
|
||||||
@ -243,7 +242,7 @@ namespace osu.Game.Beatmaps
|
|||||||
/// <returns>A list of available <see cref="BeatmapSetInfo"/>.</returns>
|
/// <returns>A list of available <see cref="BeatmapSetInfo"/>.</returns>
|
||||||
public List<BeatmapSetInfo> GetAllUsableBeatmapSets()
|
public List<BeatmapSetInfo> GetAllUsableBeatmapSets()
|
||||||
{
|
{
|
||||||
return realm.Run(r =>
|
return Realm.Run(r =>
|
||||||
{
|
{
|
||||||
r.Refresh();
|
r.Refresh();
|
||||||
return r.All<BeatmapSetInfo>().Where(b => !b.DeletePending).Detach();
|
return r.All<BeatmapSetInfo>().Where(b => !b.DeletePending).Detach();
|
||||||
@ -257,7 +256,7 @@ namespace osu.Game.Beatmaps
|
|||||||
/// <returns>The first result for the provided query, or null if no results were found.</returns>
|
/// <returns>The first result for the provided query, or null if no results were found.</returns>
|
||||||
public Live<BeatmapSetInfo>? QueryBeatmapSet(Expression<Func<BeatmapSetInfo, bool>> query)
|
public Live<BeatmapSetInfo>? QueryBeatmapSet(Expression<Func<BeatmapSetInfo, bool>> query)
|
||||||
{
|
{
|
||||||
return realm.Run(r => r.All<BeatmapSetInfo>().FirstOrDefault(query)?.ToLive(realm));
|
return Realm.Run(r => r.All<BeatmapSetInfo>().FirstOrDefault(query)?.ToLive(Realm));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -265,22 +264,13 @@ namespace osu.Game.Beatmaps
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="query">The query.</param>
|
/// <param name="query">The query.</param>
|
||||||
/// <returns>The first result for the provided query, or null if no results were found.</returns>
|
/// <returns>The first result for the provided query, or null if no results were found.</returns>
|
||||||
public BeatmapInfo? QueryBeatmap(Expression<Func<BeatmapInfo, bool>> query) => realm.Run(r => r.All<BeatmapInfo>().FirstOrDefault(query)?.Detach());
|
public BeatmapInfo? QueryBeatmap(Expression<Func<BeatmapInfo, bool>> query) => Realm.Run(r => r.All<BeatmapInfo>().FirstOrDefault(query)?.Detach());
|
||||||
|
|
||||||
/// <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>
|
||||||
public IWorkingBeatmap DefaultBeatmap => workingBeatmapCache.DefaultBeatmap;
|
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>
|
/// <summary>
|
||||||
/// Saves an <see cref="IBeatmap"/> file against a given <see cref="BeatmapInfo"/>.
|
/// Saves an <see cref="IBeatmap"/> file against a given <see cref="BeatmapInfo"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -326,7 +316,7 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
AddFile(setInfo, stream, createBeatmapFilenameFromMetadata(beatmapInfo));
|
AddFile(setInfo, stream, createBeatmapFilenameFromMetadata(beatmapInfo));
|
||||||
|
|
||||||
realm.Write(r => setInfo.CopyChangesToRealm(r.Find<BeatmapSetInfo>(setInfo.ID)));
|
Realm.Write(r => setInfo.CopyChangesToRealm(r.Find<BeatmapSetInfo>(setInfo.ID)));
|
||||||
}
|
}
|
||||||
|
|
||||||
workingBeatmapCache.Invalidate(beatmapInfo);
|
workingBeatmapCache.Invalidate(beatmapInfo);
|
||||||
@ -340,7 +330,7 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
public void DeleteAllVideos()
|
public void DeleteAllVideos()
|
||||||
{
|
{
|
||||||
realm.Write(r =>
|
Realm.Write(r =>
|
||||||
{
|
{
|
||||||
var items = r.All<BeatmapSetInfo>().Where(s => !s.DeletePending && !s.Protected);
|
var items = r.All<BeatmapSetInfo>().Where(s => !s.DeletePending && !s.Protected);
|
||||||
DeleteVideos(items.ToList());
|
DeleteVideos(items.ToList());
|
||||||
@ -349,14 +339,14 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
public void Delete(Expression<Func<BeatmapSetInfo, bool>>? filter = null, bool silent = false)
|
public void Delete(Expression<Func<BeatmapSetInfo, bool>>? filter = null, bool silent = false)
|
||||||
{
|
{
|
||||||
realm.Run(r =>
|
Realm.Run(r =>
|
||||||
{
|
{
|
||||||
var items = r.All<BeatmapSetInfo>().Where(s => !s.DeletePending && !s.Protected);
|
var items = r.All<BeatmapSetInfo>().Where(s => !s.DeletePending && !s.Protected);
|
||||||
|
|
||||||
if (filter != null)
|
if (filter != null)
|
||||||
items = items.Where(filter);
|
items = items.Where(filter);
|
||||||
|
|
||||||
beatmapImporter.Delete(items.ToList(), silent);
|
Delete(items.ToList(), silent);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,7 +361,7 @@ namespace osu.Game.Beatmaps
|
|||||||
var notification = new ProgressNotification
|
var notification = new ProgressNotification
|
||||||
{
|
{
|
||||||
Progress = 0,
|
Progress = 0,
|
||||||
Text = $"Preparing to delete all {beatmapImporter.HumanisedModelName} videos...",
|
Text = $"Preparing to delete all {HumanisedModelName} videos...",
|
||||||
CompletionText = "No videos found to delete!",
|
CompletionText = "No videos found to delete!",
|
||||||
State = ProgressNotificationState.Active,
|
State = ProgressNotificationState.Active,
|
||||||
};
|
};
|
||||||
@ -394,10 +384,10 @@ namespace osu.Game.Beatmaps
|
|||||||
{
|
{
|
||||||
DeleteFile(b, video);
|
DeleteFile(b, video);
|
||||||
deleted++;
|
deleted++;
|
||||||
notification.CompletionText = $"Deleted {deleted} {beatmapImporter.HumanisedModelName} video(s)!";
|
notification.CompletionText = $"Deleted {deleted} {HumanisedModelName} video(s)!";
|
||||||
}
|
}
|
||||||
|
|
||||||
notification.Text = $"Deleting videos from {beatmapImporter.HumanisedModelName}s ({deleted} deleted)";
|
notification.Text = $"Deleting videos from {HumanisedModelName}s ({deleted} deleted)";
|
||||||
|
|
||||||
notification.Progress = (float)++i / items.Count;
|
notification.Progress = (float)++i / items.Count;
|
||||||
}
|
}
|
||||||
@ -407,23 +397,9 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
public void UndeleteAll()
|
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
|
#region Implementation of ICanAcceptFiles
|
||||||
|
|
||||||
public Task Import(params string[] paths) => beatmapImporter.Import(paths);
|
public Task Import(params string[] paths) => beatmapImporter.Import(paths);
|
||||||
@ -453,7 +429,7 @@ namespace osu.Game.Beatmaps
|
|||||||
// If we seem to be missing files, now is a good time to re-fetch.
|
// If we seem to be missing files, now is a good time to re-fetch.
|
||||||
if (importedBeatmap?.BeatmapSet?.Files.Count == 0)
|
if (importedBeatmap?.BeatmapSet?.Files.Count == 0)
|
||||||
{
|
{
|
||||||
realm.Run(r =>
|
Realm.Run(r =>
|
||||||
{
|
{
|
||||||
var refetch = r.Find<BeatmapInfo>(importedBeatmap.ID)?.Detach();
|
var refetch = r.Find<BeatmapInfo>(importedBeatmap.ID)?.Detach();
|
||||||
|
|
||||||
@ -465,36 +441,10 @@ namespace osu.Game.Beatmaps
|
|||||||
return workingBeatmapCache.GetWorkingBeatmap(importedBeatmap);
|
return workingBeatmapCache.GetWorkingBeatmap(importedBeatmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public WorkingBeatmap GetWorkingBeatmap(Live<BeatmapInfo>? importedBeatmap)
|
|
||||||
{
|
|
||||||
WorkingBeatmap working = workingBeatmapCache.GetWorkingBeatmap(null);
|
|
||||||
|
|
||||||
importedBeatmap?.PerformRead(b => working = workingBeatmapCache.GetWorkingBeatmap(b));
|
|
||||||
|
|
||||||
return working;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IWorkingBeatmapCache.Invalidate(BeatmapSetInfo beatmapSetInfo) => workingBeatmapCache.Invalidate(beatmapSetInfo);
|
void IWorkingBeatmapCache.Invalidate(BeatmapSetInfo beatmapSetInfo) => workingBeatmapCache.Invalidate(beatmapSetInfo);
|
||||||
void IWorkingBeatmapCache.Invalidate(BeatmapInfo beatmapInfo) => workingBeatmapCache.Invalidate(beatmapInfo);
|
void IWorkingBeatmapCache.Invalidate(BeatmapInfo beatmapInfo) => workingBeatmapCache.Invalidate(beatmapInfo);
|
||||||
|
|
||||||
#endregion
|
public override bool IsAvailableLocally(BeatmapSetInfo model) => Realm.Run(realm => realm.All<BeatmapSetInfo>().Any(s => s.OnlineID == model.OnlineID));
|
||||||
|
|
||||||
#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
|
#endregion
|
||||||
|
|
||||||
@ -515,5 +465,7 @@ namespace osu.Game.Beatmaps
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
public override string HumanisedModelName => "beatmap";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ using SharpCompress.Common;
|
|||||||
namespace osu.Game.Database
|
namespace osu.Game.Database
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <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>
|
/// </summary>
|
||||||
public class ImportTask
|
public class ImportTask
|
||||||
{
|
{
|
||||||
|
@ -15,18 +15,17 @@ using Realms;
|
|||||||
|
|
||||||
namespace osu.Game.Database
|
namespace osu.Game.Database
|
||||||
{
|
{
|
||||||
/// <summary>
|
public class ModelManager<TModel> : IModelManager<TModel>, IModelFileManager<TModel, RealmNamedFileUsage>
|
||||||
/// 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>
|
|
||||||
where TModel : RealmObject, IHasRealmFiles, IHasGuidPrimaryKey, ISoftDelete
|
where TModel : RealmObject, IHasRealmFiles, IHasGuidPrimaryKey, ISoftDelete
|
||||||
{
|
{
|
||||||
|
protected RealmAccess Realm { get; }
|
||||||
|
|
||||||
private readonly RealmFileStore realmFileStore;
|
private readonly RealmFileStore realmFileStore;
|
||||||
|
|
||||||
protected RealmArchiveModelManager(Storage storage, RealmAccess realm)
|
public ModelManager(Storage storage, RealmAccess realm)
|
||||||
: base(storage, realm)
|
|
||||||
{
|
{
|
||||||
realmFileStore = new RealmFileStore(realm, storage);
|
realmFileStore = new RealmFileStore(realm, storage);
|
||||||
|
Realm = realm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteFile(TModel item, RealmNamedFileUsage file) =>
|
public void DeleteFile(TModel item, RealmNamedFileUsage file) =>
|
||||||
@ -62,7 +61,7 @@ namespace osu.Game.Database
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Delete a file from within an ongoing realm transaction.
|
/// Delete a file from within an ongoing realm transaction.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected void DeleteFile(TModel item, RealmNamedFileUsage file, Realm realm)
|
public void DeleteFile(TModel item, RealmNamedFileUsage file, Realm realm)
|
||||||
{
|
{
|
||||||
item.Files.Remove(file);
|
item.Files.Remove(file);
|
||||||
}
|
}
|
||||||
@ -70,7 +69,7 @@ namespace osu.Game.Database
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Replace a file from within an ongoing realm transaction.
|
/// Replace a file from within an ongoing realm transaction.
|
||||||
/// </summary>
|
/// </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);
|
file.File = realmFileStore.Add(contents, realm);
|
||||||
}
|
}
|
||||||
@ -78,7 +77,7 @@ namespace osu.Game.Database
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add a file from within an ongoing realm transaction. If the file already exists, it is overwritten.
|
/// Add a file from within an ongoing realm transaction. If the file already exists, it is overwritten.
|
||||||
/// </summary>
|
/// </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));
|
var existing = item.Files.FirstOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
@ -200,6 +199,10 @@ namespace osu.Game.Database
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract bool IsAvailableLocally(TModel model);
|
public virtual bool IsAvailableLocally(TModel model) => true;
|
||||||
|
|
||||||
|
public Action<Notification>? PostNotification { get; set; }
|
||||||
|
|
||||||
|
public virtual string HumanisedModelName => $"{typeof(TModel).Name.Replace(@"Info", "").ToLower()}";
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -19,7 +19,7 @@ using Realms;
|
|||||||
|
|
||||||
namespace osu.Game.Scoring
|
namespace osu.Game.Scoring
|
||||||
{
|
{
|
||||||
public class ScoreImporter : RealmArchiveModelManager<ScoreInfo>
|
public class ScoreImporter : RealmArchiveModelImporter<ScoreInfo>
|
||||||
{
|
{
|
||||||
public override IEnumerable<string> HandledExtensions => new[] { ".osr" };
|
public override IEnumerable<string> HandledExtensions => new[] { ".osr" };
|
||||||
|
|
||||||
@ -70,10 +70,5 @@ namespace osu.Game.Scoring
|
|||||||
if (string.IsNullOrEmpty(model.StatisticsJson))
|
if (string.IsNullOrEmpty(model.StatisticsJson))
|
||||||
model.StatisticsJson = JsonConvert.SerializeObject(model.Statistics);
|
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,8 @@ using osu.Game.Rulesets.Scoring;
|
|||||||
|
|
||||||
namespace osu.Game.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;
|
private readonly Scheduler scheduler;
|
||||||
private readonly Func<BeatmapDifficultyCache> difficulties;
|
private readonly Func<BeatmapDifficultyCache> difficulties;
|
||||||
private readonly OsuConfigManager configManager;
|
private readonly OsuConfigManager configManager;
|
||||||
@ -32,13 +31,16 @@ namespace osu.Game.Scoring
|
|||||||
|
|
||||||
public ScoreManager(RulesetStore rulesets, Func<BeatmapManager> beatmaps, Storage storage, RealmAccess realm, Scheduler scheduler,
|
public ScoreManager(RulesetStore rulesets, Func<BeatmapManager> beatmaps, Storage storage, RealmAccess realm, Scheduler scheduler,
|
||||||
Func<BeatmapDifficultyCache> difficulties = null, OsuConfigManager configManager = null)
|
Func<BeatmapDifficultyCache> difficulties = null, OsuConfigManager configManager = null)
|
||||||
|
: base(storage, realm)
|
||||||
{
|
{
|
||||||
this.realm = realm;
|
|
||||||
this.scheduler = scheduler;
|
this.scheduler = scheduler;
|
||||||
this.difficulties = difficulties;
|
this.difficulties = difficulties;
|
||||||
this.configManager = configManager;
|
this.configManager = configManager;
|
||||||
|
|
||||||
scoreImporter = new ScoreImporter(rulesets, beatmaps, storage, realm);
|
scoreImporter = new ScoreImporter(rulesets, beatmaps, storage, realm)
|
||||||
|
{
|
||||||
|
PostNotification = obj => PostNotification?.Invoke(obj)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public Score GetScore(ScoreInfo score) => scoreImporter.GetScore(score);
|
public Score GetScore(ScoreInfo score) => scoreImporter.GetScore(score);
|
||||||
@ -50,7 +52,7 @@ namespace osu.Game.Scoring
|
|||||||
/// <returns>The first result for the provided query, or null if no results were found.</returns>
|
/// <returns>The first result for the provided query, or null if no results were found.</returns>
|
||||||
public ScoreInfo Query(Expression<Func<ScoreInfo, bool>> query)
|
public ScoreInfo Query(Expression<Func<ScoreInfo, bool>> query)
|
||||||
{
|
{
|
||||||
return realm.Run(r => r.All<ScoreInfo>().FirstOrDefault(query)?.Detach());
|
return Realm.Run(r => r.All<ScoreInfo>().FirstOrDefault(query)?.Detach());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -227,25 +229,9 @@ 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)
|
public void Delete([CanBeNull] Expression<Func<ScoreInfo, bool>> filter = null, bool silent = false)
|
||||||
{
|
{
|
||||||
realm.Run(r =>
|
Realm.Run(r =>
|
||||||
{
|
{
|
||||||
var items = r.All<ScoreInfo>()
|
var items = r.All<ScoreInfo>()
|
||||||
.Where(s => !s.DeletePending);
|
.Where(s => !s.DeletePending);
|
||||||
@ -253,38 +239,31 @@ namespace osu.Game.Scoring
|
|||||||
if (filter != null)
|
if (filter != null)
|
||||||
items = items.Where(filter);
|
items = items.Where(filter);
|
||||||
|
|
||||||
scoreImporter.Delete(items.ToList(), silent);
|
Delete(items.ToList(), silent);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Delete(BeatmapInfo beatmap, bool silent = false)
|
public void Delete(BeatmapInfo beatmap, bool silent = false)
|
||||||
{
|
{
|
||||||
realm.Run(r =>
|
Realm.Run(r =>
|
||||||
{
|
{
|
||||||
var beatmapScores = r.Find<BeatmapInfo>(beatmap.ID).Scores.ToList();
|
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 string[] paths) => scoreImporter.Import(paths);
|
||||||
|
|
||||||
public Task Import(params ImportTask[] tasks) => scoreImporter.Import(tasks);
|
public Task Import(params ImportTask[] tasks) => scoreImporter.Import(tasks);
|
||||||
|
|
||||||
|
public override bool IsAvailableLocally(ScoreInfo model) => Realm.Run(realm => realm.All<ScoreInfo>().Any(s => s.OnlineID == model.OnlineID));
|
||||||
|
|
||||||
public IEnumerable<string> HandledExtensions => scoreImporter.HandledExtensions;
|
public IEnumerable<string> HandledExtensions => scoreImporter.HandledExtensions;
|
||||||
|
|
||||||
public Task<IEnumerable<Live<ScoreInfo>>> Import(ProgressNotification notification, params ImportTask[] tasks) => scoreImporter.Import(notification, tasks);
|
public Task<IEnumerable<Live<ScoreInfo>>> Import(ProgressNotification notification, params ImportTask[] tasks) => scoreImporter.Import(notification, tasks);
|
||||||
|
|
||||||
public Live<ScoreInfo> Import(ScoreInfo item, ArchiveReader archive = null, bool batchImport = false, CancellationToken cancellationToken = default) => scoreImporter.Import(item, archive, batchImport, cancellationToken);
|
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>
|
#region Implementation of IPresentImports<ScoreInfo>
|
||||||
|
|
||||||
|
@ -20,17 +20,21 @@ using Realms;
|
|||||||
|
|
||||||
namespace osu.Game.Skinning
|
namespace osu.Game.Skinning
|
||||||
{
|
{
|
||||||
public class SkinImporter : RealmArchiveModelManager<SkinInfo>
|
public class SkinImporter : RealmArchiveModelImporter<SkinInfo>
|
||||||
{
|
{
|
||||||
private const string skin_info_file = "skininfo.json";
|
private const string skin_info_file = "skininfo.json";
|
||||||
|
|
||||||
private readonly IStorageResourceProvider skinResources;
|
private readonly IStorageResourceProvider skinResources;
|
||||||
|
|
||||||
|
private readonly ModelManager<SkinInfo> modelManager;
|
||||||
|
|
||||||
public SkinImporter(Storage storage, RealmAccess realm, IStorageResourceProvider skinResources)
|
public SkinImporter(Storage storage, RealmAccess realm, IStorageResourceProvider skinResources)
|
||||||
: base(storage, realm)
|
: base(storage, realm)
|
||||||
{
|
{
|
||||||
this.skinResources = skinResources;
|
this.skinResources = skinResources;
|
||||||
|
|
||||||
|
modelManager = new ModelManager<SkinInfo>(storage, realm);
|
||||||
|
|
||||||
// can be removed 20220420.
|
// can be removed 20220420.
|
||||||
populateMissingHashes();
|
populateMissingHashes();
|
||||||
}
|
}
|
||||||
@ -154,7 +158,7 @@ namespace osu.Game.Skinning
|
|||||||
sw.WriteLine(line);
|
sw.WriteLine(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReplaceFile(existingFile, stream, realm);
|
modelManager.ReplaceFile(existingFile, stream, realm);
|
||||||
|
|
||||||
// can be removed 20220502.
|
// can be removed 20220502.
|
||||||
if (!ensureIniWasUpdated(item))
|
if (!ensureIniWasUpdated(item))
|
||||||
@ -184,7 +188,7 @@ namespace osu.Game.Skinning
|
|||||||
sw.WriteLine(line);
|
sw.WriteLine(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddFile(item, stream, @"skin.ini", realm);
|
modelManager.AddFile(item, stream, @"skin.ini", realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
item.Hash = ComputeHash(item);
|
item.Hash = ComputeHash(item);
|
||||||
@ -216,7 +220,7 @@ namespace osu.Game.Skinning
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Delete(skin);
|
modelManager.Delete(skin);
|
||||||
Logger.Error(e, $"Existing skin {skin} has been deleted during hash recomputation due to being invalid");
|
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)))
|
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.
|
// 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);
|
var oldFile = s.Files.FirstOrDefault(f => f.Filename == filename);
|
||||||
|
|
||||||
if (oldFile != null)
|
if (oldFile != null)
|
||||||
ReplaceFile(oldFile, streamContent, s.Realm);
|
modelManager.ReplaceFile(oldFile, streamContent, s.Realm);
|
||||||
else
|
else
|
||||||
AddFile(s, streamContent, filename, s.Realm);
|
modelManager.AddFile(s, streamContent, filename, s.Realm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Hash = ComputeHash(s);
|
s.Hash = ComputeHash(s);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsAvailableLocally(SkinInfo model) => true; // skins do not have online download support yet.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@ -24,7 +23,6 @@ using osu.Game.Audio;
|
|||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.IO;
|
using osu.Game.IO;
|
||||||
using osu.Game.IO.Archives;
|
using osu.Game.IO.Archives;
|
||||||
using osu.Game.Models;
|
|
||||||
using osu.Game.Overlays.Notifications;
|
using osu.Game.Overlays.Notifications;
|
||||||
using osu.Game.Utils;
|
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.
|
/// For gameplay components, see <see cref="RulesetSkinProvidingContainer"/> which adds extra legacy and toggle logic that may affect the lookup process.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[ExcludeFromDynamicCompile]
|
[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;
|
private readonly AudioManager audio;
|
||||||
|
|
||||||
@ -56,7 +54,6 @@ namespace osu.Game.Skinning
|
|||||||
};
|
};
|
||||||
|
|
||||||
private readonly SkinImporter skinImporter;
|
private readonly SkinImporter skinImporter;
|
||||||
private readonly RealmAccess realm;
|
|
||||||
|
|
||||||
private readonly IResourceStore<byte[]> userFiles;
|
private readonly IResourceStore<byte[]> userFiles;
|
||||||
|
|
||||||
@ -71,8 +68,8 @@ namespace osu.Game.Skinning
|
|||||||
public Skin DefaultLegacySkin { get; }
|
public Skin DefaultLegacySkin { get; }
|
||||||
|
|
||||||
public SkinManager(Storage storage, RealmAccess realm, GameHost host, IResourceStore<byte[]> resources, AudioManager audio, Scheduler scheduler)
|
public SkinManager(Storage storage, RealmAccess realm, GameHost host, IResourceStore<byte[]> resources, AudioManager audio, Scheduler scheduler)
|
||||||
|
: base(storage, realm)
|
||||||
{
|
{
|
||||||
this.realm = realm;
|
|
||||||
this.audio = audio;
|
this.audio = audio;
|
||||||
this.scheduler = scheduler;
|
this.scheduler = scheduler;
|
||||||
this.host = host;
|
this.host = host;
|
||||||
@ -80,7 +77,10 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
userFiles = new StorageBackedResourceStore(storage.GetStorageForDirectory("files"));
|
userFiles = new StorageBackedResourceStore(storage.GetStorageForDirectory("files"));
|
||||||
|
|
||||||
skinImporter = new SkinImporter(storage, realm, this);
|
skinImporter = new SkinImporter(storage, realm, this)
|
||||||
|
{
|
||||||
|
PostNotification = obj => PostNotification?.Invoke(obj),
|
||||||
|
};
|
||||||
|
|
||||||
var defaultSkins = new[]
|
var defaultSkins = new[]
|
||||||
{
|
{
|
||||||
@ -115,7 +115,7 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
public void SelectRandomSkin()
|
public void SelectRandomSkin()
|
||||||
{
|
{
|
||||||
realm.Run(r =>
|
Realm.Run(r =>
|
||||||
{
|
{
|
||||||
// choose from only user skins, removing the current selection to ensure a new one is chosen.
|
// choose from only user skins, removing the current selection to ensure a new one is chosen.
|
||||||
var randomChoices = r.All<SkinInfo>().Where(s => !s.DeletePending && s.ID != CurrentSkinInfo.Value.ID).ToArray();
|
var randomChoices = r.All<SkinInfo>().Where(s => !s.DeletePending && s.ID != CurrentSkinInfo.Value.ID).ToArray();
|
||||||
@ -128,7 +128,7 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
var chosen = randomChoices.ElementAt(RNG.Next(0, randomChoices.Length));
|
var chosen = randomChoices.ElementAt(RNG.Next(0, randomChoices.Length));
|
||||||
|
|
||||||
CurrentSkinInfo.Value = chosen.ToLive(realm);
|
CurrentSkinInfo.Value = chosen.ToLive(Realm);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ namespace osu.Game.Skinning
|
|||||||
if (!s.Protected)
|
if (!s.Protected)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
string[] existingSkinNames = realm.Run(r => r.All<SkinInfo>()
|
string[] existingSkinNames = Realm.Run(r => r.All<SkinInfo>()
|
||||||
.Where(skin => !skin.DeletePending)
|
.Where(skin => !skin.DeletePending)
|
||||||
.AsEnumerable()
|
.AsEnumerable()
|
||||||
.Select(skin => skin.Name).ToArray());
|
.Select(skin => skin.Name).ToArray());
|
||||||
@ -196,7 +196,7 @@ namespace osu.Game.Skinning
|
|||||||
/// <returns>The first result for the provided query, or null if no results were found.</returns>
|
/// <returns>The first result for the provided query, or null if no results were found.</returns>
|
||||||
public Live<SkinInfo> Query(Expression<Func<SkinInfo, bool>> query)
|
public Live<SkinInfo> Query(Expression<Func<SkinInfo, bool>> query)
|
||||||
{
|
{
|
||||||
return realm.Run(r => r.All<SkinInfo>().FirstOrDefault(query)?.ToLive(realm));
|
return Realm.Run(r => r.All<SkinInfo>().FirstOrDefault(query)?.ToLive(Realm));
|
||||||
}
|
}
|
||||||
|
|
||||||
public event Action SourceChanged;
|
public event Action SourceChanged;
|
||||||
@ -251,18 +251,13 @@ namespace osu.Game.Skinning
|
|||||||
AudioManager IStorageResourceProvider.AudioManager => audio;
|
AudioManager IStorageResourceProvider.AudioManager => audio;
|
||||||
IResourceStore<byte[]> IStorageResourceProvider.Resources => resources;
|
IResourceStore<byte[]> IStorageResourceProvider.Resources => resources;
|
||||||
IResourceStore<byte[]> IStorageResourceProvider.Files => userFiles;
|
IResourceStore<byte[]> IStorageResourceProvider.Files => userFiles;
|
||||||
RealmAccess IStorageResourceProvider.RealmAccess => realm;
|
RealmAccess IStorageResourceProvider.RealmAccess => Realm;
|
||||||
IResourceStore<TextureUpload> IStorageResourceProvider.CreateTextureLoaderStore(IResourceStore<byte[]> underlyingStore) => host.CreateTextureLoaderStore(underlyingStore);
|
IResourceStore<TextureUpload> IStorageResourceProvider.CreateTextureLoaderStore(IResourceStore<byte[]> underlyingStore) => host.CreateTextureLoaderStore(underlyingStore);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Implementation of IModelImporter<SkinInfo>
|
#region Implementation of IModelImporter<SkinInfo>
|
||||||
|
|
||||||
public Action<Notification> PostNotification
|
|
||||||
{
|
|
||||||
set => skinImporter.PostNotification = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action<IEnumerable<Live<SkinInfo>>> PostImport
|
public Action<IEnumerable<Live<SkinInfo>>> PostImport
|
||||||
{
|
{
|
||||||
set => skinImporter.PostImport = value;
|
set => skinImporter.PostImport = value;
|
||||||
@ -283,11 +278,9 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Implementation of IModelManager<SkinInfo>
|
|
||||||
|
|
||||||
public void Delete([CanBeNull] Expression<Func<SkinInfo, bool>> filter = null, bool silent = false)
|
public void Delete([CanBeNull] Expression<Func<SkinInfo, bool>> filter = null, bool silent = false)
|
||||||
{
|
{
|
||||||
realm.Run(r =>
|
Realm.Run(r =>
|
||||||
{
|
{
|
||||||
var items = r.All<SkinInfo>()
|
var items = r.All<SkinInfo>()
|
||||||
.Where(s => !s.Protected && !s.DeletePending);
|
.Where(s => !s.Protected && !s.DeletePending);
|
||||||
@ -300,26 +293,8 @@ namespace osu.Game.Skinning
|
|||||||
if (items.Any(s => s.ID == currentUserSkin))
|
if (items.Any(s => s.ID == currentUserSkin))
|
||||||
scheduler.Add(() => CurrentSkinInfo.Value = Skinning.DefaultSkin.CreateInfo().ToLiveUnmanaged());
|
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user