mirror of
https://github.com/ppy/osu.git
synced 2024-11-06 06:17:23 +08:00
Remove CollectionManager
This commit is contained in:
parent
6b73f7c7ec
commit
9c543fef48
@ -5,12 +5,14 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Tests.Resources;
|
||||
|
||||
@ -30,7 +32,11 @@ namespace osu.Game.Tests.Collections.IO
|
||||
|
||||
await importCollectionsFromStream(osu, new MemoryStream());
|
||||
|
||||
Assert.That(osu.CollectionManager.Collections.Count, Is.Zero);
|
||||
osu.Realm.Run(realm =>
|
||||
{
|
||||
var collections = realm.All<RealmBeatmapCollection>().ToList();
|
||||
Assert.That(collections.Count, Is.Zero);
|
||||
});
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -50,18 +56,22 @@ namespace osu.Game.Tests.Collections.IO
|
||||
|
||||
await importCollectionsFromStream(osu, TestResources.OpenResource("Collections/collections.db"));
|
||||
|
||||
Assert.That(osu.CollectionManager.Collections.Count, Is.EqualTo(2));
|
||||
osu.Realm.Run(realm =>
|
||||
{
|
||||
var collections = realm.All<RealmBeatmapCollection>().ToList();
|
||||
Assert.That(collections.Count, Is.EqualTo(2));
|
||||
|
||||
// Even with no beatmaps imported, collections are tracking the hashes and will continue to.
|
||||
// In the future this whole mechanism will be replaced with having the collections in realm,
|
||||
// but until that happens it makes rough sense that we want to track not-yet-imported beatmaps
|
||||
// and have them associate with collections if/when they become available.
|
||||
// Even with no beatmaps imported, collections are tracking the hashes and will continue to.
|
||||
// In the future this whole mechanism will be replaced with having the collections in realm,
|
||||
// but until that happens it makes rough sense that we want to track not-yet-imported beatmaps
|
||||
// and have them associate with collections if/when they become available.
|
||||
|
||||
Assert.That(osu.CollectionManager.Collections[0].Name.Value, Is.EqualTo("First"));
|
||||
Assert.That(osu.CollectionManager.Collections[0].BeatmapHashes.Count, Is.EqualTo(1));
|
||||
Assert.That(collections[0].Name, Is.EqualTo("First"));
|
||||
Assert.That(collections[0].BeatmapMD5Hashes.Count, Is.EqualTo(1));
|
||||
|
||||
Assert.That(osu.CollectionManager.Collections[1].Name.Value, Is.EqualTo("Second"));
|
||||
Assert.That(osu.CollectionManager.Collections[1].BeatmapHashes.Count, Is.EqualTo(12));
|
||||
Assert.That(collections[1].Name, Is.EqualTo("Second"));
|
||||
Assert.That(collections[1].BeatmapMD5Hashes.Count, Is.EqualTo(12));
|
||||
});
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -81,13 +91,18 @@ namespace osu.Game.Tests.Collections.IO
|
||||
|
||||
await importCollectionsFromStream(osu, TestResources.OpenResource("Collections/collections.db"));
|
||||
|
||||
Assert.That(osu.CollectionManager.Collections.Count, Is.EqualTo(2));
|
||||
osu.Realm.Run(realm =>
|
||||
{
|
||||
var collections = realm.All<RealmBeatmapCollection>().ToList();
|
||||
|
||||
Assert.That(osu.CollectionManager.Collections[0].Name.Value, Is.EqualTo("First"));
|
||||
Assert.That(osu.CollectionManager.Collections[0].BeatmapHashes.Count, Is.EqualTo(1));
|
||||
Assert.That(collections.Count, Is.EqualTo(2));
|
||||
|
||||
Assert.That(osu.CollectionManager.Collections[1].Name.Value, Is.EqualTo("Second"));
|
||||
Assert.That(osu.CollectionManager.Collections[1].BeatmapHashes.Count, Is.EqualTo(12));
|
||||
Assert.That(collections[0].Name, Is.EqualTo("First"));
|
||||
Assert.That(collections[0].BeatmapMD5Hashes.Count, Is.EqualTo(1));
|
||||
|
||||
Assert.That(collections[1].Name, Is.EqualTo("Second"));
|
||||
Assert.That(collections[1].BeatmapMD5Hashes.Count, Is.EqualTo(12));
|
||||
});
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -124,7 +139,11 @@ namespace osu.Game.Tests.Collections.IO
|
||||
}
|
||||
|
||||
Assert.That(exceptionThrown, Is.False);
|
||||
Assert.That(osu.CollectionManager.Collections.Count, Is.EqualTo(0));
|
||||
osu.Realm.Run(realm =>
|
||||
{
|
||||
var collections = realm.All<RealmBeatmapCollection>().ToList();
|
||||
Assert.That(collections.Count, Is.EqualTo(0));
|
||||
});
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -149,12 +168,18 @@ namespace osu.Game.Tests.Collections.IO
|
||||
|
||||
await importCollectionsFromStream(osu, TestResources.OpenResource("Collections/collections.db"));
|
||||
|
||||
// Move first beatmap from second collection into the first.
|
||||
osu.CollectionManager.Collections[0].BeatmapHashes.Add(osu.CollectionManager.Collections[1].BeatmapHashes[0]);
|
||||
osu.CollectionManager.Collections[1].BeatmapHashes.RemoveAt(0);
|
||||
// ReSharper disable once MethodHasAsyncOverload
|
||||
osu.Realm.Write(realm =>
|
||||
{
|
||||
var collections = realm.All<RealmBeatmapCollection>().ToList();
|
||||
|
||||
// Rename the second collecction.
|
||||
osu.CollectionManager.Collections[1].Name.Value = "Another";
|
||||
// Move first beatmap from second collection into the first.
|
||||
collections[0].BeatmapMD5Hashes.Add(collections[1].BeatmapMD5Hashes[0]);
|
||||
collections[1].BeatmapMD5Hashes.RemoveAt(0);
|
||||
|
||||
// Rename the second collecction.
|
||||
collections[1].Name = "Another";
|
||||
});
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -169,13 +194,17 @@ namespace osu.Game.Tests.Collections.IO
|
||||
{
|
||||
var osu = LoadOsuIntoHost(host, true);
|
||||
|
||||
Assert.That(osu.CollectionManager.Collections.Count, Is.EqualTo(2));
|
||||
osu.Realm.Run(realm =>
|
||||
{
|
||||
var collections = realm.All<RealmBeatmapCollection>().ToList();
|
||||
Assert.That(collections.Count, Is.EqualTo(2));
|
||||
|
||||
Assert.That(osu.CollectionManager.Collections[0].Name.Value, Is.EqualTo("First"));
|
||||
Assert.That(osu.CollectionManager.Collections[0].BeatmapHashes.Count, Is.EqualTo(2));
|
||||
Assert.That(collections[0].Name, Is.EqualTo("First"));
|
||||
Assert.That(collections[0].BeatmapMD5Hashes.Count, Is.EqualTo(2));
|
||||
|
||||
Assert.That(osu.CollectionManager.Collections[1].Name.Value, Is.EqualTo("Another"));
|
||||
Assert.That(osu.CollectionManager.Collections[1].BeatmapHashes.Count, Is.EqualTo(11));
|
||||
Assert.That(collections[1].Name, Is.EqualTo("Another"));
|
||||
Assert.That(collections[1].BeatmapMD5Hashes.Count, Is.EqualTo(11));
|
||||
});
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -188,7 +217,7 @@ namespace osu.Game.Tests.Collections.IO
|
||||
{
|
||||
// intentionally spin this up on a separate task to avoid disposal deadlocks.
|
||||
// see https://github.com/EventStore/EventStore/issues/1179
|
||||
await Task.Factory.StartNew(() => new LegacyCollectionImporter(osu.CollectionManager).Import(stream).WaitSafely(), TaskCreationOptions.LongRunning);
|
||||
await Task.Factory.StartNew(() => new LegacyCollectionImporter(osu.Realm).Import(stream).WaitSafely(), TaskCreationOptions.LongRunning);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Collections;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Tests.Resources;
|
||||
|
||||
namespace osu.Game.Tests
|
||||
@ -47,7 +47,7 @@ namespace osu.Game.Tests
|
||||
|
||||
public class TestOsuGameBase : OsuGameBase
|
||||
{
|
||||
public CollectionManager CollectionManager { get; private set; }
|
||||
public RealmAccess Realm => Dependencies.Get<RealmAccess>();
|
||||
|
||||
private readonly bool withBeatmap;
|
||||
|
||||
@ -62,8 +62,6 @@ namespace osu.Game.Tests
|
||||
// Beatmap must be imported before the collection manager is loaded.
|
||||
if (withBeatmap)
|
||||
BeatmapManager.Import(TestResources.GetTestBeatmapForImport()).WaitSafely();
|
||||
|
||||
AddInternal(CollectionManager = new CollectionManager());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
@ -27,13 +25,10 @@ namespace osu.Game.Tests.Visual.Collections
|
||||
{
|
||||
protected override Container<Drawable> Content { get; } = new Container { RelativeSizeAxes = Axes.Both };
|
||||
|
||||
private DialogOverlay dialogOverlay;
|
||||
private CollectionManager manager;
|
||||
|
||||
private RulesetStore rulesets;
|
||||
private BeatmapManager beatmapManager;
|
||||
|
||||
private ManageCollectionsDialog dialog;
|
||||
private DialogOverlay dialogOverlay = null!;
|
||||
private RulesetStore rulesets = null!;
|
||||
private BeatmapManager beatmapManager = null!;
|
||||
private ManageCollectionsDialog dialog = null!;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(GameHost host)
|
||||
@ -46,19 +41,17 @@ namespace osu.Game.Tests.Visual.Collections
|
||||
|
||||
base.Content.AddRange(new Drawable[]
|
||||
{
|
||||
manager = new CollectionManager(),
|
||||
Content,
|
||||
dialogOverlay = new DialogOverlay(),
|
||||
});
|
||||
|
||||
Dependencies.Cache(manager);
|
||||
Dependencies.CacheAs<IDialogOverlay>(dialogOverlay);
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void SetUp() => Schedule(() =>
|
||||
{
|
||||
manager.Collections.Clear();
|
||||
Realm.Write(r => r.RemoveAll<RealmBeatmapCollection>());
|
||||
Child = dialog = new ManageCollectionsDialog();
|
||||
});
|
||||
|
||||
@ -78,17 +71,17 @@ namespace osu.Game.Tests.Visual.Collections
|
||||
[Test]
|
||||
public void TestLastItemIsPlaceholder()
|
||||
{
|
||||
AddAssert("last item is placeholder", () => !manager.Collections.Contains(dialog.ChildrenOfType<DrawableCollectionListItem>().Last().Model));
|
||||
AddAssert("last item is placeholder", () => !dialog.ChildrenOfType<DrawableCollectionListItem>().Last().Model.IsManaged);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddCollectionExternal()
|
||||
{
|
||||
AddStep("add collection", () => manager.Collections.Add(new BeatmapCollection { Name = { Value = "First collection" } }));
|
||||
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "First collection"))));
|
||||
assertCollectionCount(1);
|
||||
assertCollectionName(0, "First collection");
|
||||
|
||||
AddStep("add another collection", () => manager.Collections.Add(new BeatmapCollection { Name = { Value = "Second collection" } }));
|
||||
AddStep("add another collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "Second collection"))));
|
||||
assertCollectionCount(2);
|
||||
assertCollectionName(1, "Second collection");
|
||||
}
|
||||
@ -108,7 +101,7 @@ namespace osu.Game.Tests.Visual.Collections
|
||||
[Test]
|
||||
public void TestAddCollectionViaPlaceholder()
|
||||
{
|
||||
DrawableCollectionListItem placeholderItem = null;
|
||||
DrawableCollectionListItem placeholderItem = null!;
|
||||
|
||||
AddStep("focus placeholder", () =>
|
||||
{
|
||||
@ -117,23 +110,31 @@ namespace osu.Game.Tests.Visual.Collections
|
||||
});
|
||||
|
||||
// Done directly via the collection since InputManager methods cannot add text to textbox...
|
||||
AddStep("change collection name", () => placeholderItem.Model.Name.Value = "a");
|
||||
AddStep("change collection name", () => placeholderItem.Model.Name = "a");
|
||||
assertCollectionCount(1);
|
||||
AddAssert("collection now exists", () => manager.Collections.Contains(placeholderItem.Model));
|
||||
AddAssert("collection now exists", () => placeholderItem.Model.IsManaged);
|
||||
|
||||
AddAssert("last item is placeholder", () => !manager.Collections.Contains(dialog.ChildrenOfType<DrawableCollectionListItem>().Last().Model));
|
||||
AddAssert("last item is placeholder", () => !dialog.ChildrenOfType<DrawableCollectionListItem>().Last().Model.IsManaged);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestRemoveCollectionExternal()
|
||||
{
|
||||
AddStep("add two collections", () => manager.Collections.AddRange(new[]
|
||||
{
|
||||
new BeatmapCollection { Name = { Value = "1" } },
|
||||
new BeatmapCollection { Name = { Value = "2" } },
|
||||
}));
|
||||
RealmBeatmapCollection first = null!;
|
||||
|
||||
AddStep("remove first collection", () => manager.Collections.RemoveAt(0));
|
||||
AddStep("add two collections", () =>
|
||||
{
|
||||
Realm.Write(r =>
|
||||
{
|
||||
r.Add(new[]
|
||||
{
|
||||
first = new RealmBeatmapCollection(name: "1"),
|
||||
new RealmBeatmapCollection(name: "2"),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
AddStep("change first collection name", () => Realm.Write(r => r.Remove(first)));
|
||||
assertCollectionCount(1);
|
||||
assertCollectionName(0, "2");
|
||||
}
|
||||
@ -151,21 +152,27 @@ namespace osu.Game.Tests.Visual.Collections
|
||||
Width = 0.4f,
|
||||
});
|
||||
});
|
||||
AddStep("add two collections with same name", () => manager.Collections.AddRange(new[]
|
||||
AddStep("add two collections with same name", () => Realm.Write(r => r.Add(new[]
|
||||
{
|
||||
new BeatmapCollection { Name = { Value = "1" } },
|
||||
new BeatmapCollection { Name = { Value = "1" }, BeatmapHashes = { beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0].MD5Hash } },
|
||||
}));
|
||||
new RealmBeatmapCollection(name: "1"),
|
||||
new RealmBeatmapCollection(name: "1")
|
||||
{
|
||||
BeatmapMD5Hashes = { beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0].MD5Hash }
|
||||
},
|
||||
})));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestRemoveCollectionViaButton()
|
||||
{
|
||||
AddStep("add two collections", () => manager.Collections.AddRange(new[]
|
||||
AddStep("add two collections", () => Realm.Write(r => r.Add(new[]
|
||||
{
|
||||
new BeatmapCollection { Name = { Value = "1" } },
|
||||
new BeatmapCollection { Name = { Value = "2" }, BeatmapHashes = { beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0].MD5Hash } },
|
||||
}));
|
||||
new RealmBeatmapCollection(name: "1"),
|
||||
new RealmBeatmapCollection(name: "2")
|
||||
{
|
||||
BeatmapMD5Hashes = { beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0].MD5Hash }
|
||||
},
|
||||
})));
|
||||
|
||||
assertCollectionCount(2);
|
||||
|
||||
@ -198,10 +205,13 @@ namespace osu.Game.Tests.Visual.Collections
|
||||
[Test]
|
||||
public void TestCollectionNotRemovedWhenDialogCancelled()
|
||||
{
|
||||
AddStep("add two collections", () => manager.Collections.AddRange(new[]
|
||||
AddStep("add collection", () => Realm.Write(r => r.Add(new[]
|
||||
{
|
||||
new BeatmapCollection { Name = { Value = "1" }, BeatmapHashes = { beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0].MD5Hash } },
|
||||
}));
|
||||
new RealmBeatmapCollection(name: "1")
|
||||
{
|
||||
BeatmapMD5Hashes = { beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0].MD5Hash }
|
||||
},
|
||||
})));
|
||||
|
||||
assertCollectionCount(1);
|
||||
|
||||
@ -224,13 +234,21 @@ namespace osu.Game.Tests.Visual.Collections
|
||||
[Test]
|
||||
public void TestCollectionRenamedExternal()
|
||||
{
|
||||
AddStep("add two collections", () => manager.Collections.AddRange(new[]
|
||||
{
|
||||
new BeatmapCollection { Name = { Value = "1" } },
|
||||
new BeatmapCollection { Name = { Value = "2" } },
|
||||
}));
|
||||
RealmBeatmapCollection first = null!;
|
||||
|
||||
AddStep("change first collection name", () => manager.Collections[0].Name.Value = "First");
|
||||
AddStep("add two collections", () =>
|
||||
{
|
||||
Realm.Write(r =>
|
||||
{
|
||||
r.Add(new[]
|
||||
{
|
||||
first = new RealmBeatmapCollection(name: "1"),
|
||||
new RealmBeatmapCollection(name: "2"),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
AddStep("change first collection name", () => Realm.Write(_ => first.Name = "First"));
|
||||
|
||||
assertCollectionName(0, "First");
|
||||
}
|
||||
@ -238,16 +256,24 @@ namespace osu.Game.Tests.Visual.Collections
|
||||
[Test]
|
||||
public void TestCollectionRenamedOnTextChange()
|
||||
{
|
||||
AddStep("add two collections", () => manager.Collections.AddRange(new[]
|
||||
RealmBeatmapCollection first = null!;
|
||||
|
||||
AddStep("add two collections", () =>
|
||||
{
|
||||
new BeatmapCollection { Name = { Value = "1" } },
|
||||
new BeatmapCollection { Name = { Value = "2" } },
|
||||
}));
|
||||
Realm.Write(r =>
|
||||
{
|
||||
r.Add(new[]
|
||||
{
|
||||
first = new RealmBeatmapCollection(name: "1"),
|
||||
new RealmBeatmapCollection(name: "2"),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
assertCollectionCount(2);
|
||||
|
||||
AddStep("change first collection name", () => dialog.ChildrenOfType<TextBox>().First().Text = "First");
|
||||
AddAssert("collection has new name", () => manager.Collections[0].Name.Value == "First");
|
||||
AddUntilStep("collection has new name", () => first.Name == "First");
|
||||
}
|
||||
|
||||
private void assertCollectionCount(int count)
|
||||
|
@ -1,8 +1,6 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
@ -28,12 +26,9 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
{
|
||||
protected override Container<Drawable> Content { get; } = new Container { RelativeSizeAxes = Axes.Both };
|
||||
|
||||
private CollectionManager collectionManager;
|
||||
|
||||
private RulesetStore rulesets;
|
||||
private BeatmapManager beatmapManager;
|
||||
|
||||
private FilterControl control;
|
||||
private RulesetStore rulesets = null!;
|
||||
private BeatmapManager beatmapManager = null!;
|
||||
private FilterControl control = null!;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(GameHost host)
|
||||
@ -46,17 +41,14 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
base.Content.AddRange(new Drawable[]
|
||||
{
|
||||
collectionManager = new CollectionManager(),
|
||||
Content
|
||||
});
|
||||
|
||||
Dependencies.Cache(collectionManager);
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void SetUp() => Schedule(() =>
|
||||
{
|
||||
collectionManager.Collections.Clear();
|
||||
Realm.Write(r => r.RemoveAll<RealmBeatmapCollection>());
|
||||
|
||||
Child = control = new FilterControl
|
||||
{
|
||||
@ -77,8 +69,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
[Test]
|
||||
public void TestCollectionAddedToDropdown()
|
||||
{
|
||||
AddStep("add collection", () => collectionManager.Collections.Add(new BeatmapCollection { Name = { Value = "1" } }));
|
||||
AddStep("add collection", () => collectionManager.Collections.Add(new BeatmapCollection { Name = { Value = "2" } }));
|
||||
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "1"))));
|
||||
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "2"))));
|
||||
assertCollectionDropdownContains("1");
|
||||
assertCollectionDropdownContains("2");
|
||||
}
|
||||
@ -86,9 +78,11 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
[Test]
|
||||
public void TestCollectionRemovedFromDropdown()
|
||||
{
|
||||
AddStep("add collection", () => collectionManager.Collections.Add(new BeatmapCollection { Name = { Value = "1" } }));
|
||||
AddStep("add collection", () => collectionManager.Collections.Add(new BeatmapCollection { Name = { Value = "2" } }));
|
||||
AddStep("remove collection", () => collectionManager.Collections.RemoveAt(0));
|
||||
var first = new RealmBeatmapCollection(name: "1");
|
||||
|
||||
AddStep("add collection", () => Realm.Write(r => r.Add(first)));
|
||||
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "2"))));
|
||||
AddStep("remove collection", () => Realm.Write(r => r.Remove(first)));
|
||||
|
||||
assertCollectionDropdownContains("1", false);
|
||||
assertCollectionDropdownContains("2");
|
||||
@ -97,7 +91,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
[Test]
|
||||
public void TestCollectionRenamed()
|
||||
{
|
||||
AddStep("add collection", () => collectionManager.Collections.Add(new BeatmapCollection { Name = { Value = "1" } }));
|
||||
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "1"))));
|
||||
AddStep("select collection", () =>
|
||||
{
|
||||
var dropdown = control.ChildrenOfType<CollectionFilterDropdown>().Single();
|
||||
@ -106,7 +100,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
addExpandHeaderStep();
|
||||
|
||||
AddStep("change name", () => collectionManager.Collections[0].Name.Value = "First");
|
||||
AddStep("change name", () => Realm.Write(_ => getFirstCollection().Name = "First"));
|
||||
|
||||
assertCollectionDropdownContains("First");
|
||||
assertCollectionHeaderDisplays("First");
|
||||
@ -124,7 +118,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
public void TestCollectionFilterHasAddButton()
|
||||
{
|
||||
addExpandHeaderStep();
|
||||
AddStep("add collection", () => collectionManager.Collections.Add(new BeatmapCollection { Name = { Value = "1" } }));
|
||||
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "1"))));
|
||||
AddStep("hover collection", () => InputManager.MoveMouseTo(getAddOrRemoveButton(1)));
|
||||
AddAssert("collection has add button", () => getAddOrRemoveButton(1).IsPresent);
|
||||
}
|
||||
@ -134,7 +128,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
{
|
||||
addExpandHeaderStep();
|
||||
|
||||
AddStep("add collection", () => collectionManager.Collections.Add(new BeatmapCollection { Name = { Value = "1" } }));
|
||||
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "1"))));
|
||||
|
||||
AddStep("select available beatmap", () => Beatmap.Value = beatmapManager.GetWorkingBeatmap(beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0]));
|
||||
AddAssert("button enabled", () => getAddOrRemoveButton(1).Enabled.Value);
|
||||
@ -150,13 +144,13 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
AddStep("select available beatmap", () => Beatmap.Value = beatmapManager.GetWorkingBeatmap(beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0]));
|
||||
|
||||
AddStep("add collection", () => collectionManager.Collections.Add(new BeatmapCollection { Name = { Value = "1" } }));
|
||||
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "1"))));
|
||||
AddAssert("button is plus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.PlusSquare));
|
||||
|
||||
AddStep("add beatmap to collection", () => collectionManager.Collections[0].BeatmapHashes.Add(Beatmap.Value.BeatmapInfo.MD5Hash));
|
||||
AddStep("add beatmap to collection", () => getFirstCollection().BeatmapMD5Hashes.Add(Beatmap.Value.BeatmapInfo.MD5Hash));
|
||||
AddAssert("button is minus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.MinusSquare));
|
||||
|
||||
AddStep("remove beatmap from collection", () => collectionManager.Collections[0].BeatmapHashes.Clear());
|
||||
AddStep("remove beatmap from collection", () => getFirstCollection().BeatmapMD5Hashes.Clear());
|
||||
AddAssert("button is plus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.PlusSquare));
|
||||
}
|
||||
|
||||
@ -167,15 +161,15 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
AddStep("select available beatmap", () => Beatmap.Value = beatmapManager.GetWorkingBeatmap(beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0]));
|
||||
|
||||
AddStep("add collection", () => collectionManager.Collections.Add(new BeatmapCollection { Name = { Value = "1" } }));
|
||||
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "1"))));
|
||||
AddAssert("button is plus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.PlusSquare));
|
||||
|
||||
addClickAddOrRemoveButtonStep(1);
|
||||
AddAssert("collection contains beatmap", () => collectionManager.Collections[0].BeatmapHashes.Contains(Beatmap.Value.BeatmapInfo.MD5Hash));
|
||||
AddAssert("collection contains beatmap", () => getFirstCollection().BeatmapMD5Hashes.Contains(Beatmap.Value.BeatmapInfo.MD5Hash));
|
||||
AddAssert("button is minus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.MinusSquare));
|
||||
|
||||
addClickAddOrRemoveButtonStep(1);
|
||||
AddAssert("collection does not contain beatmap", () => !collectionManager.Collections[0].BeatmapHashes.Contains(Beatmap.Value.BeatmapInfo.MD5Hash));
|
||||
AddAssert("collection does not contain beatmap", () => !getFirstCollection().BeatmapMD5Hashes.Contains(Beatmap.Value.BeatmapInfo.MD5Hash));
|
||||
AddAssert("button is plus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.PlusSquare));
|
||||
}
|
||||
|
||||
@ -184,7 +178,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
{
|
||||
addExpandHeaderStep();
|
||||
|
||||
AddStep("add collection", () => collectionManager.Collections.Add(new BeatmapCollection { Name = { Value = "1" } }));
|
||||
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "1"))));
|
||||
AddStep("select collection", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(getCollectionDropdownItems().ElementAt(1));
|
||||
@ -202,6 +196,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
AddAssert("collection filter still selected", () => control.CreateCriteria().Collection?.Name.Value == "1");
|
||||
}
|
||||
|
||||
private RealmBeatmapCollection getFirstCollection() => Realm.Run(r => r.All<RealmBeatmapCollection>().First());
|
||||
|
||||
private void assertCollectionHeaderDisplays(string collectionName, bool shouldDisplay = true)
|
||||
=> AddAssert($"collection dropdown header displays '{collectionName}'",
|
||||
() => shouldDisplay == (control.ChildrenOfType<CollectionFilterDropdown.CollectionDropdownHeader>().Single().ChildrenOfType<SpriteText>().First().Text == collectionName));
|
||||
|
@ -16,14 +16,14 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
public List<string> BeatmapMD5Hashes { get; set; } = null!;
|
||||
public IList<string> BeatmapMD5Hashes { get; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// The date when this collection was last modified.
|
||||
/// </summary>
|
||||
public DateTimeOffset LastModified { get; set; }
|
||||
|
||||
public RealmBeatmapCollection(string? name, List<string>? beatmapMD5Hashes)
|
||||
public RealmBeatmapCollection(string? name = null, IList<string>? beatmapMD5Hashes = null)
|
||||
{
|
||||
ID = Guid.NewGuid();
|
||||
Name = name ?? string.Empty;
|
||||
|
@ -46,9 +46,6 @@ namespace osu.Game.Collections
|
||||
[Resolved(CanBeNull = true)]
|
||||
private ManageCollectionsDialog manageCollectionsDialog { get; set; }
|
||||
|
||||
[Resolved(CanBeNull = true)]
|
||||
private CollectionManager collectionManager { get; set; }
|
||||
|
||||
public CollectionFilterDropdown()
|
||||
{
|
||||
ItemSource = filters;
|
||||
@ -59,8 +56,7 @@ namespace osu.Game.Collections
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
if (collectionManager != null)
|
||||
collections.BindTo(collectionManager.Collections);
|
||||
// TODO: bind to realm data
|
||||
|
||||
// Dropdown has logic which triggers a change on the bindable with every change to the contained items.
|
||||
// This is not desirable here, as it leads to multiple filter operations running even though nothing has changed.
|
||||
|
@ -1,62 +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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
using Realms;
|
||||
|
||||
namespace osu.Game.Collections
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles user-defined collections of beatmaps.
|
||||
/// </summary>
|
||||
public class CollectionManager : Component, IPostNotifications
|
||||
{
|
||||
public readonly BindableList<BeatmapCollection> Collections = new BindableList<BeatmapCollection>();
|
||||
|
||||
[Resolved]
|
||||
private RealmAccess realm { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
realm.RegisterForNotifications(r => r.All<RealmBeatmapCollection>(), collectionsChanged);
|
||||
}
|
||||
|
||||
private void collectionsChanged(IRealmCollection<RealmBeatmapCollection> sender, ChangeSet changes, Exception error)
|
||||
{
|
||||
// TODO: hook up with realm changes.
|
||||
|
||||
if (changes == null)
|
||||
{
|
||||
foreach (var collection in sender)
|
||||
Collections.Add(new BeatmapCollection
|
||||
{
|
||||
Name = { Value = collection.Name },
|
||||
BeatmapHashes = { Value = collection.BeatmapMD5Hashes },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public Action<Notification> PostNotification { protected get; set; }
|
||||
|
||||
public void DeleteAll()
|
||||
{
|
||||
Collections.Clear();
|
||||
PostNotification?.Invoke(new ProgressCompletionNotification { Text = "Deleted all collections!" });
|
||||
}
|
||||
}
|
||||
}
|
@ -8,16 +8,16 @@ namespace osu.Game.Collections
|
||||
{
|
||||
public class CollectionToggleMenuItem : ToggleMenuItem
|
||||
{
|
||||
public CollectionToggleMenuItem(BeatmapCollection collection, IBeatmapInfo beatmap)
|
||||
: base(collection.Name.Value, MenuItemType.Standard, state =>
|
||||
public CollectionToggleMenuItem(RealmBeatmapCollection collection, IBeatmapInfo beatmap)
|
||||
: base(collection.Name, MenuItemType.Standard, state =>
|
||||
{
|
||||
if (state)
|
||||
collection.BeatmapHashes.Add(beatmap.MD5Hash);
|
||||
collection.BeatmapMD5Hashes.Add(beatmap.MD5Hash);
|
||||
else
|
||||
collection.BeatmapHashes.Remove(beatmap.MD5Hash);
|
||||
collection.BeatmapMD5Hashes.Remove(beatmap.MD5Hash);
|
||||
})
|
||||
{
|
||||
State.Value = collection.BeatmapHashes.Contains(beatmap.MD5Hash);
|
||||
State.Value = collection.BeatmapMD5Hashes.Contains(beatmap.MD5Hash);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,16 +6,17 @@
|
||||
using System;
|
||||
using Humanizer;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Overlays.Dialog;
|
||||
|
||||
namespace osu.Game.Collections
|
||||
{
|
||||
public class DeleteCollectionDialog : PopupDialog
|
||||
{
|
||||
public DeleteCollectionDialog(BeatmapCollection collection, Action deleteAction)
|
||||
public DeleteCollectionDialog(RealmBeatmapCollection collection, Action deleteAction)
|
||||
{
|
||||
HeaderText = "Confirm deletion of";
|
||||
BodyText = $"{collection.Name.Value} ({"beatmap".ToQuantity(collection.BeatmapHashes.Count)})";
|
||||
BodyText = $"{collection.Name} ({"beatmap".ToQuantity(collection.BeatmapMD5Hashes.Count)})";
|
||||
|
||||
Icon = FontAwesome.Regular.TrashAlt;
|
||||
|
||||
|
@ -7,28 +7,31 @@ using System.Linq;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Collections
|
||||
{
|
||||
/// <summary>
|
||||
/// Visualises a list of <see cref="BeatmapCollection"/>s.
|
||||
/// Visualises a list of <see cref="RealmBeatmapCollection"/>s.
|
||||
/// </summary>
|
||||
public class DrawableCollectionList : OsuRearrangeableListContainer<BeatmapCollection>
|
||||
public class DrawableCollectionList : OsuRearrangeableListContainer<RealmBeatmapCollection>
|
||||
{
|
||||
private Scroll scroll;
|
||||
|
||||
protected override ScrollContainer<Drawable> CreateScrollContainer() => scroll = new Scroll();
|
||||
|
||||
protected override FillFlowContainer<RearrangeableListItem<BeatmapCollection>> CreateListFillFlowContainer() => new Flow
|
||||
protected override FillFlowContainer<RearrangeableListItem<RealmBeatmapCollection>> CreateListFillFlowContainer() => new Flow
|
||||
{
|
||||
DragActive = { BindTarget = DragActive }
|
||||
};
|
||||
|
||||
protected override OsuRearrangeableListItem<BeatmapCollection> CreateOsuDrawable(BeatmapCollection item)
|
||||
// TODO: source from realm
|
||||
|
||||
protected override OsuRearrangeableListItem<RealmBeatmapCollection> CreateOsuDrawable(RealmBeatmapCollection item)
|
||||
{
|
||||
if (item == scroll.PlaceholderItem.Model)
|
||||
if (item.ID == scroll.PlaceholderItem.Model.ID)
|
||||
return scroll.ReplacePlaceholder();
|
||||
|
||||
return new DrawableCollectionListItem(item, true);
|
||||
@ -95,7 +98,7 @@ namespace osu.Game.Collections
|
||||
var previous = PlaceholderItem;
|
||||
|
||||
placeholderContainer.Clear(false);
|
||||
placeholderContainer.Add(PlaceholderItem = new DrawableCollectionListItem(new BeatmapCollection(), false));
|
||||
placeholderContainer.Add(PlaceholderItem = new DrawableCollectionListItem(new RealmBeatmapCollection(), false));
|
||||
|
||||
return previous;
|
||||
}
|
||||
@ -104,7 +107,7 @@ namespace osu.Game.Collections
|
||||
/// <summary>
|
||||
/// The flow of <see cref="DrawableCollectionListItem"/>. Disables layout easing unless a drag is in progress.
|
||||
/// </summary>
|
||||
private class Flow : FillFlowContainer<RearrangeableListItem<BeatmapCollection>>
|
||||
private class Flow : FillFlowContainer<RearrangeableListItem<RealmBeatmapCollection>>
|
||||
{
|
||||
public readonly IBindable<bool> DragActive = new Bindable<bool>();
|
||||
|
||||
|
@ -12,6 +12,8 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
@ -22,15 +24,15 @@ using osuTK.Graphics;
|
||||
namespace osu.Game.Collections
|
||||
{
|
||||
/// <summary>
|
||||
/// Visualises a <see cref="BeatmapCollection"/> inside a <see cref="DrawableCollectionList"/>.
|
||||
/// Visualises a <see cref="RealmBeatmapCollection"/> inside a <see cref="DrawableCollectionList"/>.
|
||||
/// </summary>
|
||||
public class DrawableCollectionListItem : OsuRearrangeableListItem<BeatmapCollection>
|
||||
public class DrawableCollectionListItem : OsuRearrangeableListItem<RealmBeatmapCollection>
|
||||
{
|
||||
private const float item_height = 35;
|
||||
private const float button_width = item_height * 0.75f;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the <see cref="BeatmapCollection"/> currently exists inside the <see cref="CollectionManager"/>.
|
||||
/// Whether the <see cref="RealmBeatmapCollection"/> currently exists inside realm.
|
||||
/// </summary>
|
||||
public IBindable<bool> IsCreated => isCreated;
|
||||
|
||||
@ -39,9 +41,9 @@ namespace osu.Game.Collections
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="DrawableCollectionListItem"/>.
|
||||
/// </summary>
|
||||
/// <param name="item">The <see cref="BeatmapCollection"/>.</param>
|
||||
/// <param name="isCreated">Whether <paramref name="item"/> currently exists inside the <see cref="CollectionManager"/>.</param>
|
||||
public DrawableCollectionListItem(BeatmapCollection item, bool isCreated)
|
||||
/// <param name="item">The <see cref="RealmBeatmapCollection"/>.</param>
|
||||
/// <param name="isCreated">Whether <paramref name="item"/> currently exists inside realm.</param>
|
||||
public DrawableCollectionListItem(RealmBeatmapCollection item, bool isCreated)
|
||||
: base(item)
|
||||
{
|
||||
this.isCreated.Value = isCreated;
|
||||
@ -61,24 +63,18 @@ namespace osu.Game.Collections
|
||||
{
|
||||
public readonly Bindable<bool> IsCreated = new Bindable<bool>();
|
||||
|
||||
private readonly IBindable<string> collectionName;
|
||||
private readonly BeatmapCollection collection;
|
||||
|
||||
[Resolved(CanBeNull = true)]
|
||||
private CollectionManager collectionManager { get; set; }
|
||||
private readonly RealmBeatmapCollection collection;
|
||||
|
||||
private Container textBoxPaddingContainer;
|
||||
private ItemTextBox textBox;
|
||||
|
||||
public ItemContent(BeatmapCollection collection)
|
||||
public ItemContent(RealmBeatmapCollection collection)
|
||||
{
|
||||
this.collection = collection;
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = item_height;
|
||||
Masking = true;
|
||||
|
||||
collectionName = collection.Name.GetBoundCopy();
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -111,14 +107,17 @@ namespace osu.Game.Collections
|
||||
};
|
||||
}
|
||||
|
||||
[Resolved]
|
||||
private RealmAccess realm { get; set; }
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
// Bind late, as the collection name may change externally while still loading.
|
||||
textBox.Current = collection.Name;
|
||||
textBox.Current.Value = collection.Name;
|
||||
textBox.Current.BindValueChanged(_ => createNewCollection(), true);
|
||||
|
||||
collectionName.BindValueChanged(_ => createNewCollection(), true);
|
||||
IsCreated.BindValueChanged(created => textBoxPaddingContainer.Padding = new MarginPadding { Right = created.NewValue ? button_width : 0 }, true);
|
||||
}
|
||||
|
||||
@ -127,11 +126,11 @@ namespace osu.Game.Collections
|
||||
if (IsCreated.Value)
|
||||
return;
|
||||
|
||||
if (string.IsNullOrEmpty(collectionName.Value))
|
||||
if (string.IsNullOrEmpty(textBox.Current.Value))
|
||||
return;
|
||||
|
||||
// Add the new collection and disable our placeholder. If all text is removed, the placeholder should not show back again.
|
||||
collectionManager?.Collections.Add(collection);
|
||||
realm.Write(r => r.Add(collection));
|
||||
textBox.PlaceholderText = string.Empty;
|
||||
|
||||
// When this item changes from placeholder to non-placeholder (via changing containers), its textbox will lose focus, so it needs to be re-focused.
|
||||
@ -162,15 +161,15 @@ namespace osu.Game.Collections
|
||||
[Resolved(CanBeNull = true)]
|
||||
private IDialogOverlay dialogOverlay { get; set; }
|
||||
|
||||
[Resolved(CanBeNull = true)]
|
||||
private CollectionManager collectionManager { get; set; }
|
||||
[Resolved]
|
||||
private RealmAccess realmAccess { get; set; }
|
||||
|
||||
private readonly BeatmapCollection collection;
|
||||
private readonly RealmBeatmapCollection collection;
|
||||
|
||||
private Drawable fadeContainer;
|
||||
private Drawable background;
|
||||
|
||||
public DeleteButton(BeatmapCollection collection)
|
||||
public DeleteButton(RealmBeatmapCollection collection)
|
||||
{
|
||||
this.collection = collection;
|
||||
RelativeSizeAxes = Axes.Y;
|
||||
@ -227,7 +226,7 @@ namespace osu.Game.Collections
|
||||
{
|
||||
background.FlashColour(Color4.White, 150);
|
||||
|
||||
if (collection.BeatmapHashes.Count == 0)
|
||||
if (collection.BeatmapMD5Hashes.Count == 0)
|
||||
deleteCollection();
|
||||
else
|
||||
dialogOverlay?.Push(new DeleteCollectionDialog(collection, deleteCollection));
|
||||
@ -235,7 +234,7 @@ namespace osu.Game.Collections
|
||||
return true;
|
||||
}
|
||||
|
||||
private void deleteCollection() => collectionManager?.Collections.Remove(collection);
|
||||
private void deleteCollection() => realmAccess.Write(r => r.Remove(collection));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
@ -26,9 +25,6 @@ namespace osu.Game.Collections
|
||||
|
||||
private AudioFilter lowPassFilter;
|
||||
|
||||
[Resolved(CanBeNull = true)]
|
||||
private CollectionManager collectionManager { get; set; }
|
||||
|
||||
public ManageCollectionsDialog()
|
||||
{
|
||||
Anchor = Anchor.Centre;
|
||||
@ -107,7 +103,6 @@ namespace osu.Game.Collections
|
||||
new DrawableCollectionList
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Items = { BindTarget = collectionManager?.Collections ?? new BindableList<BeatmapCollection>() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,13 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Collections;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.IO.Legacy;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
@ -17,17 +16,17 @@ namespace osu.Game.Database
|
||||
{
|
||||
public class LegacyCollectionImporter
|
||||
{
|
||||
private readonly CollectionManager collections;
|
||||
public Action<Notification>? PostNotification { protected get; set; }
|
||||
|
||||
public LegacyCollectionImporter(CollectionManager collections)
|
||||
{
|
||||
this.collections = collections;
|
||||
}
|
||||
|
||||
public Action<Notification> PostNotification { protected get; set; }
|
||||
private readonly RealmAccess realm;
|
||||
|
||||
private const string database_name = "collection.db";
|
||||
|
||||
public LegacyCollectionImporter(RealmAccess realm)
|
||||
{
|
||||
this.realm = realm;
|
||||
}
|
||||
|
||||
public Task<int> GetAvailableCount(StableStorage stableStorage)
|
||||
{
|
||||
if (!stableStorage.Exists(database_name))
|
||||
@ -76,26 +75,30 @@ namespace osu.Game.Database
|
||||
notification.State = ProgressNotificationState.Completed;
|
||||
}
|
||||
|
||||
private Task importCollections(List<BeatmapCollection> newCollections)
|
||||
private Task importCollections(List<RealmBeatmapCollection> newCollections)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<bool>();
|
||||
|
||||
// Schedule(() =>
|
||||
// {
|
||||
try
|
||||
{
|
||||
foreach (var newCol in newCollections)
|
||||
realm.Write(r =>
|
||||
{
|
||||
var existing = collections.Collections.FirstOrDefault(c => c.Name.Value == newCol.Name.Value);
|
||||
if (existing == null)
|
||||
collections.Collections.Add(existing = new BeatmapCollection { Name = { Value = newCol.Name.Value } });
|
||||
|
||||
foreach (string newBeatmap in newCol.BeatmapHashes)
|
||||
foreach (var collection in newCollections)
|
||||
{
|
||||
if (!existing.BeatmapHashes.Contains(newBeatmap))
|
||||
existing.BeatmapHashes.Add(newBeatmap);
|
||||
var existing = r.All<RealmBeatmapCollection>().FirstOrDefault(c => c.Name == collection.Name);
|
||||
|
||||
if (existing != null)
|
||||
{
|
||||
foreach (string newBeatmap in existing.BeatmapMD5Hashes)
|
||||
{
|
||||
if (!existing.BeatmapMD5Hashes.Contains(newBeatmap))
|
||||
existing.BeatmapMD5Hashes.Add(newBeatmap);
|
||||
}
|
||||
}
|
||||
else
|
||||
r.Add(collection);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
tcs.SetResult(true);
|
||||
}
|
||||
@ -104,12 +107,11 @@ namespace osu.Game.Database
|
||||
Logger.Error(e, "Failed to import collection.");
|
||||
tcs.SetException(e);
|
||||
}
|
||||
// });
|
||||
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
private List<BeatmapCollection> readCollections(Stream stream, ProgressNotification notification = null)
|
||||
private List<RealmBeatmapCollection> readCollections(Stream stream, ProgressNotification? notification = null)
|
||||
{
|
||||
if (notification != null)
|
||||
{
|
||||
@ -117,7 +119,7 @@ namespace osu.Game.Database
|
||||
notification.Progress = 0;
|
||||
}
|
||||
|
||||
var result = new List<BeatmapCollection>();
|
||||
var result = new List<RealmBeatmapCollection>();
|
||||
|
||||
try
|
||||
{
|
||||
@ -133,7 +135,7 @@ namespace osu.Game.Database
|
||||
if (notification?.CancellationToken.IsCancellationRequested == true)
|
||||
return result;
|
||||
|
||||
var collection = new BeatmapCollection { Name = { Value = sr.ReadString() } };
|
||||
var collection = new RealmBeatmapCollection(sr.ReadString());
|
||||
int mapCount = sr.ReadInt32();
|
||||
|
||||
for (int j = 0; j < mapCount; j++)
|
||||
@ -143,7 +145,7 @@ namespace osu.Game.Database
|
||||
|
||||
string checksum = sr.ReadString();
|
||||
|
||||
collection.BeatmapHashes.Add(checksum);
|
||||
collection.BeatmapMD5Hashes.Add(checksum);
|
||||
}
|
||||
|
||||
if (notification != null)
|
||||
|
@ -13,7 +13,6 @@ using osu.Framework.Extensions.EnumExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Collections;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Settings.Sections.Maintenance;
|
||||
@ -36,15 +35,15 @@ namespace osu.Game.Database
|
||||
[Resolved]
|
||||
private ScoreManager scores { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private CollectionManager collections { get; set; }
|
||||
|
||||
[Resolved(canBeNull: true)]
|
||||
private OsuGame game { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private IDialogOverlay dialogOverlay { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private RealmAccess realmAccess { get; set; }
|
||||
|
||||
[Resolved(canBeNull: true)]
|
||||
private DesktopGameHost desktopGameHost { get; set; }
|
||||
|
||||
@ -72,7 +71,7 @@ namespace osu.Game.Database
|
||||
return await new LegacySkinImporter(skins).GetAvailableCount(stableStorage);
|
||||
|
||||
case StableContent.Collections:
|
||||
return await new LegacyCollectionImporter(collections).GetAvailableCount(stableStorage);
|
||||
return await new LegacyCollectionImporter(realmAccess).GetAvailableCount(stableStorage);
|
||||
|
||||
case StableContent.Scores:
|
||||
return await new LegacyScoreImporter(scores).GetAvailableCount(stableStorage);
|
||||
@ -109,7 +108,7 @@ namespace osu.Game.Database
|
||||
importTasks.Add(new LegacySkinImporter(skins).ImportFromStableAsync(stableStorage));
|
||||
|
||||
if (content.HasFlagFast(StableContent.Collections))
|
||||
importTasks.Add(beatmapImportTask.ContinueWith(_ => new LegacyCollectionImporter(collections).ImportFromStableAsync(stableStorage), TaskContinuationOptions.OnlyOnRanToCompletion));
|
||||
importTasks.Add(beatmapImportTask.ContinueWith(_ => new LegacyCollectionImporter(realmAccess).ImportFromStableAsync(stableStorage), TaskContinuationOptions.OnlyOnRanToCompletion));
|
||||
|
||||
if (content.HasFlagFast(StableContent.Scores))
|
||||
importTasks.Add(beatmapImportTask.ContinueWith(_ => new LegacyScoreImporter(scores).ImportFromStableAsync(stableStorage), TaskContinuationOptions.OnlyOnRanToCompletion));
|
||||
|
@ -858,11 +858,6 @@ namespace osu.Game
|
||||
d.Origin = Anchor.TopRight;
|
||||
}), rightFloatingOverlayContent.Add, true);
|
||||
|
||||
loadComponentSingleFile(new CollectionManager
|
||||
{
|
||||
PostNotification = n => Notifications.Post(n),
|
||||
}, Add, true);
|
||||
|
||||
loadComponentSingleFile(legacyImportManager, Add);
|
||||
|
||||
loadComponentSingleFile(screenshotManager, Add);
|
||||
|
@ -3,9 +3,10 @@
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Collections;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Localisation;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
|
||||
namespace osu.Game.Overlays.Settings.Sections.Maintenance
|
||||
{
|
||||
@ -15,11 +16,15 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
|
||||
|
||||
private SettingsButton importCollectionsButton = null!;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(CollectionManager? collectionManager, LegacyImportManager? legacyImportManager, IDialogOverlay? dialogOverlay)
|
||||
{
|
||||
if (collectionManager == null) return;
|
||||
[Resolved]
|
||||
private RealmAccess realm { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private INotificationOverlay notificationOverlay { get; set; } = null!;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(LegacyImportManager? legacyImportManager, IDialogOverlay? dialogOverlay)
|
||||
{
|
||||
if (legacyImportManager?.SupportsImportFromStable == true)
|
||||
{
|
||||
Add(importCollectionsButton = new SettingsButton
|
||||
@ -38,9 +43,15 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
|
||||
Text = MaintenanceSettingsStrings.DeleteAllCollections,
|
||||
Action = () =>
|
||||
{
|
||||
dialogOverlay?.Push(new MassDeleteConfirmationDialog(collectionManager.DeleteAll));
|
||||
dialogOverlay?.Push(new MassDeleteConfirmationDialog(deleteAllCollections));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void deleteAllCollections()
|
||||
{
|
||||
realm.Write(r => r.RemoveAll<RealmBeatmapCollection>());
|
||||
notificationOverlay.Post(new ProgressCompletionNotification { Text = "Deleted all collections!" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -94,6 +94,9 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
private PanelBackground panelBackground;
|
||||
private FillFlowContainer mainFillFlow;
|
||||
|
||||
[Resolved]
|
||||
private RealmAccess realm { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private RulesetStore rulesets { get; set; }
|
||||
|
||||
@ -112,9 +115,6 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
[Resolved(CanBeNull = true)]
|
||||
private BeatmapSetOverlay beatmapOverlay { get; set; }
|
||||
|
||||
[Resolved(CanBeNull = true)]
|
||||
private CollectionManager collectionManager { get; set; }
|
||||
|
||||
[Resolved(CanBeNull = true)]
|
||||
private ManageCollectionsDialog manageCollectionsDialog { get; set; }
|
||||
|
||||
@ -495,11 +495,11 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
if (beatmapOverlay != null)
|
||||
items.Add(new OsuMenuItem("Details...", MenuItemType.Standard, () => beatmapOverlay.FetchAndShowBeatmap(Item.Beatmap.OnlineID)));
|
||||
|
||||
if (collectionManager != null && beatmap != null)
|
||||
if (beatmap != null)
|
||||
{
|
||||
if (beatmaps.QueryBeatmap(b => b.OnlineID == beatmap.OnlineID) is BeatmapInfo local && !local.BeatmapSet.AsNonNull().DeletePending)
|
||||
{
|
||||
var collectionItems = collectionManager.Collections.Select(c => new CollectionToggleMenuItem(c, beatmap)).Cast<OsuMenuItem>().ToList();
|
||||
var collectionItems = realm.Realm.All<RealmBeatmapCollection>().Select(c => new CollectionToggleMenuItem(c, beatmap)).Cast<OsuMenuItem>().ToList();
|
||||
if (manageCollectionsDialog != null)
|
||||
collectionItems.Add(new OsuMenuItem("Manage...", MenuItemType.Standard, manageCollectionsDialog.Show));
|
||||
|
||||
|
@ -22,6 +22,7 @@ using osu.Framework.Input.Events;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Collections;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Backgrounds;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
@ -63,12 +64,12 @@ namespace osu.Game.Screens.Select.Carousel
|
||||
[Resolved]
|
||||
private BeatmapDifficultyCache difficultyCache { get; set; }
|
||||
|
||||
[Resolved(CanBeNull = true)]
|
||||
private CollectionManager collectionManager { get; set; }
|
||||
|
||||
[Resolved(CanBeNull = true)]
|
||||
private ManageCollectionsDialog manageCollectionsDialog { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private RealmAccess realm { get; set; }
|
||||
|
||||
private IBindable<StarDifficulty?> starDifficultyBindable;
|
||||
private CancellationTokenSource starDifficultyCancellationSource;
|
||||
|
||||
@ -237,14 +238,11 @@ namespace osu.Game.Screens.Select.Carousel
|
||||
if (beatmapInfo.OnlineID > 0 && beatmapOverlay != null)
|
||||
items.Add(new OsuMenuItem("Details...", MenuItemType.Standard, () => beatmapOverlay.FetchAndShowBeatmap(beatmapInfo.OnlineID)));
|
||||
|
||||
if (collectionManager != null)
|
||||
{
|
||||
var collectionItems = collectionManager.Collections.Select(c => new CollectionToggleMenuItem(c, beatmapInfo)).Cast<OsuMenuItem>().ToList();
|
||||
if (manageCollectionsDialog != null)
|
||||
collectionItems.Add(new OsuMenuItem("Manage...", MenuItemType.Standard, manageCollectionsDialog.Show));
|
||||
var collectionItems = realm.Realm.All<RealmBeatmapCollection>().Select(c => new CollectionToggleMenuItem(c, beatmapInfo)).Cast<OsuMenuItem>().ToList();
|
||||
if (manageCollectionsDialog != null)
|
||||
collectionItems.Add(new OsuMenuItem("Manage...", MenuItemType.Standard, manageCollectionsDialog.Show));
|
||||
|
||||
items.Add(new OsuMenuItem("Collections") { Items = collectionItems });
|
||||
}
|
||||
items.Add(new OsuMenuItem("Collections") { Items = collectionItems });
|
||||
|
||||
if (hideRequested != null)
|
||||
items.Add(new OsuMenuItem(CommonStrings.ButtonsHide.ToSentence(), MenuItemType.Destructive, () => hideRequested(beatmapInfo)));
|
||||
|
@ -17,6 +17,7 @@ using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Collections;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Overlays;
|
||||
|
||||
@ -32,12 +33,12 @@ namespace osu.Game.Screens.Select.Carousel
|
||||
[Resolved(CanBeNull = true)]
|
||||
private IDialogOverlay dialogOverlay { get; set; }
|
||||
|
||||
[Resolved(CanBeNull = true)]
|
||||
private CollectionManager collectionManager { get; set; }
|
||||
|
||||
[Resolved(CanBeNull = true)]
|
||||
private ManageCollectionsDialog manageCollectionsDialog { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private RealmAccess realm { get; set; }
|
||||
|
||||
public IEnumerable<DrawableCarouselItem> DrawableBeatmaps => beatmapContainer?.IsLoaded != true ? Enumerable.Empty<DrawableCarouselItem>() : beatmapContainer.AliveChildren;
|
||||
|
||||
[CanBeNull]
|
||||
@ -223,14 +224,11 @@ namespace osu.Game.Screens.Select.Carousel
|
||||
if (beatmapSet.OnlineID > 0 && viewDetails != null)
|
||||
items.Add(new OsuMenuItem("Details...", MenuItemType.Standard, () => viewDetails(beatmapSet.OnlineID)));
|
||||
|
||||
if (collectionManager != null)
|
||||
{
|
||||
var collectionItems = collectionManager.Collections.Select(createCollectionMenuItem).ToList();
|
||||
if (manageCollectionsDialog != null)
|
||||
collectionItems.Add(new OsuMenuItem("Manage...", MenuItemType.Standard, manageCollectionsDialog.Show));
|
||||
var collectionItems = realm.Realm.All<RealmBeatmapCollection>().AsEnumerable().Select(createCollectionMenuItem).ToList();
|
||||
if (manageCollectionsDialog != null)
|
||||
collectionItems.Add(new OsuMenuItem("Manage...", MenuItemType.Standard, manageCollectionsDialog.Show));
|
||||
|
||||
items.Add(new OsuMenuItem("Collections") { Items = collectionItems });
|
||||
}
|
||||
items.Add(new OsuMenuItem("Collections") { Items = collectionItems });
|
||||
|
||||
if (beatmapSet.Beatmaps.Any(b => b.Hidden))
|
||||
items.Add(new OsuMenuItem("Restore all hidden", MenuItemType.Standard, () => restoreHiddenRequested(beatmapSet)));
|
||||
@ -241,13 +239,13 @@ namespace osu.Game.Screens.Select.Carousel
|
||||
}
|
||||
}
|
||||
|
||||
private MenuItem createCollectionMenuItem(BeatmapCollection collection)
|
||||
private MenuItem createCollectionMenuItem(RealmBeatmapCollection collection)
|
||||
{
|
||||
Debug.Assert(beatmapSet != null);
|
||||
|
||||
TernaryState state;
|
||||
|
||||
int countExisting = beatmapSet.Beatmaps.Count(b => collection.BeatmapHashes.Contains(b.MD5Hash));
|
||||
int countExisting = beatmapSet.Beatmaps.Count(b => collection.BeatmapMD5Hashes.Contains(b.MD5Hash));
|
||||
|
||||
if (countExisting == beatmapSet.Beatmaps.Count)
|
||||
state = TernaryState.True;
|
||||
@ -256,21 +254,21 @@ namespace osu.Game.Screens.Select.Carousel
|
||||
else
|
||||
state = TernaryState.False;
|
||||
|
||||
return new TernaryStateToggleMenuItem(collection.Name.Value, MenuItemType.Standard, s =>
|
||||
return new TernaryStateToggleMenuItem(collection.Name, MenuItemType.Standard, s =>
|
||||
{
|
||||
foreach (var b in beatmapSet.Beatmaps)
|
||||
{
|
||||
switch (s)
|
||||
{
|
||||
case TernaryState.True:
|
||||
if (collection.BeatmapHashes.Contains(b.MD5Hash))
|
||||
if (collection.BeatmapMD5Hashes.Contains(b.MD5Hash))
|
||||
continue;
|
||||
|
||||
collection.BeatmapHashes.Add(b.MD5Hash);
|
||||
collection.BeatmapMD5Hashes.Add(b.MD5Hash);
|
||||
break;
|
||||
|
||||
case TernaryState.False:
|
||||
collection.BeatmapHashes.Remove(b.MD5Hash);
|
||||
collection.BeatmapMD5Hashes.Remove(b.MD5Hash);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user