Merge branch 'master' into kps

This commit is contained in:
Ryuki 2022-07-28 18:38:09 +02:00
commit 2df24019fd
No known key found for this signature in database
GPG Key ID: A353889EAEACBF49
136 changed files with 1197 additions and 1210 deletions

View File

@ -1,8 +1,6 @@
// 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 disable
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;

View File

@ -1,8 +1,6 @@
// 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 disable
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;

View File

@ -1,8 +1,6 @@
// 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 disable
using NUnit.Framework; using NUnit.Framework;
using osu.Game.Rulesets.Mania.Mods; using osu.Game.Rulesets.Mania.Mods;
using osu.Game.Tests.Visual; using osu.Game.Tests.Visual;

View File

@ -1,8 +1,6 @@
// 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 disable
using NUnit.Framework; using NUnit.Framework;
using osu.Game.Rulesets.Mania.Mods; using osu.Game.Rulesets.Mania.Mods;
using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects;

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods

View File

@ -1,8 +1,6 @@
// 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 disable
using System; using System;
using System.Linq; using System.Linq;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;

View File

@ -1,8 +1,6 @@
// 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 disable
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Beatmaps;

View File

@ -1,8 +1,6 @@
// 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 disable
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Beatmaps;

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects;

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods

View File

@ -1,8 +1,6 @@
// 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 disable
using System; using System;
using System.Linq; using System.Linq;
using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Mania.UI;

View File

@ -1,8 +1,6 @@
// 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 disable
using System; using System;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods

View File

@ -1,8 +1,6 @@
// 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 disable
using System; using System;
using System.Linq; using System.Linq;
using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Mania.UI;

View File

@ -1,8 +1,6 @@
// 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 disable
using System; using System;
using System.Linq; using System.Linq;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;

View File

@ -1,8 +1,6 @@
// 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 disable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;

View File

@ -1,8 +1,6 @@
// 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 disable
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods
{ {
public class ManiaModKey1 : ManiaKeyMod public class ManiaModKey1 : ManiaKeyMod

View File

@ -1,8 +1,6 @@
// 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 disable
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods
{ {
public class ManiaModKey10 : ManiaKeyMod public class ManiaModKey10 : ManiaKeyMod

View File

@ -1,8 +1,6 @@
// 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 disable
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods
{ {
public class ManiaModKey2 : ManiaKeyMod public class ManiaModKey2 : ManiaKeyMod

View File

@ -1,8 +1,6 @@
// 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 disable
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods
{ {
public class ManiaModKey3 : ManiaKeyMod public class ManiaModKey3 : ManiaKeyMod

View File

@ -1,8 +1,6 @@
// 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 disable
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods
{ {
public class ManiaModKey4 : ManiaKeyMod public class ManiaModKey4 : ManiaKeyMod

View File

@ -1,8 +1,6 @@
// 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 disable
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods
{ {
public class ManiaModKey5 : ManiaKeyMod public class ManiaModKey5 : ManiaKeyMod

View File

@ -1,8 +1,6 @@
// 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 disable
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods
{ {
public class ManiaModKey6 : ManiaKeyMod public class ManiaModKey6 : ManiaKeyMod

View File

@ -1,8 +1,6 @@
// 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 disable
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods
{ {
public class ManiaModKey7 : ManiaKeyMod public class ManiaModKey7 : ManiaKeyMod

View File

@ -1,8 +1,6 @@
// 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 disable
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods
{ {
public class ManiaModKey8 : ManiaKeyMod public class ManiaModKey8 : ManiaKeyMod

View File

@ -1,8 +1,6 @@
// 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 disable
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods
{ {
public class ManiaModKey9 : ManiaKeyMod public class ManiaModKey9 : ManiaKeyMod

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods

View File

@ -1,8 +1,6 @@
// 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 disable
using System; using System;
using System.Linq; using System.Linq;
using osu.Framework.Graphics; using osu.Framework.Graphics;

View File

@ -1,8 +1,6 @@
// 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 disable
using System; using System;
using System.Linq; using System.Linq;
using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Extensions.IEnumerableExtensions;

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Tests.Visual; using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Taiko.Tests.Mods namespace osu.Game.Rulesets.Taiko.Tests.Mods

View File

@ -1,8 +1,6 @@
// 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 disable
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Game.Rulesets.Taiko.Mods; using osu.Game.Rulesets.Taiko.Mods;

View File

@ -1,8 +1,6 @@
// 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 disable
using NUnit.Framework; using NUnit.Framework;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Mods; using osu.Game.Rulesets.Taiko.Mods;

View File

@ -1,8 +1,6 @@
// 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 disable
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;

View File

@ -1,8 +1,6 @@
// 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 disable
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;

View File

@ -1,8 +1,7 @@
// 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 disable using System.Diagnostics;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.Taiko.UI; using osu.Game.Rulesets.Taiko.UI;
@ -12,7 +11,7 @@ namespace osu.Game.Rulesets.Taiko.Mods
{ {
public class TaikoModClassic : ModClassic, IApplicableToDrawableRuleset<TaikoHitObject>, IUpdatableByPlayfield public class TaikoModClassic : ModClassic, IApplicableToDrawableRuleset<TaikoHitObject>, IUpdatableByPlayfield
{ {
private DrawableTaikoRuleset drawableTaikoRuleset; private DrawableTaikoRuleset? drawableTaikoRuleset;
public void ApplyToDrawableRuleset(DrawableRuleset<TaikoHitObject> drawableRuleset) public void ApplyToDrawableRuleset(DrawableRuleset<TaikoHitObject> drawableRuleset)
{ {
@ -25,6 +24,8 @@ namespace osu.Game.Rulesets.Taiko.Mods
public void Update(Playfield playfield) public void Update(Playfield playfield)
{ {
Debug.Assert(drawableTaikoRuleset != null);
// Classic taiko scrolls at a constant 100px per 1000ms. More notes become visible as the playfield is lengthened. // Classic taiko scrolls at a constant 100px per 1000ms. More notes become visible as the playfield is lengthened.
const float scroll_rate = 10; const float scroll_rate = 10;

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Taiko.Mods namespace osu.Game.Rulesets.Taiko.Mods

View File

@ -1,8 +1,6 @@
// 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 disable
using System.Linq; using System.Linq;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Configuration; using osu.Game.Configuration;

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Taiko.Mods namespace osu.Game.Rulesets.Taiko.Mods

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;

View File

@ -1,9 +1,8 @@
// 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 disable
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Layout; using osu.Framework.Layout;
using osu.Game.Configuration; using osu.Game.Configuration;
@ -38,9 +37,9 @@ namespace osu.Game.Rulesets.Taiko.Mods
public override float DefaultFlashlightSize => 250; public override float DefaultFlashlightSize => 250;
protected override Flashlight CreateFlashlight() => new TaikoFlashlight(this, playfield); protected override Flashlight CreateFlashlight() => new TaikoFlashlight(this, playfield.AsNonNull());
private TaikoPlayfield playfield; private TaikoPlayfield? playfield;
public override void ApplyToDrawableRuleset(DrawableRuleset<TaikoHitObject> drawableRuleset) public override void ApplyToDrawableRuleset(DrawableRuleset<TaikoHitObject> drawableRuleset)
{ {

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Taiko.Mods namespace osu.Game.Rulesets.Taiko.Mods

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;

View File

@ -1,8 +1,7 @@
// 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 disable using System.Diagnostics;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
@ -32,7 +31,7 @@ namespace osu.Game.Rulesets.Taiko.Mods
/// </summary> /// </summary>
private const float fade_out_duration = 0.375f; private const float fade_out_duration = 0.375f;
private DrawableTaikoRuleset drawableRuleset; private DrawableTaikoRuleset? drawableRuleset;
public void ApplyToDrawableRuleset(DrawableRuleset<TaikoHitObject> drawableRuleset) public void ApplyToDrawableRuleset(DrawableRuleset<TaikoHitObject> drawableRuleset)
{ {
@ -46,6 +45,8 @@ namespace osu.Game.Rulesets.Taiko.Mods
protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state)
{ {
Debug.Assert(drawableRuleset != null);
switch (hitObject) switch (hitObject)
{ {
case DrawableDrumRollTick: case DrawableDrumRollTick:

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Objects;

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Objects;

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Taiko.Mods namespace osu.Game.Rulesets.Taiko.Mods

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Taiko.Mods namespace osu.Game.Rulesets.Taiko.Mods

View File

@ -1,8 +1,6 @@
// 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 disable
using System; using System;
using System.Linq; using System.Linq;
using osu.Framework.Utils; using osu.Framework.Utils;

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Taiko.Mods namespace osu.Game.Rulesets.Taiko.Mods

View File

@ -1,8 +1,6 @@
// 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 disable
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Taiko.Mods namespace osu.Game.Rulesets.Taiko.Mods

View File

@ -1,8 +1,6 @@
// 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 disable
using System; using System;
using System.Linq; using System.Linq;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;

View File

@ -26,7 +26,7 @@ namespace osu.Game.Tests.Beatmaps
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio, RulesetStore rulesets) private void load(GameHost host, AudioManager audio, RulesetStore rulesets)
{ {
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
} }
[SetUpSteps] [SetUpSteps]

View File

@ -5,12 +5,15 @@
using System; using System;
using System.IO; using System.IO;
using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Extensions; using osu.Framework.Extensions;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Collections;
using osu.Game.Database;
using osu.Game.Tests.Resources; using osu.Game.Tests.Resources;
namespace osu.Game.Tests.Collections.IO namespace osu.Game.Tests.Collections.IO
@ -29,7 +32,11 @@ namespace osu.Game.Tests.Collections.IO
await importCollectionsFromStream(osu, new MemoryStream()); await importCollectionsFromStream(osu, new MemoryStream());
Assert.That(osu.CollectionManager.Collections.Count, Is.Zero); osu.Realm.Run(realm =>
{
var collections = realm.All<BeatmapCollection>().ToList();
Assert.That(collections.Count, Is.Zero);
});
} }
finally finally
{ {
@ -49,18 +56,22 @@ namespace osu.Game.Tests.Collections.IO
await importCollectionsFromStream(osu, TestResources.OpenResource("Collections/collections.db")); 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<BeatmapCollection>().ToList();
Assert.That(collections.Count, Is.EqualTo(2));
// Even with no beatmaps imported, collections are tracking the hashes and will continue to. // 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, // 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 // 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. // and have them associate with collections if/when they become available.
Assert.That(osu.CollectionManager.Collections[0].Name.Value, Is.EqualTo("First")); Assert.That(collections[0].Name, Is.EqualTo("First"));
Assert.That(osu.CollectionManager.Collections[0].BeatmapHashes.Count, Is.EqualTo(1)); Assert.That(collections[0].BeatmapMD5Hashes.Count, Is.EqualTo(1));
Assert.That(osu.CollectionManager.Collections[1].Name.Value, Is.EqualTo("Second")); Assert.That(collections[1].Name, Is.EqualTo("Second"));
Assert.That(osu.CollectionManager.Collections[1].BeatmapHashes.Count, Is.EqualTo(12)); Assert.That(collections[1].BeatmapMD5Hashes.Count, Is.EqualTo(12));
});
} }
finally finally
{ {
@ -80,13 +91,18 @@ namespace osu.Game.Tests.Collections.IO
await importCollectionsFromStream(osu, TestResources.OpenResource("Collections/collections.db")); 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<BeatmapCollection>().ToList();
Assert.That(osu.CollectionManager.Collections[0].Name.Value, Is.EqualTo("First")); Assert.That(collections.Count, Is.EqualTo(2));
Assert.That(osu.CollectionManager.Collections[0].BeatmapHashes.Count, Is.EqualTo(1));
Assert.That(osu.CollectionManager.Collections[1].Name.Value, Is.EqualTo("Second")); Assert.That(collections[0].Name, Is.EqualTo("First"));
Assert.That(osu.CollectionManager.Collections[1].BeatmapHashes.Count, Is.EqualTo(12)); 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 finally
{ {
@ -123,7 +139,11 @@ namespace osu.Game.Tests.Collections.IO
} }
Assert.That(exceptionThrown, Is.False); Assert.That(exceptionThrown, Is.False);
Assert.That(osu.CollectionManager.Collections.Count, Is.EqualTo(0)); osu.Realm.Run(realm =>
{
var collections = realm.All<BeatmapCollection>().ToList();
Assert.That(collections.Count, Is.EqualTo(0));
});
} }
finally finally
{ {
@ -148,12 +168,18 @@ namespace osu.Game.Tests.Collections.IO
await importCollectionsFromStream(osu, TestResources.OpenResource("Collections/collections.db")); await importCollectionsFromStream(osu, TestResources.OpenResource("Collections/collections.db"));
// Move first beatmap from second collection into the first. // ReSharper disable once MethodHasAsyncOverload
osu.CollectionManager.Collections[0].BeatmapHashes.Add(osu.CollectionManager.Collections[1].BeatmapHashes[0]); osu.Realm.Write(realm =>
osu.CollectionManager.Collections[1].BeatmapHashes.RemoveAt(0); {
var collections = realm.All<BeatmapCollection>().ToList();
// Rename the second collecction. // Move first beatmap from second collection into the first.
osu.CollectionManager.Collections[1].Name.Value = "Another"; collections[0].BeatmapMD5Hashes.Add(collections[1].BeatmapMD5Hashes[0]);
collections[1].BeatmapMD5Hashes.RemoveAt(0);
// Rename the second collecction.
collections[1].Name = "Another";
});
} }
finally finally
{ {
@ -168,13 +194,17 @@ namespace osu.Game.Tests.Collections.IO
{ {
var osu = LoadOsuIntoHost(host, true); var osu = LoadOsuIntoHost(host, true);
Assert.That(osu.CollectionManager.Collections.Count, Is.EqualTo(2)); osu.Realm.Run(realm =>
{
var collections = realm.All<BeatmapCollection>().ToList();
Assert.That(collections.Count, Is.EqualTo(2));
Assert.That(osu.CollectionManager.Collections[0].Name.Value, Is.EqualTo("First")); Assert.That(collections[0].Name, Is.EqualTo("First"));
Assert.That(osu.CollectionManager.Collections[0].BeatmapHashes.Count, Is.EqualTo(2)); Assert.That(collections[0].BeatmapMD5Hashes.Count, Is.EqualTo(2));
Assert.That(osu.CollectionManager.Collections[1].Name.Value, Is.EqualTo("Another")); Assert.That(collections[1].Name, Is.EqualTo("Another"));
Assert.That(osu.CollectionManager.Collections[1].BeatmapHashes.Count, Is.EqualTo(11)); Assert.That(collections[1].BeatmapMD5Hashes.Count, Is.EqualTo(11));
});
} }
finally finally
{ {
@ -187,7 +217,7 @@ namespace osu.Game.Tests.Collections.IO
{ {
// intentionally spin this up on a separate task to avoid disposal deadlocks. // intentionally spin this up on a separate task to avoid disposal deadlocks.
// see https://github.com/EventStore/EventStore/issues/1179 // see https://github.com/EventStore/EventStore/issues/1179
await Task.Factory.StartNew(() => osu.CollectionManager.Import(stream).WaitSafely(), TaskCreationOptions.LongRunning); await Task.Factory.StartNew(() => new LegacyCollectionImporter(osu.Realm).Import(stream).WaitSafely(), TaskCreationOptions.LongRunning);
} }
} }
} }

View File

@ -9,6 +9,7 @@ using System.Linq.Expressions;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Collections;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Models; using osu.Game.Models;
using osu.Game.Overlays.Notifications; using osu.Game.Overlays.Notifications;
@ -51,6 +52,8 @@ namespace osu.Game.Tests.Database
Assert.That(importBeforeUpdate, Is.Not.Null); Assert.That(importBeforeUpdate, Is.Not.Null);
Debug.Assert(importBeforeUpdate != null); Debug.Assert(importBeforeUpdate != null);
realm.Run(r => r.Refresh());
checkCount<BeatmapSetInfo>(realm, 1, s => !s.DeletePending); checkCount<BeatmapSetInfo>(realm, 1, s => !s.DeletePending);
Assert.That(importBeforeUpdate.Value.Beatmaps, Has.Count.EqualTo(count_beatmaps - 1)); Assert.That(importBeforeUpdate.Value.Beatmaps, Has.Count.EqualTo(count_beatmaps - 1));
@ -60,6 +63,8 @@ namespace osu.Game.Tests.Database
Assert.That(importAfterUpdate, Is.Not.Null); Assert.That(importAfterUpdate, Is.Not.Null);
Debug.Assert(importAfterUpdate != null); Debug.Assert(importAfterUpdate != null);
realm.Run(r => r.Refresh());
checkCount<BeatmapInfo>(realm, count_beatmaps); checkCount<BeatmapInfo>(realm, count_beatmaps);
checkCount<BeatmapMetadata>(realm, count_beatmaps); checkCount<BeatmapMetadata>(realm, count_beatmaps);
checkCount<BeatmapSetInfo>(realm, 1); checkCount<BeatmapSetInfo>(realm, 1);
@ -103,6 +108,8 @@ namespace osu.Game.Tests.Database
beatmap.ResetOnlineInfo(); beatmap.ResetOnlineInfo();
}); });
realm.Run(r => r.Refresh());
checkCount<BeatmapSetInfo>(realm, 1, s => !s.DeletePending); checkCount<BeatmapSetInfo>(realm, 1, s => !s.DeletePending);
Assert.That(importBeforeUpdate.Value.Beatmaps, Has.Count.EqualTo(count_beatmaps - 1)); Assert.That(importBeforeUpdate.Value.Beatmaps, Has.Count.EqualTo(count_beatmaps - 1));
@ -112,6 +119,8 @@ namespace osu.Game.Tests.Database
Assert.That(importAfterUpdate, Is.Not.Null); Assert.That(importAfterUpdate, Is.Not.Null);
Debug.Assert(importAfterUpdate != null); Debug.Assert(importAfterUpdate != null);
realm.Run(r => r.Refresh());
checkCount<BeatmapInfo>(realm, count_beatmaps); checkCount<BeatmapInfo>(realm, count_beatmaps);
checkCount<BeatmapMetadata>(realm, count_beatmaps); checkCount<BeatmapMetadata>(realm, count_beatmaps);
checkCount<BeatmapSetInfo>(realm, 1); checkCount<BeatmapSetInfo>(realm, 1);
@ -148,6 +157,8 @@ namespace osu.Game.Tests.Database
Assert.That(importBeforeUpdate, Is.Not.Null); Assert.That(importBeforeUpdate, Is.Not.Null);
Debug.Assert(importBeforeUpdate != null); Debug.Assert(importBeforeUpdate != null);
realm.Run(r => r.Refresh());
checkCount<BeatmapSetInfo>(realm, 1, s => !s.DeletePending); checkCount<BeatmapSetInfo>(realm, 1, s => !s.DeletePending);
Assert.That(importBeforeUpdate.Value.Beatmaps, Has.Count.EqualTo(count_beatmaps)); Assert.That(importBeforeUpdate.Value.Beatmaps, Has.Count.EqualTo(count_beatmaps));
@ -161,6 +172,8 @@ namespace osu.Game.Tests.Database
Assert.That(importBeforeUpdate.Value.Beatmaps, Has.Count.EqualTo(1)); Assert.That(importBeforeUpdate.Value.Beatmaps, Has.Count.EqualTo(1));
Assert.That(importAfterUpdate.Value.Beatmaps, Has.Count.EqualTo(count_beatmaps)); Assert.That(importAfterUpdate.Value.Beatmaps, Has.Count.EqualTo(count_beatmaps));
realm.Run(r => r.Refresh());
checkCount<BeatmapInfo>(realm, count_beatmaps + 1); checkCount<BeatmapInfo>(realm, count_beatmaps + 1);
checkCount<BeatmapMetadata>(realm, count_beatmaps + 1); checkCount<BeatmapMetadata>(realm, count_beatmaps + 1);
@ -198,6 +211,8 @@ namespace osu.Game.Tests.Database
Assert.That(importAfterUpdate, Is.Not.Null); Assert.That(importAfterUpdate, Is.Not.Null);
Debug.Assert(importAfterUpdate != null); Debug.Assert(importAfterUpdate != null);
realm.Run(r => r.Refresh());
checkCount<BeatmapInfo>(realm, count_beatmaps); checkCount<BeatmapInfo>(realm, count_beatmaps);
checkCount<BeatmapMetadata>(realm, count_beatmaps); checkCount<BeatmapMetadata>(realm, count_beatmaps);
checkCount<BeatmapSetInfo>(realm, 2); checkCount<BeatmapSetInfo>(realm, 2);
@ -234,6 +249,8 @@ namespace osu.Game.Tests.Database
var importAfterUpdate = await importer.ImportAsUpdate(new ProgressNotification(), new ImportTask(pathEmpty), importBeforeUpdate.Value); var importAfterUpdate = await importer.ImportAsUpdate(new ProgressNotification(), new ImportTask(pathEmpty), importBeforeUpdate.Value);
Assert.That(importAfterUpdate, Is.Null); Assert.That(importAfterUpdate, Is.Null);
realm.Run(r => r.Refresh());
checkCount<BeatmapSetInfo>(realm, 1); checkCount<BeatmapSetInfo>(realm, 1);
checkCount<BeatmapInfo>(realm, count_beatmaps); checkCount<BeatmapInfo>(realm, count_beatmaps);
checkCount<BeatmapMetadata>(realm, count_beatmaps); checkCount<BeatmapMetadata>(realm, count_beatmaps);
@ -263,6 +280,8 @@ namespace osu.Game.Tests.Database
Assert.That(importAfterUpdate, Is.Not.Null); Assert.That(importAfterUpdate, Is.Not.Null);
Debug.Assert(importAfterUpdate != null); Debug.Assert(importAfterUpdate != null);
realm.Run(r => r.Refresh());
checkCount<BeatmapSetInfo>(realm, 1); checkCount<BeatmapSetInfo>(realm, 1);
checkCount<BeatmapInfo>(realm, count_beatmaps); checkCount<BeatmapInfo>(realm, count_beatmaps);
checkCount<BeatmapMetadata>(realm, count_beatmaps); checkCount<BeatmapMetadata>(realm, count_beatmaps);
@ -307,6 +326,8 @@ namespace osu.Game.Tests.Database
s.Realm.Add(new ScoreInfo(beatmapInfo, s.Realm.All<RulesetInfo>().First(), new RealmUser())); s.Realm.Add(new ScoreInfo(beatmapInfo, s.Realm.All<RulesetInfo>().First(), new RealmUser()));
}); });
realm.Run(r => r.Refresh());
checkCount<ScoreInfo>(realm, 1); checkCount<ScoreInfo>(realm, 1);
var importAfterUpdate = await importer.ImportAsUpdate(new ProgressNotification(), new ImportTask(pathMissingOneBeatmap), importBeforeUpdate.Value); var importAfterUpdate = await importer.ImportAsUpdate(new ProgressNotification(), new ImportTask(pathMissingOneBeatmap), importBeforeUpdate.Value);
@ -314,6 +335,8 @@ namespace osu.Game.Tests.Database
Assert.That(importAfterUpdate, Is.Not.Null); Assert.That(importAfterUpdate, Is.Not.Null);
Debug.Assert(importAfterUpdate != null); Debug.Assert(importAfterUpdate != null);
realm.Run(r => r.Refresh());
checkCount<BeatmapInfo>(realm, count_beatmaps); checkCount<BeatmapInfo>(realm, count_beatmaps);
checkCount<BeatmapMetadata>(realm, count_beatmaps); checkCount<BeatmapMetadata>(realm, count_beatmaps);
checkCount<BeatmapSetInfo>(realm, 2); checkCount<BeatmapSetInfo>(realm, 2);
@ -348,6 +371,8 @@ namespace osu.Game.Tests.Database
s.Realm.Add(new ScoreInfo(beatmapInfo, s.Realm.All<RulesetInfo>().First(), new RealmUser())); s.Realm.Add(new ScoreInfo(beatmapInfo, s.Realm.All<RulesetInfo>().First(), new RealmUser()));
}); });
realm.Run(r => r.Refresh());
checkCount<ScoreInfo>(realm, 1); checkCount<ScoreInfo>(realm, 1);
using var _ = getBeatmapArchiveWithModifications(out string pathModified, directory => using var _ = getBeatmapArchiveWithModifications(out string pathModified, directory =>
@ -365,6 +390,8 @@ namespace osu.Game.Tests.Database
Assert.That(importAfterUpdate, Is.Not.Null); Assert.That(importAfterUpdate, Is.Not.Null);
Debug.Assert(importAfterUpdate != null); Debug.Assert(importAfterUpdate != null);
realm.Run(r => r.Refresh());
checkCount<BeatmapInfo>(realm, count_beatmaps + 1); checkCount<BeatmapInfo>(realm, count_beatmaps + 1);
checkCount<BeatmapMetadata>(realm, count_beatmaps + 1); checkCount<BeatmapMetadata>(realm, count_beatmaps + 1);
checkCount<BeatmapSetInfo>(realm, 2); checkCount<BeatmapSetInfo>(realm, 2);
@ -406,6 +433,126 @@ namespace osu.Game.Tests.Database
}); });
} }
/// <summary>
/// If all difficulties in the original beatmap set are in a collection, presume the user also wants new difficulties added.
/// </summary>
[TestCase(false)]
[TestCase(true)]
public void TestCollectionTransferNewBeatmap(bool allOriginalBeatmapsInCollection)
{
RunTestWithRealmAsync(async (realm, storage) =>
{
var importer = new BeatmapImporter(storage, realm);
using var rulesets = new RealmRulesetStore(realm, storage);
using var __ = getBeatmapArchive(out string pathOriginal);
using var _ = getBeatmapArchiveWithModifications(out string pathMissingOneBeatmap, directory =>
{
// remove one difficulty before first import
directory.GetFiles("*.osu").First().Delete();
});
var importBeforeUpdate = await importer.Import(new ImportTask(pathMissingOneBeatmap));
Assert.That(importBeforeUpdate, Is.Not.Null);
Debug.Assert(importBeforeUpdate != null);
int beatmapsToAddToCollection = 0;
importBeforeUpdate.PerformWrite(s =>
{
var beatmapCollection = s.Realm.Add(new BeatmapCollection("test collection"));
beatmapsToAddToCollection = s.Beatmaps.Count - (allOriginalBeatmapsInCollection ? 0 : 1);
for (int i = 0; i < beatmapsToAddToCollection; i++)
beatmapCollection.BeatmapMD5Hashes.Add(s.Beatmaps[i].MD5Hash);
});
// Second import matches first but contains one extra .osu file.
var importAfterUpdate = await importer.ImportAsUpdate(new ProgressNotification(), new ImportTask(pathOriginal), importBeforeUpdate.Value);
Assert.That(importAfterUpdate, Is.Not.Null);
Debug.Assert(importAfterUpdate != null);
importAfterUpdate.PerformRead(updated =>
{
updated.Realm.Refresh();
string[] hashes = updated.Realm.All<BeatmapCollection>().Single().BeatmapMD5Hashes.ToArray();
if (allOriginalBeatmapsInCollection)
{
Assert.That(updated.Beatmaps.Count, Is.EqualTo(beatmapsToAddToCollection + 1));
Assert.That(hashes, Has.Length.EqualTo(updated.Beatmaps.Count));
}
else
{
// Collection contains one less than the original beatmap, and two less after update (new difficulty included).
Assert.That(updated.Beatmaps.Count, Is.EqualTo(beatmapsToAddToCollection + 2));
Assert.That(hashes, Has.Length.EqualTo(beatmapsToAddToCollection));
}
});
});
}
/// <summary>
/// If a difficulty in the original beatmap set is modified, the updated version should remain in any collections it was in.
/// </summary>
[Test]
public void TestCollectionTransferModifiedBeatmap()
{
RunTestWithRealmAsync(async (realm, storage) =>
{
var importer = new BeatmapImporter(storage, realm);
using var rulesets = new RealmRulesetStore(realm, storage);
using var __ = getBeatmapArchive(out string pathOriginal);
using var _ = getBeatmapArchiveWithModifications(out string pathModified, directory =>
{
// Modify one .osu file with different content.
var firstOsuFile = directory.GetFiles("*[Hard]*.osu").First();
string existingContent = File.ReadAllText(firstOsuFile.FullName);
File.WriteAllText(firstOsuFile.FullName, existingContent + "\n# I am new content");
});
var importBeforeUpdate = await importer.Import(new ImportTask(pathOriginal));
Assert.That(importBeforeUpdate, Is.Not.Null);
Debug.Assert(importBeforeUpdate != null);
string originalHash = string.Empty;
importBeforeUpdate.PerformWrite(s =>
{
var beatmapCollection = s.Realm.Add(new BeatmapCollection("test collection"));
originalHash = s.Beatmaps.Single(b => b.DifficultyName == "Hard").MD5Hash;
beatmapCollection.BeatmapMD5Hashes.Add(originalHash);
});
// Second import matches first but contains a modified .osu file.
var importAfterUpdate = await importer.ImportAsUpdate(new ProgressNotification(), new ImportTask(pathModified), importBeforeUpdate.Value);
Assert.That(importAfterUpdate, Is.Not.Null);
Debug.Assert(importAfterUpdate != null);
importAfterUpdate.PerformRead(updated =>
{
updated.Realm.Refresh();
string[] hashes = updated.Realm.All<BeatmapCollection>().Single().BeatmapMD5Hashes.ToArray();
string updatedHash = updated.Beatmaps.Single(b => b.DifficultyName == "Hard").MD5Hash;
Assert.That(hashes, Has.Length.EqualTo(1));
Assert.That(hashes.First(), Is.EqualTo(updatedHash));
Assert.That(updatedHash, Is.Not.EqualTo(originalHash));
});
});
}
private static void checkCount<T>(RealmAccess realm, int expected, Expression<Func<T, bool>>? condition = null) where T : RealmObject private static void checkCount<T>(RealmAccess realm, int expected, Expression<Func<T, bool>>? condition = null) where T : RealmObject
{ {
var query = realm.Realm.All<T>(); var query = realm.Realm.All<T>();

View File

@ -41,8 +41,6 @@ namespace osu.Game.Tests.Gameplay
AddStep("create container", () => AddStep("create container", () =>
{ {
var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
working.LoadTrack();
Child = gameplayClockContainer = new MasterGameplayClockContainer(working, 0); Child = gameplayClockContainer = new MasterGameplayClockContainer(working, 0);
}); });
@ -58,8 +56,6 @@ namespace osu.Game.Tests.Gameplay
AddStep("create container", () => AddStep("create container", () =>
{ {
var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
working.LoadTrack();
Child = gameplayClockContainer = new MasterGameplayClockContainer(working, 0); Child = gameplayClockContainer = new MasterGameplayClockContainer(working, 0);
}); });
@ -102,8 +98,6 @@ namespace osu.Game.Tests.Gameplay
AddStep("create container", () => AddStep("create container", () =>
{ {
working = new ClockBackedTestWorkingBeatmap(new OsuRuleset().RulesetInfo, new FramedClock(new ManualClock()), Audio); working = new ClockBackedTestWorkingBeatmap(new OsuRuleset().RulesetInfo, new FramedClock(new ManualClock()), Audio);
working.LoadTrack();
Child = gameplayClockContainer = new MasterGameplayClockContainer(working, 0); Child = gameplayClockContainer = new MasterGameplayClockContainer(working, 0);
gameplayClockContainer.Reset(startClock: !whileStopped); gameplayClockContainer.Reset(startClock: !whileStopped);

View File

@ -69,7 +69,6 @@ namespace osu.Game.Tests.Gameplay
AddStep("create container", () => AddStep("create container", () =>
{ {
var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
working.LoadTrack();
Add(gameplayContainer = new MasterGameplayClockContainer(working, 0) Add(gameplayContainer = new MasterGameplayClockContainer(working, 0)
{ {
@ -96,7 +95,6 @@ namespace osu.Game.Tests.Gameplay
AddStep("create container", () => AddStep("create container", () =>
{ {
var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
working.LoadTrack();
const double start_time = 1000; const double start_time = 1000;

View File

@ -10,7 +10,7 @@ using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions; using osu.Framework.Extensions;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Game.Collections; using osu.Game.Database;
using osu.Game.Tests.Resources; using osu.Game.Tests.Resources;
namespace osu.Game.Tests namespace osu.Game.Tests
@ -47,7 +47,7 @@ namespace osu.Game.Tests
public class TestOsuGameBase : OsuGameBase public class TestOsuGameBase : OsuGameBase
{ {
public CollectionManager CollectionManager { get; private set; } public RealmAccess Realm => Dependencies.Get<RealmAccess>();
private readonly bool withBeatmap; private readonly bool withBeatmap;
@ -62,8 +62,6 @@ namespace osu.Game.Tests
// Beatmap must be imported before the collection manager is loaded. // Beatmap must be imported before the collection manager is loaded.
if (withBeatmap) if (withBeatmap)
BeatmapManager.Import(TestResources.GetTestBeatmapForImport()).WaitSafely(); BeatmapManager.Import(TestResources.GetTestBeatmapForImport()).WaitSafely();
AddInternal(CollectionManager = new CollectionManager(Storage));
} }
} }
} }

View File

@ -208,7 +208,7 @@ namespace osu.Game.Tests.Online
public TestBeatmapManager(Storage storage, RealmAccess realm, RulesetStore rulesets, IAPIProvider api, [NotNull] AudioManager audioManager, IResourceStore<byte[]> resources, public TestBeatmapManager(Storage storage, RealmAccess realm, RulesetStore rulesets, IAPIProvider api, [NotNull] AudioManager audioManager, IResourceStore<byte[]> resources,
GameHost host = null, WorkingBeatmap defaultBeatmap = null) GameHost host = null, WorkingBeatmap defaultBeatmap = null)
: base(storage, realm, rulesets, api, audioManager, resources, host, defaultBeatmap) : base(storage, realm, api, audioManager, resources, host, defaultBeatmap)
{ {
} }

View File

@ -32,7 +32,6 @@ namespace osu.Game.Tests.Skins
imported?.PerformRead(s => imported?.PerformRead(s =>
{ {
beatmap = beatmaps.GetWorkingBeatmap(s.Beatmaps[0]); beatmap = beatmaps.GetWorkingBeatmap(s.Beatmaps[0]);
beatmap.LoadTrack();
}); });
} }
@ -40,6 +39,10 @@ namespace osu.Game.Tests.Skins
public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => beatmap.Skin.GetSample(new SampleInfo("sample")) != null); public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => beatmap.Skin.GetSample(new SampleInfo("sample")) != null);
[Test] [Test]
public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => !(beatmap.Track is TrackVirtual)); public void TestRetrieveOggTrack() => AddAssert("track is non-null", () =>
{
using (var track = beatmap.LoadTrack())
return track is not TrackVirtual;
});
} }
} }

View File

@ -49,7 +49,7 @@ namespace osu.Game.Tests.Visual.Background
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm)); Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(new OsuConfigManager(LocalStorage)); Dependencies.Cache(new OsuConfigManager(LocalStorage));
Dependencies.Cache(Realm); Dependencies.Cache(Realm);

View File

@ -1,8 +1,6 @@
// 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 disable
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
@ -27,38 +25,32 @@ namespace osu.Game.Tests.Visual.Collections
{ {
protected override Container<Drawable> Content { get; } = new Container { RelativeSizeAxes = Axes.Both }; protected override Container<Drawable> Content { get; } = new Container { RelativeSizeAxes = Axes.Both };
private DialogOverlay dialogOverlay; private DialogOverlay dialogOverlay = null!;
private CollectionManager manager; private BeatmapManager beatmapManager = null!;
private ManageCollectionsDialog dialog = null!;
private RulesetStore rulesets;
private BeatmapManager beatmapManager;
private ManageCollectionsDialog dialog;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host) private void load(GameHost host)
{ {
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm)); Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, rulesets, null, Audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, null, Audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm); Dependencies.Cache(Realm);
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely(); beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
base.Content.AddRange(new Drawable[] base.Content.AddRange(new Drawable[]
{ {
manager = new CollectionManager(LocalStorage),
Content, Content,
dialogOverlay = new DialogOverlay(), dialogOverlay = new DialogOverlay(),
}); });
Dependencies.Cache(manager);
Dependencies.CacheAs<IDialogOverlay>(dialogOverlay); Dependencies.CacheAs<IDialogOverlay>(dialogOverlay);
} }
[SetUp] [SetUp]
public void SetUp() => Schedule(() => public void SetUp() => Schedule(() =>
{ {
manager.Collections.Clear(); Realm.Write(r => r.RemoveAll<BeatmapCollection>());
Child = dialog = new ManageCollectionsDialog(); Child = dialog = new ManageCollectionsDialog();
}); });
@ -78,17 +70,17 @@ namespace osu.Game.Tests.Visual.Collections
[Test] [Test]
public void TestLastItemIsPlaceholder() 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] [Test]
public void TestAddCollectionExternal() public void TestAddCollectionExternal()
{ {
AddStep("add collection", () => manager.Collections.Add(new BeatmapCollection { Name = { Value = "First collection" } })); AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "First collection"))));
assertCollectionCount(1); assertCollectionCount(1);
assertCollectionName(0, "First collection"); 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 BeatmapCollection(name: "Second collection"))));
assertCollectionCount(2); assertCollectionCount(2);
assertCollectionName(1, "Second collection"); assertCollectionName(1, "Second collection");
} }
@ -108,7 +100,7 @@ namespace osu.Game.Tests.Visual.Collections
[Test] [Test]
public void TestAddCollectionViaPlaceholder() public void TestAddCollectionViaPlaceholder()
{ {
DrawableCollectionListItem placeholderItem = null; DrawableCollectionListItem placeholderItem = null!;
AddStep("focus placeholder", () => AddStep("focus placeholder", () =>
{ {
@ -116,24 +108,37 @@ namespace osu.Game.Tests.Visual.Collections
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
}); });
// Done directly via the collection since InputManager methods cannot add text to textbox... assertCollectionCount(0);
AddStep("change collection name", () => placeholderItem.Model.Name.Value = "a");
assertCollectionCount(1);
AddAssert("collection now exists", () => manager.Collections.Contains(placeholderItem.Model));
AddAssert("last item is placeholder", () => !manager.Collections.Contains(dialog.ChildrenOfType<DrawableCollectionListItem>().Last().Model)); AddStep("change collection name", () =>
{
placeholderItem.ChildrenOfType<TextBox>().First().Text = "test text";
InputManager.Key(Key.Enter);
});
assertCollectionCount(1);
AddAssert("last item is placeholder", () => !dialog.ChildrenOfType<DrawableCollectionListItem>().Last().Model.IsManaged);
} }
[Test] [Test]
public void TestRemoveCollectionExternal() public void TestRemoveCollectionExternal()
{ {
AddStep("add two collections", () => manager.Collections.AddRange(new[] BeatmapCollection first = null!;
{
new BeatmapCollection { Name = { Value = "1" } },
new BeatmapCollection { Name = { Value = "2" } },
}));
AddStep("remove first collection", () => manager.Collections.RemoveAt(0)); AddStep("add two collections", () =>
{
Realm.Write(r =>
{
r.Add(new[]
{
first = new BeatmapCollection(name: "1"),
new BeatmapCollection(name: "2"),
});
});
});
AddStep("remove first collection", () => Realm.Write(r => r.Remove(first)));
assertCollectionCount(1); assertCollectionCount(1);
assertCollectionName(0, "2"); assertCollectionName(0, "2");
} }
@ -143,7 +148,7 @@ namespace osu.Game.Tests.Visual.Collections
{ {
AddStep("add dropdown", () => AddStep("add dropdown", () =>
{ {
Add(new CollectionFilterDropdown Add(new CollectionDropdown
{ {
Anchor = Anchor.TopRight, Anchor = Anchor.TopRight,
Origin = Anchor.TopRight, Origin = Anchor.TopRight,
@ -151,21 +156,27 @@ namespace osu.Game.Tests.Visual.Collections
Width = 0.4f, 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: "1"),
new BeatmapCollection { Name = { Value = "1" }, BeatmapHashes = { beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0].MD5Hash } }, new BeatmapCollection(name: "1")
})); {
BeatmapMD5Hashes = { beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0].MD5Hash }
},
})));
} }
[Test] [Test]
public void TestRemoveCollectionViaButton() 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: "1"),
new BeatmapCollection { Name = { Value = "2" }, BeatmapHashes = { beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0].MD5Hash } }, new BeatmapCollection(name: "2")
})); {
BeatmapMD5Hashes = { beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0].MD5Hash }
},
})));
assertCollectionCount(2); assertCollectionCount(2);
@ -198,10 +209,13 @@ namespace osu.Game.Tests.Visual.Collections
[Test] [Test]
public void TestCollectionNotRemovedWhenDialogCancelled() 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 BeatmapCollection(name: "1")
})); {
BeatmapMD5Hashes = { beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0].MD5Hash }
},
})));
assertCollectionCount(1); assertCollectionCount(1);
@ -224,34 +238,67 @@ namespace osu.Game.Tests.Visual.Collections
[Test] [Test]
public void TestCollectionRenamedExternal() public void TestCollectionRenamedExternal()
{ {
AddStep("add two collections", () => manager.Collections.AddRange(new[] BeatmapCollection first = null!;
AddStep("add two collections", () =>
{ {
new BeatmapCollection { Name = { Value = "1" } }, Realm.Write(r =>
new BeatmapCollection { Name = { Value = "2" } }, {
})); r.Add(new[]
{
first = new BeatmapCollection(name: "1"),
new BeatmapCollection(name: "2"),
});
});
});
AddStep("change first collection name", () => manager.Collections[0].Name.Value = "First"); assertCollectionName(0, "1");
assertCollectionName(1, "2");
assertCollectionName(0, "First"); AddStep("change first collection name", () => Realm.Write(_ => first.Name = "First"));
// Item will have moved due to alphabetical sorting.
assertCollectionName(0, "2");
assertCollectionName(1, "First");
} }
[Test] [Test]
public void TestCollectionRenamedOnTextChange() public void TestCollectionRenamedOnTextChange()
{ {
AddStep("add two collections", () => manager.Collections.AddRange(new[] BeatmapCollection first = null!;
DrawableCollectionListItem firstItem = null!;
AddStep("add two collections", () =>
{ {
new BeatmapCollection { Name = { Value = "1" } }, Realm.Write(r =>
new BeatmapCollection { Name = { Value = "2" } }, {
})); r.Add(new[]
{
first = new BeatmapCollection(name: "1"),
new BeatmapCollection(name: "2"),
});
});
});
assertCollectionCount(2); assertCollectionCount(2);
AddStep("change first collection name", () => dialog.ChildrenOfType<TextBox>().First().Text = "First"); AddStep("focus first collection", () =>
AddAssert("collection has new name", () => manager.Collections[0].Name.Value == "First"); {
InputManager.MoveMouseTo(firstItem = dialog.ChildrenOfType<DrawableCollectionListItem>().First());
InputManager.Click(MouseButton.Left);
});
AddStep("change first collection name", () =>
{
firstItem.ChildrenOfType<TextBox>().First().Text = "First";
InputManager.Key(Key.Enter);
});
AddUntilStep("collection has new name", () => first.Name == "First");
} }
private void assertCollectionCount(int count) private void assertCollectionCount(int count)
=> AddUntilStep($"{count} collections shown", () => dialog.ChildrenOfType<DrawableCollectionListItem>().Count(i => i.IsCreated.Value) == count); => AddUntilStep($"{count} collections shown", () => dialog.ChildrenOfType<DrawableCollectionListItem>().Count() == count + 1); // +1 for placeholder
private void assertCollectionName(int index, string name) private void assertCollectionName(int index, string name)
=> AddUntilStep($"item {index + 1} has correct name", () => dialog.ChildrenOfType<DrawableCollectionListItem>().ElementAt(index).ChildrenOfType<TextBox>().First().Text == name); => AddUntilStep($"item {index + 1} has correct name", () => dialog.ChildrenOfType<DrawableCollectionListItem>().ElementAt(index).ChildrenOfType<TextBox>().First().Text == name);

View File

@ -159,6 +159,7 @@ namespace osu.Game.Tests.Visual.Gameplay
AddUntilStep("wait for hud load", () => hudOverlay.IsLoaded); AddUntilStep("wait for hud load", () => hudOverlay.IsLoaded);
AddUntilStep("wait for components to be hidden", () => hudOverlay.ChildrenOfType<SkinnableTargetContainer>().Single().Alpha == 0); AddUntilStep("wait for components to be hidden", () => hudOverlay.ChildrenOfType<SkinnableTargetContainer>().Single().Alpha == 0);
AddUntilStep("wait for hud load", () => hudOverlay.ChildrenOfType<SkinnableTargetContainer>().All(c => c.ComponentsLoaded));
AddStep("bind on update", () => AddStep("bind on update", () =>
{ {

View File

@ -36,7 +36,7 @@ namespace osu.Game.Tests.Visual.Gameplay
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm)); Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(new ScoreManager(rulesets, () => beatmaps, LocalStorage, Realm, Scheduler, API)); Dependencies.Cache(new ScoreManager(rulesets, () => beatmaps, LocalStorage, Realm, Scheduler, API));
Dependencies.Cache(Realm); Dependencies.Cache(Realm);
} }

View File

@ -14,6 +14,7 @@ using osu.Game.Overlays.Settings;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu;
using osu.Game.Screens.Play.HUD.HitErrorMeters; using osu.Game.Screens.Play.HUD.HitErrorMeters;
using osu.Game.Skinning;
using osu.Game.Skinning.Editor; using osu.Game.Skinning.Editor;
using osuTK.Input; using osuTK.Input;
@ -33,6 +34,8 @@ namespace osu.Game.Tests.Visual.Gameplay
{ {
base.SetUpSteps(); base.SetUpSteps();
AddUntilStep("wait for hud load", () => Player.ChildrenOfType<SkinnableTargetContainer>().All(c => c.ComponentsLoaded));
AddStep("reload skin editor", () => AddStep("reload skin editor", () =>
{ {
skinEditor?.Expire(); skinEditor?.Expire();

View File

@ -33,7 +33,6 @@ namespace osu.Game.Tests.Visual.Gameplay
increment = skip_time; increment = skip_time;
var working = CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)); var working = CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo));
working.LoadTrack();
Child = gameplayClockContainer = new MasterGameplayClockContainer(working, 0) Child = gameplayClockContainer = new MasterGameplayClockContainer(working, 0)
{ {

View File

@ -35,7 +35,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
protected IScreen CurrentSubScreen => multiplayerComponents.MultiplayerScreen.CurrentSubScreen; protected IScreen CurrentSubScreen => multiplayerComponents.MultiplayerScreen.CurrentSubScreen;
private BeatmapManager beatmaps; private BeatmapManager beatmaps;
private RulesetStore rulesets;
private BeatmapSetInfo importedSet; private BeatmapSetInfo importedSet;
private TestMultiplayerComponents multiplayerComponents; private TestMultiplayerComponents multiplayerComponents;
@ -45,8 +44,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm)); Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm); Dependencies.Cache(Realm);
} }

View File

@ -38,13 +38,12 @@ namespace osu.Game.Tests.Visual.Multiplayer
private TestPlaylist playlist; private TestPlaylist playlist;
private BeatmapManager manager; private BeatmapManager manager;
private RulesetStore rulesets;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm)); Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm); Dependencies.Cache(Realm);
} }

View File

@ -49,7 +49,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
public class TestSceneMultiplayer : ScreenTestScene public class TestSceneMultiplayer : ScreenTestScene
{ {
private BeatmapManager beatmaps = null!; private BeatmapManager beatmaps = null!;
private RulesetStore rulesets = null!;
private BeatmapSetInfo importedSet = null!; private BeatmapSetInfo importedSet = null!;
private TestMultiplayerComponents multiplayerComponents = null!; private TestMultiplayerComponents multiplayerComponents = null!;
@ -63,8 +62,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm)); Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, rulesets, API, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, API, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm); Dependencies.Cache(Realm);
} }

View File

@ -47,7 +47,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm)); Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm); Dependencies.Cache(Realm);
importedBeatmapSet = manager.Import(TestResources.CreateTestBeatmapSetInfo(8, rulesets.AvailableRulesets.ToArray())); importedBeatmapSet = manager.Import(TestResources.CreateTestBeatmapSetInfo(8, rulesets.AvailableRulesets.ToArray()));

View File

@ -40,7 +40,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
private MultiplayerMatchSubScreen screen; private MultiplayerMatchSubScreen screen;
private BeatmapManager beatmaps; private BeatmapManager beatmaps;
private RulesetStore rulesets;
private BeatmapSetInfo importedSet; private BeatmapSetInfo importedSet;
public TestSceneMultiplayerMatchSubScreen() public TestSceneMultiplayerMatchSubScreen()
@ -51,8 +50,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm)); Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm); Dependencies.Cache(Realm);
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely(); beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();

View File

@ -31,15 +31,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
{ {
private MultiplayerPlaylist list; private MultiplayerPlaylist list;
private BeatmapManager beatmaps; private BeatmapManager beatmaps;
private RulesetStore rulesets;
private BeatmapSetInfo importedSet; private BeatmapSetInfo importedSet;
private BeatmapInfo importedBeatmap; private BeatmapInfo importedBeatmap;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm)); Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm); Dependencies.Cache(Realm);
} }

View File

@ -29,15 +29,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
{ {
private MultiplayerQueueList playlist; private MultiplayerQueueList playlist;
private BeatmapManager beatmaps; private BeatmapManager beatmaps;
private RulesetStore rulesets;
private BeatmapSetInfo importedSet; private BeatmapSetInfo importedSet;
private BeatmapInfo importedBeatmap; private BeatmapInfo importedBeatmap;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm)); Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, rulesets, API, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, API, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm); Dependencies.Cache(Realm);
} }

View File

@ -35,13 +35,12 @@ namespace osu.Game.Tests.Visual.Multiplayer
private BeatmapSetInfo importedSet; private BeatmapSetInfo importedSet;
private BeatmapManager beatmaps; private BeatmapManager beatmaps;
private RulesetStore rulesets;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm)); Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm); Dependencies.Cache(Realm);
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely(); beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();

View File

@ -28,15 +28,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
{ {
private BeatmapManager manager; private BeatmapManager manager;
private RulesetStore rulesets;
private TestPlaylistsSongSelect songSelect; private TestPlaylistsSongSelect songSelect;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm)); Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm); Dependencies.Cache(Realm);
var beatmapSet = TestResources.CreateTestBeatmapSetInfo(); var beatmapSet = TestResources.CreateTestBeatmapSetInfo();

View File

@ -30,7 +30,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
public class TestSceneTeamVersus : ScreenTestScene public class TestSceneTeamVersus : ScreenTestScene
{ {
private BeatmapManager beatmaps; private BeatmapManager beatmaps;
private RulesetStore rulesets;
private BeatmapSetInfo importedSet; private BeatmapSetInfo importedSet;
private TestMultiplayerComponents multiplayerComponents; private TestMultiplayerComponents multiplayerComponents;
@ -40,8 +39,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm)); Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm); Dependencies.Cache(Realm);
} }

View File

@ -74,14 +74,14 @@ namespace osu.Game.Tests.Visual.Navigation
AddStep("set filter again", () => songSelect.ChildrenOfType<SearchTextBox>().Single().Current.Value = "test"); AddStep("set filter again", () => songSelect.ChildrenOfType<SearchTextBox>().Single().Current.Value = "test");
AddStep("open collections dropdown", () => AddStep("open collections dropdown", () =>
{ {
InputManager.MoveMouseTo(songSelect.ChildrenOfType<CollectionFilterDropdown>().Single()); InputManager.MoveMouseTo(songSelect.ChildrenOfType<CollectionDropdown>().Single());
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
}); });
AddStep("press back once", () => InputManager.Click(MouseButton.Button1)); AddStep("press back once", () => InputManager.Click(MouseButton.Button1));
AddAssert("still at song select", () => Game.ScreenStack.CurrentScreen == songSelect); AddAssert("still at song select", () => Game.ScreenStack.CurrentScreen == songSelect);
AddAssert("collections dropdown closed", () => songSelect AddAssert("collections dropdown closed", () => songSelect
.ChildrenOfType<CollectionFilterDropdown>().Single() .ChildrenOfType<CollectionDropdown>().Single()
.ChildrenOfType<Dropdown<CollectionFilterMenuItem>.DropdownMenu>().Single().State == MenuState.Closed); .ChildrenOfType<Dropdown<CollectionFilterMenuItem>.DropdownMenu>().Single().State == MenuState.Closed);
AddStep("press back a second time", () => InputManager.Click(MouseButton.Button1)); AddStep("press back a second time", () => InputManager.Click(MouseButton.Button1));

View File

@ -3,6 +3,8 @@
#nullable disable #nullable disable
using osu.Framework.Graphics;
using osu.Game.Graphics.Cursor;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osuTK; using osuTK;
@ -12,9 +14,15 @@ namespace osu.Game.Tests.Visual.Online
{ {
public TestSceneExternalLinkButton() public TestSceneExternalLinkButton()
{ {
Child = new ExternalLinkButton("https://osu.ppy.sh/home") Child = new OsuContextMenuContainer
{ {
Size = new Vector2(50) RelativeSizeAxes = Axes.Both,
Child = new ExternalLinkButton("https://osu.ppy.sh/home")
{
Size = new Vector2(50),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
}
}; };
} }
} }

View File

@ -32,7 +32,6 @@ namespace osu.Game.Tests.Visual.Playlists
public class TestScenePlaylistsRoomCreation : OnlinePlayTestScene public class TestScenePlaylistsRoomCreation : OnlinePlayTestScene
{ {
private BeatmapManager manager; private BeatmapManager manager;
private RulesetStore rulesets;
private TestPlaylistsRoomSubScreen match; private TestPlaylistsRoomSubScreen match;
@ -41,8 +40,8 @@ namespace osu.Game.Tests.Visual.Playlists
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm)); Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, rulesets, API, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, API, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm); Dependencies.Cache(Realm);
} }

View File

@ -46,7 +46,7 @@ namespace osu.Game.Tests.Visual.SongSelect
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
dependencies.Cache(rulesetStore = new RealmRulesetStore(Realm)); dependencies.Cache(rulesetStore = new RealmRulesetStore(Realm));
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, rulesetStore, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default)); dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default));
dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, Realm, Scheduler, API)); dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, Realm, Scheduler, API));
Dependencies.Cache(Realm); Dependencies.Cache(Realm);

View File

@ -1,8 +1,6 @@
// 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 disable
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
@ -28,35 +26,28 @@ namespace osu.Game.Tests.Visual.SongSelect
{ {
protected override Container<Drawable> Content { get; } = new Container { RelativeSizeAxes = Axes.Both }; protected override Container<Drawable> Content { get; } = new Container { RelativeSizeAxes = Axes.Both };
private CollectionManager collectionManager; private BeatmapManager beatmapManager = null!;
private FilterControl control = null!;
private RulesetStore rulesets;
private BeatmapManager beatmapManager;
private FilterControl control;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host) private void load(GameHost host)
{ {
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm)); Dependencies.Cache(new RealmRulesetStore(Realm));
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, rulesets, null, Audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, null, Audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Realm); Dependencies.Cache(Realm);
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely(); beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
base.Content.AddRange(new Drawable[] base.Content.AddRange(new Drawable[]
{ {
collectionManager = new CollectionManager(LocalStorage),
Content Content
}); });
Dependencies.Cache(collectionManager);
} }
[SetUp] [SetUp]
public void SetUp() => Schedule(() => public void SetUp() => Schedule(() =>
{ {
collectionManager.Collections.Clear(); Realm.Write(r => r.RemoveAll<BeatmapCollection>());
Child = control = new FilterControl Child = control = new FilterControl
{ {
@ -77,8 +68,8 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test] [Test]
public void TestCollectionAddedToDropdown() public void TestCollectionAddedToDropdown()
{ {
AddStep("add collection", () => collectionManager.Collections.Add(new BeatmapCollection { Name = { Value = "1" } })); AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "1"))));
AddStep("add collection", () => collectionManager.Collections.Add(new BeatmapCollection { Name = { Value = "2" } })); AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "2"))));
assertCollectionDropdownContains("1"); assertCollectionDropdownContains("1");
assertCollectionDropdownContains("2"); assertCollectionDropdownContains("2");
} }
@ -86,9 +77,11 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test] [Test]
public void TestCollectionRemovedFromDropdown() public void TestCollectionRemovedFromDropdown()
{ {
AddStep("add collection", () => collectionManager.Collections.Add(new BeatmapCollection { Name = { Value = "1" } })); BeatmapCollection first = null!;
AddStep("add collection", () => collectionManager.Collections.Add(new BeatmapCollection { Name = { Value = "2" } }));
AddStep("remove collection", () => collectionManager.Collections.RemoveAt(0)); AddStep("add collection", () => Realm.Write(r => r.Add(first = new BeatmapCollection(name: "1"))));
AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "2"))));
AddStep("remove collection", () => Realm.Write(r => r.Remove(first)));
assertCollectionDropdownContains("1", false); assertCollectionDropdownContains("1", false);
assertCollectionDropdownContains("2"); assertCollectionDropdownContains("2");
@ -97,16 +90,16 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test] [Test]
public void TestCollectionRenamed() public void TestCollectionRenamed()
{ {
AddStep("add collection", () => collectionManager.Collections.Add(new BeatmapCollection { Name = { Value = "1" } })); AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "1"))));
AddStep("select collection", () => AddStep("select collection", () =>
{ {
var dropdown = control.ChildrenOfType<CollectionFilterDropdown>().Single(); var dropdown = control.ChildrenOfType<CollectionDropdown>().Single();
dropdown.Current.Value = dropdown.ItemSource.ElementAt(1); dropdown.Current.Value = dropdown.ItemSource.ElementAt(1);
}); });
addExpandHeaderStep(); addExpandHeaderStep();
AddStep("change name", () => collectionManager.Collections[0].Name.Value = "First"); AddStep("change name", () => Realm.Write(_ => getFirstCollection().Name = "First"));
assertCollectionDropdownContains("First"); assertCollectionDropdownContains("First");
assertCollectionHeaderDisplays("First"); assertCollectionHeaderDisplays("First");
@ -124,7 +117,7 @@ namespace osu.Game.Tests.Visual.SongSelect
public void TestCollectionFilterHasAddButton() public void TestCollectionFilterHasAddButton()
{ {
addExpandHeaderStep(); addExpandHeaderStep();
AddStep("add collection", () => collectionManager.Collections.Add(new BeatmapCollection { Name = { Value = "1" } })); AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "1"))));
AddStep("hover collection", () => InputManager.MoveMouseTo(getAddOrRemoveButton(1))); AddStep("hover collection", () => InputManager.MoveMouseTo(getAddOrRemoveButton(1)));
AddAssert("collection has add button", () => getAddOrRemoveButton(1).IsPresent); AddAssert("collection has add button", () => getAddOrRemoveButton(1).IsPresent);
} }
@ -134,7 +127,7 @@ namespace osu.Game.Tests.Visual.SongSelect
{ {
addExpandHeaderStep(); addExpandHeaderStep();
AddStep("add collection", () => collectionManager.Collections.Add(new BeatmapCollection { Name = { Value = "1" } })); AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "1"))));
AddStep("select available beatmap", () => Beatmap.Value = beatmapManager.GetWorkingBeatmap(beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0])); AddStep("select available beatmap", () => Beatmap.Value = beatmapManager.GetWorkingBeatmap(beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0]));
AddAssert("button enabled", () => getAddOrRemoveButton(1).Enabled.Value); AddAssert("button enabled", () => getAddOrRemoveButton(1).Enabled.Value);
@ -150,13 +143,13 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("select available beatmap", () => Beatmap.Value = beatmapManager.GetWorkingBeatmap(beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0])); 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 BeatmapCollection(name: "1"))));
AddAssert("button is plus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.PlusSquare)); 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", () => Realm.Write(r => getFirstCollection().BeatmapMD5Hashes.Add(Beatmap.Value.BeatmapInfo.MD5Hash)));
AddAssert("button is minus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.MinusSquare)); 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", () => Realm.Write(r => getFirstCollection().BeatmapMD5Hashes.Clear()));
AddAssert("button is plus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.PlusSquare)); AddAssert("button is plus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.PlusSquare));
} }
@ -167,24 +160,26 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("select available beatmap", () => Beatmap.Value = beatmapManager.GetWorkingBeatmap(beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0])); 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 BeatmapCollection(name: "1"))));
AddAssert("button is plus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.PlusSquare)); AddAssert("button is plus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.PlusSquare));
addClickAddOrRemoveButtonStep(1); 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)); AddAssert("button is minus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.MinusSquare));
addClickAddOrRemoveButtonStep(1); 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)); AddAssert("button is plus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.PlusSquare));
} }
[Test] [Test]
public void TestManageCollectionsFilterIsNotSelected() public void TestManageCollectionsFilterIsNotSelected()
{ {
bool received = false;
addExpandHeaderStep(); addExpandHeaderStep();
AddStep("add collection", () => collectionManager.Collections.Add(new BeatmapCollection { Name = { Value = "1" } })); AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "1", new List<string> { "abc" }))));
AddStep("select collection", () => AddStep("select collection", () =>
{ {
InputManager.MoveMouseTo(getCollectionDropdownItems().ElementAt(1)); InputManager.MoveMouseTo(getCollectionDropdownItems().ElementAt(1));
@ -193,18 +188,28 @@ namespace osu.Game.Tests.Visual.SongSelect
addExpandHeaderStep(); addExpandHeaderStep();
AddStep("watch for filter requests", () =>
{
received = false;
control.ChildrenOfType<CollectionDropdown>().First().RequestFilter = () => received = true;
});
AddStep("click manage collections filter", () => AddStep("click manage collections filter", () =>
{ {
InputManager.MoveMouseTo(getCollectionDropdownItems().Last()); InputManager.MoveMouseTo(getCollectionDropdownItems().Last());
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
}); });
AddAssert("collection filter still selected", () => control.CreateCriteria().Collection?.Name.Value == "1"); AddAssert("collection filter still selected", () => control.CreateCriteria().CollectionBeatmapMD5Hashes.Any());
AddAssert("filter request not fired", () => !received);
} }
private BeatmapCollection getFirstCollection() => Realm.Run(r => r.All<BeatmapCollection>().First());
private void assertCollectionHeaderDisplays(string collectionName, bool shouldDisplay = true) private void assertCollectionHeaderDisplays(string collectionName, bool shouldDisplay = true)
=> AddAssert($"collection dropdown header displays '{collectionName}'", => AddAssert($"collection dropdown header displays '{collectionName}'",
() => shouldDisplay == (control.ChildrenOfType<CollectionFilterDropdown.CollectionDropdownHeader>().Single().ChildrenOfType<SpriteText>().First().Text == collectionName)); () => shouldDisplay == (control.ChildrenOfType<CollectionDropdown.CollectionDropdownHeader>().Single().ChildrenOfType<SpriteText>().First().Text == collectionName));
private void assertCollectionDropdownContains(string collectionName, bool shouldContain = true) => private void assertCollectionDropdownContains(string collectionName, bool shouldContain = true) =>
AddAssert($"collection dropdown {(shouldContain ? "contains" : "does not contain")} '{collectionName}'", AddAssert($"collection dropdown {(shouldContain ? "contains" : "does not contain")} '{collectionName}'",
@ -216,7 +221,7 @@ namespace osu.Game.Tests.Visual.SongSelect
private void addExpandHeaderStep() => AddStep("expand header", () => private void addExpandHeaderStep() => AddStep("expand header", () =>
{ {
InputManager.MoveMouseTo(control.ChildrenOfType<CollectionFilterDropdown.CollectionDropdownHeader>().Single()); InputManager.MoveMouseTo(control.ChildrenOfType<CollectionDropdown.CollectionDropdownHeader>().Single());
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
}); });
@ -227,6 +232,6 @@ namespace osu.Game.Tests.Visual.SongSelect
}); });
private IEnumerable<Dropdown<CollectionFilterMenuItem>.DropdownMenu.DrawableDropdownMenuItem> getCollectionDropdownItems() private IEnumerable<Dropdown<CollectionFilterMenuItem>.DropdownMenu.DrawableDropdownMenuItem> getCollectionDropdownItems()
=> control.ChildrenOfType<CollectionFilterDropdown>().Single().ChildrenOfType<Dropdown<CollectionFilterMenuItem>.DropdownMenu.DrawableDropdownMenuItem>(); => control.ChildrenOfType<CollectionDropdown>().Single().ChildrenOfType<Dropdown<CollectionFilterMenuItem>.DropdownMenu.DrawableDropdownMenuItem>();
} }
} }

View File

@ -54,7 +54,7 @@ namespace osu.Game.Tests.Visual.SongSelect
// At a point we have isolated interactive test runs enough, this can likely be removed. // At a point we have isolated interactive test runs enough, this can likely be removed.
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm)); Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(Realm); Dependencies.Cache(Realm);
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, defaultBeatmap = Beatmap.Default)); Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, defaultBeatmap = Beatmap.Default));
Dependencies.Cache(music = new MusicController()); Dependencies.Cache(music = new MusicController());

View File

@ -31,7 +31,7 @@ namespace osu.Game.Tests.Visual.SongSelect
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm)); Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(scoreManager = new ScoreManager(rulesets, () => beatmapManager, LocalStorage, Realm, Scheduler, API)); Dependencies.Cache(scoreManager = new ScoreManager(rulesets, () => beatmapManager, LocalStorage, Realm, Scheduler, API));
Dependencies.Cache(Realm); Dependencies.Cache(Realm);

View File

@ -37,7 +37,6 @@ namespace osu.Game.Tests.Visual.UserInterface
private readonly ContextMenuContainer contextMenuContainer; private readonly ContextMenuContainer contextMenuContainer;
private readonly BeatmapLeaderboard leaderboard; private readonly BeatmapLeaderboard leaderboard;
private RulesetStore rulesetStore;
private BeatmapManager beatmapManager; private BeatmapManager beatmapManager;
private ScoreManager scoreManager; private ScoreManager scoreManager;
@ -72,8 +71,8 @@ namespace osu.Game.Tests.Visual.UserInterface
{ {
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
dependencies.Cache(rulesetStore = new RealmRulesetStore(Realm)); dependencies.Cache(new RealmRulesetStore(Realm));
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, rulesetStore, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default)); dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default));
dependencies.Cache(scoreManager = new ScoreManager(dependencies.Get<RulesetStore>(), () => beatmapManager, LocalStorage, Realm, Scheduler, API)); dependencies.Cache(scoreManager = new ScoreManager(dependencies.Get<RulesetStore>(), () => beatmapManager, LocalStorage, Realm, Scheduler, API));
Dependencies.Cache(Realm); Dependencies.Cache(Realm);

View File

@ -14,9 +14,6 @@ using osu.Game.IO.Serialization.Converters;
namespace osu.Game.Beatmaps namespace osu.Game.Beatmaps
{ {
/// <summary>
/// A Beatmap containing converted HitObjects.
/// </summary>
public class Beatmap<T> : IBeatmap<T> public class Beatmap<T> : IBeatmap<T>
where T : HitObject where T : HitObject
{ {

View File

@ -14,6 +14,7 @@ using osu.Framework.Logging;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Formats;
using osu.Game.Collections;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Extensions; using osu.Game.Extensions;
using osu.Game.IO; using osu.Game.IO;
@ -71,6 +72,8 @@ namespace osu.Game.Beatmaps
// Transfer local values which should be persisted across a beatmap update. // Transfer local values which should be persisted across a beatmap update.
updated.DateAdded = original.DateAdded; updated.DateAdded = original.DateAdded;
transferCollectionReferences(realm, original, updated);
foreach (var beatmap in original.Beatmaps.ToArray()) foreach (var beatmap in original.Beatmaps.ToArray())
{ {
var updatedBeatmap = updated.Beatmaps.FirstOrDefault(b => b.Hash == beatmap.Hash); var updatedBeatmap = updated.Beatmaps.FirstOrDefault(b => b.Hash == beatmap.Hash);
@ -112,6 +115,40 @@ namespace osu.Game.Beatmaps
return first; return first;
} }
private static void transferCollectionReferences(Realm realm, BeatmapSetInfo original, BeatmapSetInfo updated)
{
// First check if every beatmap in the original set is in any collections.
// In this case, we will assume they also want any newly added difficulties added to the collection.
foreach (var c in realm.All<BeatmapCollection>())
{
if (original.Beatmaps.Select(b => b.MD5Hash).All(c.BeatmapMD5Hashes.Contains))
{
foreach (var b in original.Beatmaps)
c.BeatmapMD5Hashes.Remove(b.MD5Hash);
foreach (var b in updated.Beatmaps)
c.BeatmapMD5Hashes.Add(b.MD5Hash);
}
}
// Handle collections using permissive difficulty name to track difficulties.
foreach (var originalBeatmap in original.Beatmaps)
{
var updatedBeatmap = updated.Beatmaps.FirstOrDefault(b => b.DifficultyName == originalBeatmap.DifficultyName);
if (updatedBeatmap == null)
continue;
var collections = realm.All<BeatmapCollection>().AsEnumerable().Where(c => c.BeatmapMD5Hashes.Contains(originalBeatmap.MD5Hash));
foreach (var c in collections)
{
c.BeatmapMD5Hashes.Remove(originalBeatmap.MD5Hash);
c.BeatmapMD5Hashes.Add(updatedBeatmap.MD5Hash);
}
}
}
protected override bool ShouldDeleteArchive(string path) => Path.GetExtension(path).ToLowerInvariant() == ".osz"; protected override bool ShouldDeleteArchive(string path) => Path.GetExtension(path).ToLowerInvariant() == ".osz";
protected override void Populate(BeatmapSetInfo beatmapSet, ArchiveReader? archive, Realm realm, CancellationToken cancellationToken = default) protected override void Populate(BeatmapSetInfo beatmapSet, ArchiveReader? archive, Realm realm, CancellationToken cancellationToken = default)

View File

@ -20,8 +20,12 @@ using Realms;
namespace osu.Game.Beatmaps namespace osu.Game.Beatmaps
{ {
/// <summary> /// <summary>
/// A single beatmap difficulty. /// A realm model containing metadata for a single beatmap difficulty.
/// This should generally include anything which is required to be filtered on at song select, or anything pertaining to storage of beatmaps in the client.
/// </summary> /// </summary>
/// <remarks>
/// There are some legacy fields in this model which are not persisted to realm. These are isolated in a code region within the class and should eventually be migrated to `Beatmap`.
/// </remarks>
[ExcludeFromDynamicCompile] [ExcludeFromDynamicCompile]
[Serializable] [Serializable]
[MapTo("Beatmap")] [MapTo("Beatmap")]

View File

@ -44,7 +44,7 @@ namespace osu.Game.Beatmaps
public Action<BeatmapSetInfo>? ProcessBeatmap { private get; set; } public Action<BeatmapSetInfo>? ProcessBeatmap { private get; set; }
public BeatmapManager(Storage storage, RealmAccess realm, RulesetStore rulesets, IAPIProvider? api, AudioManager audioManager, IResourceStore<byte[]> gameResources, GameHost? host = null, public BeatmapManager(Storage storage, RealmAccess realm, IAPIProvider? api, AudioManager audioManager, IResourceStore<byte[]> gameResources, GameHost? host = null,
WorkingBeatmap? defaultBeatmap = null, BeatmapDifficultyCache? difficultyCache = null, bool performOnlineLookups = false) WorkingBeatmap? defaultBeatmap = null, BeatmapDifficultyCache? difficultyCache = null, bool performOnlineLookups = false)
: base(storage, realm) : base(storage, realm)
{ {

View File

@ -12,6 +12,17 @@ using Realms;
namespace osu.Game.Beatmaps namespace osu.Game.Beatmaps
{ {
/// <summary>
/// A realm model containing metadata for a beatmap.
/// </summary>
/// <remarks>
/// This is currently stored against each beatmap difficulty, even when it is duplicated.
/// It is also provided via <see cref="BeatmapSetInfo"/> for convenience and historical purposes.
/// A future effort could see this converted to an <see cref="EmbeddedObject"/> or potentially de-duped
/// and shared across multiple difficulties in the same set, if required.
///
/// Note that difficulty name is not stored in this metadata but in <see cref="BeatmapInfo"/>.
/// </remarks>
[ExcludeFromDynamicCompile] [ExcludeFromDynamicCompile]
[Serializable] [Serializable]
[MapTo("BeatmapMetadata")] [MapTo("BeatmapMetadata")]

View File

@ -14,6 +14,9 @@ using Realms;
namespace osu.Game.Beatmaps namespace osu.Game.Beatmaps
{ {
/// <summary>
/// A realm model containing metadata for a beatmap set (containing multiple <see cref="BeatmapInfo"/>s).
/// </summary>
[ExcludeFromDynamicCompile] [ExcludeFromDynamicCompile]
[MapTo("BeatmapSet")] [MapTo("BeatmapSet")]
public class BeatmapSetInfo : RealmObject, IHasGuidPrimaryKey, IHasRealmFiles, ISoftDelete, IEquatable<BeatmapSetInfo>, IBeatmapSetInfo public class BeatmapSetInfo : RealmObject, IHasGuidPrimaryKey, IHasRealmFiles, ISoftDelete, IEquatable<BeatmapSetInfo>, IBeatmapSetInfo

Some files were not shown because too many files have changed in this diff Show More