mirror of
https://github.com/osukey/osukey.git
synced 2025-06-24 04:38:02 +09:00
Merge pull request #18733 from peppy/bmm-cleanup
More model importer clean-ups (delete `BeatmapModelManager`)
This commit is contained in:
commit
6df4b16a89
@ -38,7 +38,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using (var importer = new BeatmapModelManager(realm, storage))
|
using (var importer = new BeatmapImporter(realm, storage))
|
||||||
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 BeatmapModelManager(realm, storage))
|
using (var importer = new BeatmapImporter(realm, storage))
|
||||||
using (new RealmRulesetStore(realm, storage))
|
using (new RealmRulesetStore(realm, storage))
|
||||||
{
|
{
|
||||||
Live<BeatmapSetInfo>? beatmapSet;
|
Live<BeatmapSetInfo>? beatmapSet;
|
||||||
@ -141,7 +141,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
BeatmapSetInfo? detachedSet = null;
|
BeatmapSetInfo? detachedSet = null;
|
||||||
|
|
||||||
using (var importer = new BeatmapModelManager(realm, storage))
|
using (var importer = new BeatmapImporter(realm, storage))
|
||||||
using (new RealmRulesetStore(realm, storage))
|
using (new RealmRulesetStore(realm, storage))
|
||||||
{
|
{
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
@ -170,7 +170,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using (var importer = new BeatmapModelManager(realm, storage))
|
using (var importer = new BeatmapImporter(realm, storage))
|
||||||
using (new RealmRulesetStore(realm, storage))
|
using (new RealmRulesetStore(realm, storage))
|
||||||
{
|
{
|
||||||
Live<BeatmapSetInfo>? imported;
|
Live<BeatmapSetInfo>? imported;
|
||||||
@ -202,7 +202,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
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 +214,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
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 +232,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
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 +246,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
using var store = new RealmRulesetStore(realm, storage);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? tempPath = TestResources.GetTestBeatmapForImport();
|
string? tempPath = TestResources.GetTestBeatmapForImport();
|
||||||
@ -276,7 +276,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
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 +296,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
using var store = new RealmRulesetStore(realm, storage);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? temp = TestResources.GetTestBeatmapForImport();
|
string? temp = TestResources.GetTestBeatmapForImport();
|
||||||
@ -345,7 +345,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
using var store = new RealmRulesetStore(realm, storage);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? temp = TestResources.GetTestBeatmapForImport();
|
string? temp = TestResources.GetTestBeatmapForImport();
|
||||||
@ -396,7 +396,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
using var store = new RealmRulesetStore(realm, storage);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? temp = TestResources.GetTestBeatmapForImport();
|
string? temp = TestResources.GetTestBeatmapForImport();
|
||||||
@ -444,7 +444,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
using var store = new RealmRulesetStore(realm, storage);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? temp = TestResources.GetTestBeatmapForImport();
|
string? temp = TestResources.GetTestBeatmapForImport();
|
||||||
@ -492,7 +492,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
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 +527,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
using var store = new RealmRulesetStore(realm, storage);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
var progressNotification = new ImportProgressNotification();
|
var progressNotification = new ImportProgressNotification();
|
||||||
@ -565,7 +565,7 @@ namespace osu.Game.Tests.Database
|
|||||||
Interlocked.Increment(ref loggedExceptionCount);
|
Interlocked.Increment(ref loggedExceptionCount);
|
||||||
};
|
};
|
||||||
|
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
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 +617,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
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 +644,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realmFactory, storage) =>
|
RunTestWithRealmAsync(async (realmFactory, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realmFactory, storage);
|
using var importer = new BeatmapImporter(realmFactory, storage);
|
||||||
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 +676,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
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 +703,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
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 +729,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealm((realm, storage) =>
|
RunTestWithRealm((realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
using var store = new RealmRulesetStore(realm, storage);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
var metadata = new BeatmapMetadata
|
var metadata = new BeatmapMetadata
|
||||||
@ -777,7 +777,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
using var store = new RealmRulesetStore(realm, storage);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? temp = TestResources.GetTestBeatmapForImport();
|
string? temp = TestResources.GetTestBeatmapForImport();
|
||||||
@ -794,7 +794,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
using var store = new RealmRulesetStore(realm, storage);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? temp = TestResources.GetTestBeatmapForImport();
|
string? temp = TestResources.GetTestBeatmapForImport();
|
||||||
@ -830,7 +830,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
using var store = new RealmRulesetStore(realm, storage);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? temp = TestResources.GetTestBeatmapForImport();
|
string? temp = TestResources.GetTestBeatmapForImport();
|
||||||
@ -872,7 +872,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
using var store = new RealmRulesetStore(realm, storage);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? temp = TestResources.GetTestBeatmapForImport();
|
string? temp = TestResources.GetTestBeatmapForImport();
|
||||||
@ -923,7 +923,7 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
RunTestWithRealmAsync(async (realm, storage) =>
|
RunTestWithRealmAsync(async (realm, storage) =>
|
||||||
{
|
{
|
||||||
using var importer = new BeatmapModelManager(realm, storage);
|
using var importer = new BeatmapImporter(realm, storage);
|
||||||
using var store = new RealmRulesetStore(realm, storage);
|
using var store = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
string? temp = TestResources.GetTestBeatmapForImport();
|
string? temp = TestResources.GetTestBeatmapForImport();
|
||||||
|
@ -210,16 +210,16 @@ namespace osu.Game.Tests.Online
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override BeatmapModelManager CreateBeatmapModelManager(Storage storage, RealmAccess realm, RulesetStore rulesets, BeatmapOnlineLookupQueue onlineLookupQueue)
|
protected override BeatmapImporter CreateBeatmapImporter(Storage storage, RealmAccess realm, RulesetStore rulesets, BeatmapOnlineLookupQueue onlineLookupQueue)
|
||||||
{
|
{
|
||||||
return new TestBeatmapModelManager(this, storage, realm, onlineLookupQueue);
|
return new TestBeatmapImporter(this, storage, realm, onlineLookupQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class TestBeatmapModelManager : BeatmapModelManager
|
internal class TestBeatmapImporter : BeatmapImporter
|
||||||
{
|
{
|
||||||
private readonly TestBeatmapManager testBeatmapManager;
|
private readonly TestBeatmapManager testBeatmapManager;
|
||||||
|
|
||||||
public TestBeatmapModelManager(TestBeatmapManager testBeatmapManager, Storage storage, RealmAccess databaseAccess, BeatmapOnlineLookupQueue beatmapOnlineLookupQueue)
|
public TestBeatmapImporter(TestBeatmapManager testBeatmapManager, Storage storage, RealmAccess databaseAccess, BeatmapOnlineLookupQueue beatmapOnlineLookupQueue)
|
||||||
: base(databaseAccess, storage, beatmapOnlineLookupQueue)
|
: base(databaseAccess, storage, 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 abstract class BeatmapImporter : RealmArchiveModelManager<BeatmapSetInfo>, IDisposable
|
public class BeatmapImporter : RealmArchiveModelManager<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;
|
||||||
|
|
||||||
protected BeatmapImporter(RealmAccess realm, Storage storage, BeatmapOnlineLookupQueue? onlineLookupQueue = null)
|
public BeatmapImporter(RealmAccess realm, Storage storage, BeatmapOnlineLookupQueue? onlineLookupQueue = null)
|
||||||
: base(storage, realm)
|
: base(storage, realm)
|
||||||
{
|
{
|
||||||
this.onlineLookupQueue = onlineLookupQueue;
|
this.onlineLookupQueue = onlineLookupQueue;
|
||||||
|
@ -1,19 +1,26 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.IO.Stores;
|
using osu.Framework.IO.Stores;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Beatmaps.Formats;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
|
using osu.Game.Extensions;
|
||||||
using osu.Game.IO.Archives;
|
using osu.Game.IO.Archives;
|
||||||
using osu.Game.Models;
|
using osu.Game.Models;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
@ -23,8 +30,6 @@ using osu.Game.Rulesets;
|
|||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osu.Game.Utils;
|
using osu.Game.Utils;
|
||||||
|
|
||||||
#nullable enable
|
|
||||||
|
|
||||||
namespace osu.Game.Beatmaps
|
namespace osu.Game.Beatmaps
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -35,14 +40,15 @@ namespace osu.Game.Beatmaps
|
|||||||
{
|
{
|
||||||
public ITrackStore BeatmapTrackStore { get; }
|
public ITrackStore BeatmapTrackStore { get; }
|
||||||
|
|
||||||
private readonly BeatmapModelManager beatmapModelManager;
|
private readonly BeatmapImporter beatmapImporter;
|
||||||
|
|
||||||
private readonly WorkingBeatmapCache workingBeatmapCache;
|
private readonly WorkingBeatmapCache workingBeatmapCache;
|
||||||
private readonly BeatmapOnlineLookupQueue? onlineBeatmapLookupQueue;
|
private readonly BeatmapOnlineLookupQueue? onlineBeatmapLookupQueue;
|
||||||
|
|
||||||
private readonly RealmAccess realm;
|
private readonly RealmAccess realm;
|
||||||
|
|
||||||
public BeatmapManager(Storage storage, RealmAccess realm, RulesetStore rulesets, IAPIProvider? api, AudioManager audioManager, IResourceStore<byte[]> gameResources, GameHost? host = null, WorkingBeatmap? defaultBeatmap = null, bool performOnlineLookups = false)
|
public BeatmapManager(Storage storage, RealmAccess realm, RulesetStore rulesets, IAPIProvider? api, AudioManager audioManager, IResourceStore<byte[]> gameResources, GameHost? host = null,
|
||||||
|
WorkingBeatmap? defaultBeatmap = null, bool performOnlineLookups = false)
|
||||||
{
|
{
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
|
|
||||||
@ -58,19 +64,18 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
BeatmapTrackStore = audioManager.GetTrackStore(userResources);
|
BeatmapTrackStore = audioManager.GetTrackStore(userResources);
|
||||||
|
|
||||||
beatmapModelManager = CreateBeatmapModelManager(storage, realm, rulesets, onlineBeatmapLookupQueue);
|
beatmapImporter = CreateBeatmapImporter(storage, realm, rulesets, onlineBeatmapLookupQueue);
|
||||||
workingBeatmapCache = CreateWorkingBeatmapCache(audioManager, gameResources, userResources, defaultBeatmap, host);
|
workingBeatmapCache = CreateWorkingBeatmapCache(audioManager, gameResources, userResources, defaultBeatmap, host);
|
||||||
|
|
||||||
beatmapModelManager.WorkingBeatmapCache = workingBeatmapCache;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual WorkingBeatmapCache CreateWorkingBeatmapCache(AudioManager audioManager, IResourceStore<byte[]> resources, IResourceStore<byte[]> storage, WorkingBeatmap? defaultBeatmap, GameHost? host)
|
protected virtual WorkingBeatmapCache CreateWorkingBeatmapCache(AudioManager audioManager, IResourceStore<byte[]> resources, IResourceStore<byte[]> storage, WorkingBeatmap? defaultBeatmap,
|
||||||
|
GameHost? host)
|
||||||
{
|
{
|
||||||
return new WorkingBeatmapCache(BeatmapTrackStore, audioManager, resources, storage, defaultBeatmap, host);
|
return new WorkingBeatmapCache(BeatmapTrackStore, audioManager, resources, storage, defaultBeatmap, host);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual BeatmapModelManager CreateBeatmapModelManager(Storage storage, RealmAccess realm, RulesetStore rulesets, BeatmapOnlineLookupQueue? onlineLookupQueue) =>
|
protected virtual BeatmapImporter CreateBeatmapImporter(Storage storage, RealmAccess realm, RulesetStore rulesets, BeatmapOnlineLookupQueue? onlineLookupQueue) =>
|
||||||
new BeatmapModelManager(realm, storage, onlineLookupQueue);
|
new BeatmapImporter(realm, storage, 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,
|
||||||
@ -99,7 +104,7 @@ namespace osu.Game.Beatmaps
|
|||||||
foreach (BeatmapInfo b in beatmapSet.Beatmaps)
|
foreach (BeatmapInfo b in beatmapSet.Beatmaps)
|
||||||
b.BeatmapSet = beatmapSet;
|
b.BeatmapSet = beatmapSet;
|
||||||
|
|
||||||
var imported = beatmapModelManager.Import(beatmapSet);
|
var imported = beatmapImporter.Import(beatmapSet);
|
||||||
|
|
||||||
if (imported == null)
|
if (imported == null)
|
||||||
throw new InvalidOperationException("Failed to import new beatmap");
|
throw new InvalidOperationException("Failed to import new beatmap");
|
||||||
@ -169,12 +174,12 @@ namespace osu.Game.Beatmaps
|
|||||||
private WorkingBeatmap addDifficultyToSet(BeatmapSetInfo targetBeatmapSet, IBeatmap newBeatmap, ISkin beatmapSkin)
|
private WorkingBeatmap addDifficultyToSet(BeatmapSetInfo targetBeatmapSet, IBeatmap newBeatmap, ISkin beatmapSkin)
|
||||||
{
|
{
|
||||||
// populate circular beatmap set info <-> beatmap info references manually.
|
// populate circular beatmap set info <-> beatmap info references manually.
|
||||||
// several places like `BeatmapModelManager.Save()` or `GetWorkingBeatmap()`
|
// several places like `Save()` or `GetWorkingBeatmap()`
|
||||||
// rely on them being freely traversable in both directions for correct operation.
|
// rely on them being freely traversable in both directions for correct operation.
|
||||||
targetBeatmapSet.Beatmaps.Add(newBeatmap.BeatmapInfo);
|
targetBeatmapSet.Beatmaps.Add(newBeatmap.BeatmapInfo);
|
||||||
newBeatmap.BeatmapInfo.BeatmapSet = targetBeatmapSet;
|
newBeatmap.BeatmapInfo.BeatmapSet = targetBeatmapSet;
|
||||||
|
|
||||||
beatmapModelManager.Save(newBeatmap.BeatmapInfo, newBeatmap, beatmapSkin);
|
Save(newBeatmap.BeatmapInfo, newBeatmap, beatmapSkin);
|
||||||
|
|
||||||
workingBeatmapCache.Invalidate(targetBeatmapSet);
|
workingBeatmapCache.Invalidate(targetBeatmapSet);
|
||||||
return GetWorkingBeatmap(newBeatmap.BeatmapInfo);
|
return GetWorkingBeatmap(newBeatmap.BeatmapInfo);
|
||||||
@ -255,23 +260,12 @@ namespace osu.Game.Beatmaps
|
|||||||
return realm.Run(r => r.All<BeatmapSetInfo>().FirstOrDefault(query)?.ToLive(realm));
|
return realm.Run(r => r.All<BeatmapSetInfo>().FirstOrDefault(query)?.ToLive(realm));
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Delegation to BeatmapModelManager (methods which previously existed locally).
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Perform a lookup query on available <see cref="BeatmapInfo"/>s.
|
/// Perform a lookup query on available <see cref="BeatmapInfo"/>s.
|
||||||
/// </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) => beatmapModelManager.QueryBeatmap(query)?.Detach();
|
public BeatmapInfo? QueryBeatmap(Expression<Func<BeatmapInfo, bool>> query) => realm.Run(r => r.All<BeatmapInfo>().FirstOrDefault(query)?.Detach());
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Saves an <see cref="IBeatmap"/> file against a given <see cref="BeatmapInfo"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="info">The <see cref="BeatmapInfo"/> to save the content against. The file referenced by <see cref="BeatmapInfo.Path"/> will be replaced.</param>
|
|
||||||
/// <param name="beatmapContent">The <see cref="IBeatmap"/> content to write.</param>
|
|
||||||
/// <param name="beatmapSkin">The beatmap <see cref="ISkin"/> content to write, null if to be omitted.</param>
|
|
||||||
public virtual void Save(BeatmapInfo info, IBeatmap beatmapContent, ISkin? beatmapSkin = null) =>
|
|
||||||
beatmapModelManager.Save(info, beatmapContent, beatmapSkin);
|
|
||||||
|
|
||||||
/// <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.
|
||||||
@ -281,28 +275,76 @@ namespace osu.Game.Beatmaps
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fired when a notification should be presented to the user.
|
/// Fired when a notification should be presented to the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Action<Notification> PostNotification
|
public Action<Notification>? PostNotification
|
||||||
{
|
{
|
||||||
set => beatmapModelManager.PostNotification = value;
|
get => beatmapImporter.PostNotification;
|
||||||
|
set => beatmapImporter.PostNotification = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
/// <summary>
|
||||||
|
/// Saves an <see cref="IBeatmap"/> file against a given <see cref="BeatmapInfo"/>.
|
||||||
#region Implementation of IModelManager<BeatmapSetInfo>
|
/// </summary>
|
||||||
|
/// <param name="beatmapInfo">The <see cref="BeatmapInfo"/> to save the content against. The file referenced by <see cref="BeatmapInfo.Path"/> will be replaced.</param>
|
||||||
public bool IsAvailableLocally(BeatmapSetInfo model)
|
/// <param name="beatmapContent">The <see cref="IBeatmap"/> content to write.</param>
|
||||||
|
/// <param name="beatmapSkin">The beatmap <see cref="ISkin"/> content to write, null if to be omitted.</param>
|
||||||
|
public virtual void Save(BeatmapInfo beatmapInfo, IBeatmap beatmapContent, ISkin? beatmapSkin = null)
|
||||||
{
|
{
|
||||||
return beatmapModelManager.IsAvailableLocally(model);
|
var setInfo = beatmapInfo.BeatmapSet;
|
||||||
|
Debug.Assert(setInfo != null);
|
||||||
|
|
||||||
|
// Difficulty settings must be copied first due to the clone in `Beatmap<>.BeatmapInfo_Set`.
|
||||||
|
// This should hopefully be temporary, assuming said clone is eventually removed.
|
||||||
|
|
||||||
|
// Warning: The directionality here is important. Changes have to be copied *from* beatmapContent (which comes from editor and is being saved)
|
||||||
|
// *to* the beatmapInfo (which is a database model and needs to receive values without the taiko slider velocity multiplier for correct operation).
|
||||||
|
// CopyTo() will undo such adjustments, while CopyFrom() will not.
|
||||||
|
beatmapContent.Difficulty.CopyTo(beatmapInfo.Difficulty);
|
||||||
|
|
||||||
|
// All changes to metadata are made in the provided beatmapInfo, so this should be copied to the `IBeatmap` before encoding.
|
||||||
|
beatmapContent.BeatmapInfo = beatmapInfo;
|
||||||
|
|
||||||
|
using (var stream = new MemoryStream())
|
||||||
|
{
|
||||||
|
using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true))
|
||||||
|
new LegacyBeatmapEncoder(beatmapContent, beatmapSkin).Encode(sw);
|
||||||
|
|
||||||
|
stream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
// AddFile generally handles updating/replacing files, but this is a case where the filename may have also changed so let's delete for simplicity.
|
||||||
|
var existingFileInfo = setInfo.Files.SingleOrDefault(f => string.Equals(f.Filename, beatmapInfo.Path, StringComparison.OrdinalIgnoreCase));
|
||||||
|
string targetFilename = createBeatmapFilenameFromMetadata(beatmapInfo);
|
||||||
|
|
||||||
|
// ensure that two difficulties from the set don't point at the same beatmap file.
|
||||||
|
if (setInfo.Beatmaps.Any(b => b.ID != beatmapInfo.ID && string.Equals(b.Path, targetFilename, StringComparison.OrdinalIgnoreCase)))
|
||||||
|
throw new InvalidOperationException($"{setInfo.GetDisplayString()} already has a difficulty with the name of '{beatmapInfo.DifficultyName}'.");
|
||||||
|
|
||||||
|
if (existingFileInfo != null)
|
||||||
|
DeleteFile(setInfo, existingFileInfo);
|
||||||
|
|
||||||
|
beatmapInfo.MD5Hash = stream.ComputeMD5Hash();
|
||||||
|
beatmapInfo.Hash = stream.ComputeSHA2Hash();
|
||||||
|
|
||||||
|
AddFile(setInfo, stream, createBeatmapFilenameFromMetadata(beatmapInfo));
|
||||||
|
|
||||||
|
realm.Write(r => setInfo.CopyChangesToRealm(r.Find<BeatmapSetInfo>(setInfo.ID)));
|
||||||
|
}
|
||||||
|
|
||||||
|
workingBeatmapCache.Invalidate(beatmapInfo);
|
||||||
|
|
||||||
|
static string createBeatmapFilenameFromMetadata(BeatmapInfo beatmapInfo)
|
||||||
|
{
|
||||||
|
var metadata = beatmapInfo.Metadata;
|
||||||
|
return $"{metadata.Artist} - {metadata.Title} ({metadata.Author.Username}) [{beatmapInfo.DifficultyName}].osu".GetValidArchiveContentFilename();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Delete(BeatmapSetInfo item)
|
public void DeleteAllVideos()
|
||||||
{
|
{
|
||||||
return beatmapModelManager.Delete(item);
|
realm.Write(r =>
|
||||||
}
|
{
|
||||||
|
var items = r.All<BeatmapSetInfo>().Where(s => !s.DeletePending && !s.Protected);
|
||||||
public void Delete(List<BeatmapSetInfo> items, bool silent = false)
|
DeleteVideos(items.ToList());
|
||||||
{
|
});
|
||||||
beatmapModelManager.Delete(items, silent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Delete(Expression<Func<BeatmapSetInfo, bool>>? filter = null, bool silent = false)
|
public void Delete(Expression<Func<BeatmapSetInfo, bool>>? filter = null, bool silent = false)
|
||||||
@ -314,51 +356,92 @@ namespace osu.Game.Beatmaps
|
|||||||
if (filter != null)
|
if (filter != null)
|
||||||
items = items.Where(filter);
|
items = items.Where(filter);
|
||||||
|
|
||||||
beatmapModelManager.Delete(items.ToList(), silent);
|
beatmapImporter.Delete(items.ToList(), silent);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteAllVideos()
|
/// <summary>
|
||||||
|
/// Delete videos from a list of beatmaps.
|
||||||
|
/// This will post notifications tracking progress.
|
||||||
|
/// </summary>
|
||||||
|
public void DeleteVideos(List<BeatmapSetInfo> items, bool silent = false)
|
||||||
{
|
{
|
||||||
realm.Write(r =>
|
if (items.Count == 0) return;
|
||||||
|
|
||||||
|
var notification = new ProgressNotification
|
||||||
{
|
{
|
||||||
var items = r.All<BeatmapSetInfo>().Where(s => !s.DeletePending && !s.Protected);
|
Progress = 0,
|
||||||
beatmapModelManager.DeleteVideos(items.ToList());
|
Text = $"Preparing to delete all {beatmapImporter.HumanisedModelName} videos...",
|
||||||
});
|
CompletionText = "No videos found to delete!",
|
||||||
|
State = ProgressNotificationState.Active,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!silent)
|
||||||
|
PostNotification?.Invoke(notification);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
int deleted = 0;
|
||||||
|
|
||||||
|
foreach (var b in items)
|
||||||
|
{
|
||||||
|
if (notification.State == ProgressNotificationState.Cancelled)
|
||||||
|
// user requested abort
|
||||||
|
return;
|
||||||
|
|
||||||
|
var video = b.Files.FirstOrDefault(f => OsuGameBase.VIDEO_EXTENSIONS.Any(ex => f.Filename.EndsWith(ex, StringComparison.Ordinal)));
|
||||||
|
|
||||||
|
if (video != null)
|
||||||
|
{
|
||||||
|
DeleteFile(b, video);
|
||||||
|
deleted++;
|
||||||
|
notification.CompletionText = $"Deleted {deleted} {beatmapImporter.HumanisedModelName} video(s)!";
|
||||||
|
}
|
||||||
|
|
||||||
|
notification.Text = $"Deleting videos from {beatmapImporter.HumanisedModelName}s ({deleted} deleted)";
|
||||||
|
|
||||||
|
notification.Progress = (float)++i / items.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
notification.State = ProgressNotificationState.Completed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UndeleteAll()
|
public void UndeleteAll()
|
||||||
{
|
{
|
||||||
realm.Run(r => beatmapModelManager.Undelete(r.All<BeatmapSetInfo>().Where(s => s.DeletePending).ToList()));
|
realm.Run(r => beatmapImporter.Undelete(r.All<BeatmapSetInfo>().Where(s => s.DeletePending).ToList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Undelete(List<BeatmapSetInfo> items, bool silent = false)
|
#region Implementation of IModelManager<BeatmapSetInfo>
|
||||||
{
|
|
||||||
beatmapModelManager.Undelete(items, silent);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Undelete(BeatmapSetInfo item)
|
public bool IsAvailableLocally(BeatmapSetInfo model) => beatmapImporter.IsAvailableLocally(model);
|
||||||
{
|
|
||||||
beatmapModelManager.Undelete(item);
|
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
|
#endregion
|
||||||
|
|
||||||
#region Implementation of ICanAcceptFiles
|
#region Implementation of ICanAcceptFiles
|
||||||
|
|
||||||
public Task Import(params string[] paths) => beatmapModelManager.Import(paths);
|
public Task Import(params string[] paths) => beatmapImporter.Import(paths);
|
||||||
|
|
||||||
public Task Import(params ImportTask[] tasks) => beatmapModelManager.Import(tasks);
|
public Task Import(params ImportTask[] tasks) => beatmapImporter.Import(tasks);
|
||||||
|
|
||||||
public Task<IEnumerable<Live<BeatmapSetInfo>>> Import(ProgressNotification notification, params ImportTask[] tasks) => beatmapModelManager.Import(notification, tasks);
|
public Task<IEnumerable<Live<BeatmapSetInfo>>> Import(ProgressNotification notification, params ImportTask[] tasks) => beatmapImporter.Import(notification, tasks);
|
||||||
|
|
||||||
public Task<Live<BeatmapSetInfo>?> Import(ImportTask task, bool batchImport = false, CancellationToken cancellationToken = default) => beatmapModelManager.Import(task, batchImport, cancellationToken);
|
public Task<Live<BeatmapSetInfo>?> Import(ImportTask task, bool batchImport = false, CancellationToken cancellationToken = default) =>
|
||||||
|
beatmapImporter.Import(task, batchImport, cancellationToken);
|
||||||
|
|
||||||
public Task<Live<BeatmapSetInfo>?> Import(ArchiveReader archive, bool batchImport = false, CancellationToken cancellationToken = default) => beatmapModelManager.Import(archive, batchImport, cancellationToken);
|
public Task<Live<BeatmapSetInfo>?> Import(ArchiveReader archive, bool batchImport = false, CancellationToken cancellationToken = default) =>
|
||||||
|
beatmapImporter.Import(archive, batchImport, cancellationToken);
|
||||||
|
|
||||||
public Live<BeatmapSetInfo>? Import(BeatmapSetInfo item, ArchiveReader? archive = null, CancellationToken cancellationToken = default) => beatmapModelManager.Import(item, archive, false, cancellationToken);
|
public Live<BeatmapSetInfo>? Import(BeatmapSetInfo item, ArchiveReader? archive = null, CancellationToken cancellationToken = default) =>
|
||||||
|
beatmapImporter.Import(item, archive, false, cancellationToken);
|
||||||
|
|
||||||
public IEnumerable<string> HandledExtensions => beatmapModelManager.HandledExtensions;
|
public IEnumerable<string> HandledExtensions => beatmapImporter.HandledExtensions;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -400,17 +483,17 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
public void ReplaceFile(BeatmapSetInfo model, RealmNamedFileUsage file, Stream contents)
|
public void ReplaceFile(BeatmapSetInfo model, RealmNamedFileUsage file, Stream contents)
|
||||||
{
|
{
|
||||||
beatmapModelManager.ReplaceFile(model, file, contents);
|
beatmapImporter.ReplaceFile(model, file, contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteFile(BeatmapSetInfo model, RealmNamedFileUsage file)
|
public void DeleteFile(BeatmapSetInfo model, RealmNamedFileUsage file)
|
||||||
{
|
{
|
||||||
beatmapModelManager.DeleteFile(model, file);
|
beatmapImporter.DeleteFile(model, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddFile(BeatmapSetInfo model, Stream contents, string filename)
|
public void AddFile(BeatmapSetInfo model, Stream contents, string filename)
|
||||||
{
|
{
|
||||||
beatmapModelManager.AddFile(model, contents, filename);
|
beatmapImporter.AddFile(model, contents, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -428,7 +511,7 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
public Action<IEnumerable<Live<BeatmapSetInfo>>>? PostImport
|
public Action<IEnumerable<Live<BeatmapSetInfo>>>? PostImport
|
||||||
{
|
{
|
||||||
set => beatmapModelManager.PostImport = value;
|
set => beatmapImporter.PostImport = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -1,163 +0,0 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Text;
|
|
||||||
using osu.Framework.Extensions;
|
|
||||||
using osu.Framework.Platform;
|
|
||||||
using osu.Framework.Testing;
|
|
||||||
using osu.Game.Beatmaps.Formats;
|
|
||||||
using osu.Game.Database;
|
|
||||||
using osu.Game.Extensions;
|
|
||||||
using osu.Game.Skinning;
|
|
||||||
using osu.Game.Overlays.Notifications;
|
|
||||||
|
|
||||||
#nullable enable
|
|
||||||
|
|
||||||
namespace osu.Game.Beatmaps
|
|
||||||
{
|
|
||||||
[ExcludeFromDynamicCompile]
|
|
||||||
public class BeatmapModelManager : BeatmapImporter
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The game working beatmap cache, used to invalidate entries on changes.
|
|
||||||
/// </summary>
|
|
||||||
public IWorkingBeatmapCache? WorkingBeatmapCache { private get; set; }
|
|
||||||
|
|
||||||
public override IEnumerable<string> HandledExtensions => new[] { ".osz" };
|
|
||||||
|
|
||||||
protected override string[] HashableFileTypes => new[] { ".osu" };
|
|
||||||
|
|
||||||
public static readonly string[] VIDEO_EXTENSIONS = { ".mp4", ".mov", ".avi", ".flv" };
|
|
||||||
|
|
||||||
public BeatmapModelManager(RealmAccess realm, Storage storage, BeatmapOnlineLookupQueue? onlineLookupQueue = null)
|
|
||||||
: base(realm, storage, onlineLookupQueue)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Saves an <see cref="IBeatmap"/> file against a given <see cref="BeatmapInfo"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="beatmapInfo">The <see cref="BeatmapInfo"/> to save the content against. The file referenced by <see cref="BeatmapInfo.Path"/> will be replaced.</param>
|
|
||||||
/// <param name="beatmapContent">The <see cref="IBeatmap"/> content to write.</param>
|
|
||||||
/// <param name="beatmapSkin">The beatmap <see cref="ISkin"/> content to write, null if to be omitted.</param>
|
|
||||||
public void Save(BeatmapInfo beatmapInfo, IBeatmap beatmapContent, ISkin? beatmapSkin = null)
|
|
||||||
{
|
|
||||||
var setInfo = beatmapInfo.BeatmapSet;
|
|
||||||
Debug.Assert(setInfo != null);
|
|
||||||
|
|
||||||
// Difficulty settings must be copied first due to the clone in `Beatmap<>.BeatmapInfo_Set`.
|
|
||||||
// This should hopefully be temporary, assuming said clone is eventually removed.
|
|
||||||
|
|
||||||
// Warning: The directionality here is important. Changes have to be copied *from* beatmapContent (which comes from editor and is being saved)
|
|
||||||
// *to* the beatmapInfo (which is a database model and needs to receive values without the taiko slider velocity multiplier for correct operation).
|
|
||||||
// CopyTo() will undo such adjustments, while CopyFrom() will not.
|
|
||||||
beatmapContent.Difficulty.CopyTo(beatmapInfo.Difficulty);
|
|
||||||
|
|
||||||
// All changes to metadata are made in the provided beatmapInfo, so this should be copied to the `IBeatmap` before encoding.
|
|
||||||
beatmapContent.BeatmapInfo = beatmapInfo;
|
|
||||||
|
|
||||||
using (var stream = new MemoryStream())
|
|
||||||
{
|
|
||||||
using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true))
|
|
||||||
new LegacyBeatmapEncoder(beatmapContent, beatmapSkin).Encode(sw);
|
|
||||||
|
|
||||||
stream.Seek(0, SeekOrigin.Begin);
|
|
||||||
|
|
||||||
// AddFile generally handles updating/replacing files, but this is a case where the filename may have also changed so let's delete for simplicity.
|
|
||||||
var existingFileInfo = setInfo.Files.SingleOrDefault(f => string.Equals(f.Filename, beatmapInfo.Path, StringComparison.OrdinalIgnoreCase));
|
|
||||||
string targetFilename = getFilename(beatmapInfo);
|
|
||||||
|
|
||||||
// ensure that two difficulties from the set don't point at the same beatmap file.
|
|
||||||
if (setInfo.Beatmaps.Any(b => b.ID != beatmapInfo.ID && string.Equals(b.Path, targetFilename, StringComparison.OrdinalIgnoreCase)))
|
|
||||||
throw new InvalidOperationException($"{setInfo.GetDisplayString()} already has a difficulty with the name of '{beatmapInfo.DifficultyName}'.");
|
|
||||||
|
|
||||||
if (existingFileInfo != null)
|
|
||||||
DeleteFile(setInfo, existingFileInfo);
|
|
||||||
|
|
||||||
beatmapInfo.MD5Hash = stream.ComputeMD5Hash();
|
|
||||||
beatmapInfo.Hash = stream.ComputeSHA2Hash();
|
|
||||||
|
|
||||||
AddFile(setInfo, stream, getFilename(beatmapInfo));
|
|
||||||
Update(setInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
WorkingBeatmapCache?.Invalidate(beatmapInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string getFilename(BeatmapInfo beatmapInfo)
|
|
||||||
{
|
|
||||||
var metadata = beatmapInfo.Metadata;
|
|
||||||
return $"{metadata.Artist} - {metadata.Title} ({metadata.Author.Username}) [{beatmapInfo.DifficultyName}].osu".GetValidArchiveContentFilename();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Perform a lookup query on available <see cref="BeatmapInfo"/>s.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="query">The query.</param>
|
|
||||||
/// <returns>The first result for the provided query, or null if no results were found.</returns>
|
|
||||||
public BeatmapInfo? QueryBeatmap(Expression<Func<BeatmapInfo, bool>> query)
|
|
||||||
{
|
|
||||||
return Realm.Run(realm => realm.All<BeatmapInfo>().FirstOrDefault(query)?.Detach());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Update(BeatmapSetInfo item)
|
|
||||||
{
|
|
||||||
Realm.Write(r =>
|
|
||||||
{
|
|
||||||
var existing = r.Find<BeatmapSetInfo>(item.ID);
|
|
||||||
item.CopyChangesToRealm(existing);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Delete videos from a list of beatmaps.
|
|
||||||
/// This will post notifications tracking progress.
|
|
||||||
/// </summary>
|
|
||||||
public void DeleteVideos(List<BeatmapSetInfo> items, bool silent = false)
|
|
||||||
{
|
|
||||||
if (items.Count == 0) return;
|
|
||||||
|
|
||||||
var notification = new ProgressNotification
|
|
||||||
{
|
|
||||||
Progress = 0,
|
|
||||||
Text = $"Preparing to delete all {HumanisedModelName} videos...",
|
|
||||||
CompletionText = "No videos found to delete!",
|
|
||||||
State = ProgressNotificationState.Active,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!silent)
|
|
||||||
PostNotification?.Invoke(notification);
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
int deleted = 0;
|
|
||||||
|
|
||||||
foreach (var b in items)
|
|
||||||
{
|
|
||||||
if (notification.State == ProgressNotificationState.Cancelled)
|
|
||||||
// user requested abort
|
|
||||||
return;
|
|
||||||
|
|
||||||
var video = b.Files.FirstOrDefault(f => VIDEO_EXTENSIONS.Any(ex => f.Filename.EndsWith(ex, StringComparison.Ordinal)));
|
|
||||||
|
|
||||||
if (video != null)
|
|
||||||
{
|
|
||||||
DeleteFile(b, video);
|
|
||||||
deleted++;
|
|
||||||
notification.CompletionText = $"Deleted {deleted} {HumanisedModelName} video(s)!";
|
|
||||||
}
|
|
||||||
|
|
||||||
notification.Text = $"Deleting videos from {HumanisedModelName}s ({deleted} deleted)";
|
|
||||||
|
|
||||||
notification.Progress = (float)++i / items.Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
notification.State = ProgressNotificationState.Completed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -72,7 +72,7 @@ namespace osu.Game.Database
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set an endpoint for notifications to be posted to.
|
/// Set an endpoint for notifications to be posted to.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Action<Notification>? PostNotification { protected get; set; }
|
public Action<Notification>? PostNotification { get; set; }
|
||||||
|
|
||||||
protected RealmArchiveModelImporter(Storage storage, RealmAccess realm)
|
protected RealmArchiveModelImporter(Storage storage, RealmAccess realm)
|
||||||
{
|
{
|
||||||
|
@ -8,7 +8,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
@ -67,7 +66,7 @@ namespace osu.Game.Graphics.UserInterfaceV2
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (BeatmapModelManager.VIDEO_EXTENSIONS.Contains(File.Extension))
|
if (OsuGameBase.VIDEO_EXTENSIONS.Contains(File.Extension))
|
||||||
return FontAwesome.Regular.FileVideo;
|
return FontAwesome.Regular.FileVideo;
|
||||||
|
|
||||||
switch (File.Extension)
|
switch (File.Extension)
|
||||||
|
@ -57,6 +57,8 @@ namespace osu.Game
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class OsuGameBase : Framework.Game, ICanAcceptFiles, IBeatSyncProvider
|
public partial class OsuGameBase : Framework.Game, ICanAcceptFiles, IBeatSyncProvider
|
||||||
{
|
{
|
||||||
|
public static readonly string[] VIDEO_EXTENSIONS = { ".mp4", ".mov", ".avi", ".flv" };
|
||||||
|
|
||||||
public const string OSU_PROTOCOL = "osu://";
|
public const string OSU_PROTOCOL = "osu://";
|
||||||
|
|
||||||
public const string CLIENT_STREAM_NAME = @"lazer";
|
public const string CLIENT_STREAM_NAME = @"lazer";
|
||||||
|
@ -19,7 +19,7 @@ using Realms;
|
|||||||
|
|
||||||
namespace osu.Game.Scoring
|
namespace osu.Game.Scoring
|
||||||
{
|
{
|
||||||
public class ScoreModelManager : RealmArchiveModelManager<ScoreInfo>
|
public class ScoreImporter : RealmArchiveModelManager<ScoreInfo>
|
||||||
{
|
{
|
||||||
public override IEnumerable<string> HandledExtensions => new[] { ".osr" };
|
public override IEnumerable<string> HandledExtensions => new[] { ".osr" };
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ namespace osu.Game.Scoring
|
|||||||
private readonly RulesetStore rulesets;
|
private readonly RulesetStore rulesets;
|
||||||
private readonly Func<BeatmapManager> beatmaps;
|
private readonly Func<BeatmapManager> beatmaps;
|
||||||
|
|
||||||
public ScoreModelManager(RulesetStore rulesets, Func<BeatmapManager> beatmaps, Storage storage, RealmAccess realm)
|
public ScoreImporter(RulesetStore rulesets, Func<BeatmapManager> beatmaps, Storage storage, RealmAccess realm)
|
||||||
: base(storage, realm)
|
: base(storage, realm)
|
||||||
{
|
{
|
||||||
this.rulesets = rulesets;
|
this.rulesets = rulesets;
|
@ -28,7 +28,7 @@ namespace osu.Game.Scoring
|
|||||||
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;
|
||||||
private readonly ScoreModelManager scoreModelManager;
|
private readonly ScoreImporter scoreImporter;
|
||||||
|
|
||||||
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)
|
||||||
@ -38,10 +38,10 @@ namespace osu.Game.Scoring
|
|||||||
this.difficulties = difficulties;
|
this.difficulties = difficulties;
|
||||||
this.configManager = configManager;
|
this.configManager = configManager;
|
||||||
|
|
||||||
scoreModelManager = new ScoreModelManager(rulesets, beatmaps, storage, realm);
|
scoreImporter = new ScoreImporter(rulesets, beatmaps, storage, realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Score GetScore(ScoreInfo score) => scoreModelManager.GetScore(score);
|
public Score GetScore(ScoreInfo score) => scoreImporter.GetScore(score);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Perform a lookup query on available <see cref="ScoreInfo"/>s.
|
/// Perform a lookup query on available <see cref="ScoreInfo"/>s.
|
||||||
@ -231,7 +231,7 @@ namespace osu.Game.Scoring
|
|||||||
|
|
||||||
public Action<Notification> PostNotification
|
public Action<Notification> PostNotification
|
||||||
{
|
{
|
||||||
set => scoreModelManager.PostNotification = value;
|
set => scoreImporter.PostNotification = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -240,7 +240,7 @@ namespace osu.Game.Scoring
|
|||||||
|
|
||||||
public bool Delete(ScoreInfo item)
|
public bool Delete(ScoreInfo item)
|
||||||
{
|
{
|
||||||
return scoreModelManager.Delete(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)
|
||||||
@ -253,7 +253,7 @@ namespace osu.Game.Scoring
|
|||||||
if (filter != null)
|
if (filter != null)
|
||||||
items = items.Where(filter);
|
items = items.Where(filter);
|
||||||
|
|
||||||
scoreModelManager.Delete(items.ToList(), silent);
|
scoreImporter.Delete(items.ToList(), silent);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,27 +262,27 @@ namespace osu.Game.Scoring
|
|||||||
realm.Run(r =>
|
realm.Run(r =>
|
||||||
{
|
{
|
||||||
var beatmapScores = r.Find<BeatmapInfo>(beatmap.ID).Scores.ToList();
|
var beatmapScores = r.Find<BeatmapInfo>(beatmap.ID).Scores.ToList();
|
||||||
scoreModelManager.Delete(beatmapScores, silent);
|
scoreImporter.Delete(beatmapScores, silent);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Delete(List<ScoreInfo> items, bool silent = false) => scoreModelManager.Delete(items, silent);
|
public void Delete(List<ScoreInfo> items, bool silent = false) => scoreImporter.Delete(items, silent);
|
||||||
|
|
||||||
public void Undelete(List<ScoreInfo> items, bool silent = false) => scoreModelManager.Undelete(items, silent);
|
public void Undelete(List<ScoreInfo> items, bool silent = false) => scoreImporter.Undelete(items, silent);
|
||||||
|
|
||||||
public void Undelete(ScoreInfo item) => scoreModelManager.Undelete(item);
|
public void Undelete(ScoreInfo item) => scoreImporter.Undelete(item);
|
||||||
|
|
||||||
public Task Import(params string[] paths) => scoreModelManager.Import(paths);
|
public Task Import(params string[] paths) => scoreImporter.Import(paths);
|
||||||
|
|
||||||
public Task Import(params ImportTask[] tasks) => scoreModelManager.Import(tasks);
|
public Task Import(params ImportTask[] tasks) => scoreImporter.Import(tasks);
|
||||||
|
|
||||||
public IEnumerable<string> HandledExtensions => scoreModelManager.HandledExtensions;
|
public IEnumerable<string> HandledExtensions => scoreImporter.HandledExtensions;
|
||||||
|
|
||||||
public Task<IEnumerable<Live<ScoreInfo>>> Import(ProgressNotification notification, params ImportTask[] tasks) => scoreModelManager.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) => scoreModelManager.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) => scoreModelManager.IsAvailableLocally(model);
|
public bool IsAvailableLocally(ScoreInfo model) => scoreImporter.IsAvailableLocally(model);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -290,7 +290,7 @@ namespace osu.Game.Scoring
|
|||||||
|
|
||||||
public Action<IEnumerable<Live<ScoreInfo>>> PostImport
|
public Action<IEnumerable<Live<ScoreInfo>>> PostImport
|
||||||
{
|
{
|
||||||
set => scoreModelManager.PostImport = value;
|
set => scoreImporter.PostImport = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -20,13 +20,13 @@ using Realms;
|
|||||||
|
|
||||||
namespace osu.Game.Skinning
|
namespace osu.Game.Skinning
|
||||||
{
|
{
|
||||||
public class SkinModelManager : RealmArchiveModelManager<SkinInfo>
|
public class SkinImporter : RealmArchiveModelManager<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;
|
||||||
|
|
||||||
public SkinModelManager(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;
|
@ -55,7 +55,7 @@ namespace osu.Game.Skinning
|
|||||||
Default = Skinning.DefaultSkin.CreateInfo().ToLiveUnmanaged()
|
Default = Skinning.DefaultSkin.CreateInfo().ToLiveUnmanaged()
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly SkinModelManager skinModelManager;
|
private readonly SkinImporter skinImporter;
|
||||||
private readonly RealmAccess realm;
|
private readonly RealmAccess realm;
|
||||||
|
|
||||||
private readonly IResourceStore<byte[]> userFiles;
|
private readonly IResourceStore<byte[]> userFiles;
|
||||||
@ -80,7 +80,7 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
userFiles = new StorageBackedResourceStore(storage.GetStorageForDirectory("files"));
|
userFiles = new StorageBackedResourceStore(storage.GetStorageForDirectory("files"));
|
||||||
|
|
||||||
skinModelManager = new SkinModelManager(storage, realm, this);
|
skinImporter = new SkinImporter(storage, realm, this);
|
||||||
|
|
||||||
var defaultSkins = new[]
|
var defaultSkins = new[]
|
||||||
{
|
{
|
||||||
@ -166,7 +166,7 @@ namespace osu.Game.Skinning
|
|||||||
Name = NamingUtils.GetNextBestName(existingSkinNames, $@"{s.Name} (modified)")
|
Name = NamingUtils.GetNextBestName(existingSkinNames, $@"{s.Name} (modified)")
|
||||||
};
|
};
|
||||||
|
|
||||||
var result = skinModelManager.Import(skinInfo);
|
var result = skinImporter.Import(skinInfo);
|
||||||
|
|
||||||
if (result != null)
|
if (result != null)
|
||||||
{
|
{
|
||||||
@ -186,7 +186,7 @@ namespace osu.Game.Skinning
|
|||||||
if (!skin.SkinInfo.IsManaged)
|
if (!skin.SkinInfo.IsManaged)
|
||||||
throw new InvalidOperationException($"Attempting to save a skin which is not yet tracked. Call {nameof(EnsureMutableSkin)} first.");
|
throw new InvalidOperationException($"Attempting to save a skin which is not yet tracked. Call {nameof(EnsureMutableSkin)} first.");
|
||||||
|
|
||||||
skinModelManager.Save(skin);
|
skinImporter.Save(skin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -260,26 +260,26 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
public Action<Notification> PostNotification
|
public Action<Notification> PostNotification
|
||||||
{
|
{
|
||||||
set => skinModelManager.PostNotification = value;
|
set => skinImporter.PostNotification = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Action<IEnumerable<Live<SkinInfo>>> PostImport
|
public Action<IEnumerable<Live<SkinInfo>>> PostImport
|
||||||
{
|
{
|
||||||
set => skinModelManager.PostImport = value;
|
set => skinImporter.PostImport = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task Import(params string[] paths) => skinModelManager.Import(paths);
|
public Task Import(params string[] paths) => skinImporter.Import(paths);
|
||||||
|
|
||||||
public Task Import(params ImportTask[] tasks) => skinModelManager.Import(tasks);
|
public Task Import(params ImportTask[] tasks) => skinImporter.Import(tasks);
|
||||||
|
|
||||||
public IEnumerable<string> HandledExtensions => skinModelManager.HandledExtensions;
|
public IEnumerable<string> HandledExtensions => skinImporter.HandledExtensions;
|
||||||
|
|
||||||
public Task<IEnumerable<Live<SkinInfo>>> Import(ProgressNotification notification, params ImportTask[] tasks) => skinModelManager.Import(notification, tasks);
|
public Task<IEnumerable<Live<SkinInfo>>> Import(ProgressNotification notification, params ImportTask[] tasks) => skinImporter.Import(notification, tasks);
|
||||||
|
|
||||||
public Task<Live<SkinInfo>> Import(ImportTask task, bool batchImport = false, CancellationToken cancellationToken = default) => skinModelManager.Import(task, batchImport, cancellationToken);
|
public Task<Live<SkinInfo>> Import(ImportTask task, bool batchImport = false, CancellationToken cancellationToken = default) => skinImporter.Import(task, batchImport, cancellationToken);
|
||||||
|
|
||||||
public Task<Live<SkinInfo>> Import(ArchiveReader archive, bool batchImport = false, CancellationToken cancellationToken = default) =>
|
public Task<Live<SkinInfo>> Import(ArchiveReader archive, bool batchImport = false, CancellationToken cancellationToken = default) =>
|
||||||
skinModelManager.Import(archive, batchImport, cancellationToken);
|
skinImporter.Import(archive, batchImport, cancellationToken);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -300,25 +300,25 @@ 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());
|
||||||
|
|
||||||
skinModelManager.Delete(items.ToList(), silent);
|
skinImporter.Delete(items.ToList(), silent);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Delete(SkinInfo item) => skinModelManager.Delete(item);
|
public bool Delete(SkinInfo item) => skinImporter.Delete(item);
|
||||||
|
|
||||||
public void Delete(List<SkinInfo> items, bool silent = false) => skinModelManager.Delete(items, silent);
|
public void Delete(List<SkinInfo> items, bool silent = false) => skinImporter.Delete(items, silent);
|
||||||
|
|
||||||
public void Undelete(List<SkinInfo> items, bool silent = false) => skinModelManager.Undelete(items, silent);
|
public void Undelete(List<SkinInfo> items, bool silent = false) => skinImporter.Undelete(items, silent);
|
||||||
|
|
||||||
public void Undelete(SkinInfo item) => skinModelManager.Undelete(item);
|
public void Undelete(SkinInfo item) => skinImporter.Undelete(item);
|
||||||
|
|
||||||
public bool IsAvailableLocally(SkinInfo model) => skinModelManager.IsAvailableLocally(model);
|
public bool IsAvailableLocally(SkinInfo model) => skinImporter.IsAvailableLocally(model);
|
||||||
|
|
||||||
public void ReplaceFile(SkinInfo model, RealmNamedFileUsage file, Stream contents) => skinModelManager.ReplaceFile(model, file, contents);
|
public void ReplaceFile(SkinInfo model, RealmNamedFileUsage file, Stream contents) => skinImporter.ReplaceFile(model, file, contents);
|
||||||
|
|
||||||
public void DeleteFile(SkinInfo model, RealmNamedFileUsage file) => skinModelManager.DeleteFile(model, file);
|
public void DeleteFile(SkinInfo model, RealmNamedFileUsage file) => skinImporter.DeleteFile(model, file);
|
||||||
|
|
||||||
public void AddFile(SkinInfo model, Stream contents, string filename) => skinModelManager.AddFile(model, contents, filename);
|
public void AddFile(SkinInfo model, Stream contents, string filename) => skinImporter.AddFile(model, contents, filename);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -145,11 +145,6 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override BeatmapModelManager CreateBeatmapModelManager(Storage storage, RealmAccess realm, RulesetStore rulesets, BeatmapOnlineLookupQueue onlineLookupQueue)
|
|
||||||
{
|
|
||||||
return new BeatmapModelManager(realm, storage, onlineLookupQueue);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override WorkingBeatmapCache CreateWorkingBeatmapCache(AudioManager audioManager, IResourceStore<byte[]> resources, IResourceStore<byte[]> storage, WorkingBeatmap defaultBeatmap, GameHost host)
|
protected override WorkingBeatmapCache CreateWorkingBeatmapCache(AudioManager audioManager, IResourceStore<byte[]> resources, IResourceStore<byte[]> storage, WorkingBeatmap defaultBeatmap, GameHost host)
|
||||||
{
|
{
|
||||||
return new TestWorkingBeatmapCache(this, audioManager, resources, storage, defaultBeatmap, host);
|
return new TestWorkingBeatmapCache(this, audioManager, resources, storage, defaultBeatmap, host);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user