From b93bbf81aa4cba9b9ad840a4c804d7419c3a25be Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 10 Dec 2019 15:10:35 +0300 Subject: [PATCH 01/28] Add lighten background during breaks setting --- osu.Game/Configuration/OsuConfigManager.cs | 2 ++ .../Overlays/Settings/Sections/Gameplay/GeneralSettings.cs | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index b71463841a..947e864a87 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -80,6 +80,7 @@ namespace osu.Game.Configuration // Gameplay Set(OsuSetting.DimLevel, 0.3, 0, 1, 0.01); Set(OsuSetting.BlurLevel, 0, 0, 1, 0.01); + Set(OsuSetting.LightenDuringBreaks, true); Set(OsuSetting.HitLighting, true); @@ -142,6 +143,7 @@ namespace osu.Game.Configuration AutoCursorSize, DimLevel, BlurLevel, + LightenDuringBreaks, ShowStoryboard, ShowVideoBackground, KeyOverlay, diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index f4aa9a0144..3f8bc2b0c7 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -30,6 +30,11 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay KeyboardStep = 0.01f }, new SettingsCheckbox + { + LabelText = "Lighten playfield during breaks", + Bindable = config.GetBindable(OsuSetting.LightenDuringBreaks) + }, + new SettingsCheckbox { LabelText = "Show score overlay", Bindable = config.GetBindable(OsuSetting.ShowInterface) From bb078c2afc82b34bc1e9fae15cd8b09627d38892 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 10 Dec 2019 15:13:44 +0300 Subject: [PATCH 02/28] Lighten user-dim container if on break time --- .../Graphics/Containers/UserDimContainer.cs | 22 ++++++++++++++++--- .../Backgrounds/BackgroundScreenBeatmap.cs | 3 +++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index 7683bbcd63..20f5a4fd83 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -1,11 +1,13 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Configuration; +using osu.Game.Screens.Play; namespace osu.Game.Graphics.Containers { @@ -14,7 +16,9 @@ namespace osu.Game.Graphics.Containers /// public abstract class UserDimContainer : Container { - protected const float BACKGROUND_FADE_DURATION = 800; + private const float break_lighten_amount = 0.3f; + + protected const double BACKGROUND_FADE_DURATION = 800; /// /// Whether or not user-configured dim levels should be applied to the container. @@ -26,6 +30,12 @@ namespace osu.Game.Graphics.Containers /// public readonly Bindable StoryboardReplacesBackground = new Bindable(); + /// + /// Whether player is in break time. + /// Must be bound to to allow for dim adjustments in gameplay. + /// + internal readonly IBindable IsBreakTime = new Bindable(); + /// /// Whether the content of this container is currently being displayed. /// @@ -33,11 +43,14 @@ namespace osu.Game.Graphics.Containers protected Bindable UserDimLevel { get; private set; } + protected Bindable LightenDuringBreaks { get; private set; } + protected Bindable ShowStoryboard { get; private set; } protected Bindable ShowVideo { get; private set; } - protected double DimLevel => EnableUserDim.Value ? UserDimLevel.Value : 0; + private float breakLightening => LightenDuringBreaks.Value && IsBreakTime.Value ? break_lighten_amount : 0; + protected float DimLevel => Math.Max(EnableUserDim.Value ? (float)UserDimLevel.Value - breakLightening : 0, 0); protected override Container Content => dimContent; @@ -55,11 +68,14 @@ namespace osu.Game.Graphics.Containers private void load(OsuConfigManager config) { UserDimLevel = config.GetBindable(OsuSetting.DimLevel); + LightenDuringBreaks = config.GetBindable(OsuSetting.LightenDuringBreaks); ShowStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); ShowVideo = config.GetBindable(OsuSetting.ShowVideoBackground); EnableUserDim.ValueChanged += _ => UpdateVisuals(); UserDimLevel.ValueChanged += _ => UpdateVisuals(); + LightenDuringBreaks.ValueChanged += _ => UpdateVisuals(); + IsBreakTime.ValueChanged += _ => UpdateVisuals(); ShowStoryboard.ValueChanged += _ => UpdateVisuals(); ShowVideo.ValueChanged += _ => UpdateVisuals(); StoryboardReplacesBackground.ValueChanged += _ => UpdateVisuals(); @@ -84,7 +100,7 @@ namespace osu.Game.Graphics.Containers ContentDisplayed = ShowDimContent; dimContent.FadeTo(ContentDisplayed ? 1 : 0, BACKGROUND_FADE_DURATION, Easing.OutQuint); - dimContent.FadeColour(OsuColour.Gray(1 - (float)DimLevel), BACKGROUND_FADE_DURATION, Easing.OutQuint); + dimContent.FadeColour(OsuColour.Gray(1f - DimLevel), BACKGROUND_FADE_DURATION, Easing.OutQuint); } } } diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs index 7b68460e6b..1ab3a5b533 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs @@ -38,6 +38,8 @@ namespace osu.Game.Screens.Backgrounds /// public readonly Bindable BlurAmount = new Bindable(); + internal readonly IBindable IsBreakTime = new Bindable(); + private readonly DimmableBackground dimmable; protected virtual DimmableBackground CreateFadeContainer() => new DimmableBackground { RelativeSizeAxes = Axes.Both }; @@ -48,6 +50,7 @@ namespace osu.Game.Screens.Backgrounds InternalChild = dimmable = CreateFadeContainer(); dimmable.EnableUserDim.BindTo(EnableUserDim); + dimmable.IsBreakTime.BindTo(IsBreakTime); dimmable.BlurAmount.BindTo(BlurAmount); } From 38f1a8bc170d11a3a4edacc4d058f7ef791fbd32 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 10 Dec 2019 15:14:47 +0300 Subject: [PATCH 03/28] Bind UserDimContainer.IsBreakTime from Player --- osu.Game/Screens/Play/Player.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index d40c448452..9b372c3791 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -140,6 +140,11 @@ namespace osu.Game.Screens.Play // bind clock into components that require it DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused); + // bind break into components that require it. + Background.IsBreakTime.BindTo(breakOverlay.IsBreakTime); + DimmableStoryboard.IsBreakTime.BindTo(breakOverlay.IsBreakTime); + DimmableVideo.IsBreakTime.BindTo(breakOverlay.IsBreakTime); + // Bind ScoreProcessor to ourselves ScoreProcessor.AllJudged += onCompletion; ScoreProcessor.Failed += onFail; From 63f66aa5fa9fa2c178910e6bb9f1a68de5e0a372 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 10 Dec 2019 15:25:03 +0300 Subject: [PATCH 04/28] Check by UserDimContainer.DimLevel instead --- .../Visual/Background/TestSceneUserDimContainer.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs index 8f71584b4d..910c462718 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs @@ -314,7 +314,7 @@ namespace osu.Game.Tests.Visual.Background config.BindWith(OsuSetting.BlurLevel, BlurLevel); } - public bool IsBackgroundDimmed() => ((FadeAccessibleBackground)Background).CurrentColour == OsuColour.Gray(1 - (float)DimLevel.Value); + public bool IsBackgroundDimmed() => ((FadeAccessibleBackground)Background).CurrentColour == OsuColour.Gray(1f - ((FadeAccessibleBackground)Background).CurrentDim); public bool IsBackgroundUndimmed() => ((FadeAccessibleBackground)Background).CurrentColour == Color4.White; @@ -404,6 +404,8 @@ namespace osu.Game.Tests.Visual.Background public float CurrentAlpha => dimmable.CurrentAlpha; + public float CurrentDim => dimmable.DimLevel; + public Vector2 CurrentBlur => Background.BlurSigma; private TestDimmableBackground dimmable; @@ -418,6 +420,8 @@ namespace osu.Game.Tests.Visual.Background { public Color4 CurrentColour => Content.Colour; public float CurrentAlpha => Content.Alpha; + + public new float DimLevel => base.DimLevel; } } } From 53daa37eaa97e3575261c333f67b68cd6ab5ad92 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 10 Dec 2019 23:06:13 +0300 Subject: [PATCH 05/28] Fix failing tests --- osu.Game/Screens/Play/Player.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 9b372c3791..8684798632 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -140,11 +140,6 @@ namespace osu.Game.Screens.Play // bind clock into components that require it DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused); - // bind break into components that require it. - Background.IsBreakTime.BindTo(breakOverlay.IsBreakTime); - DimmableStoryboard.IsBreakTime.BindTo(breakOverlay.IsBreakTime); - DimmableVideo.IsBreakTime.BindTo(breakOverlay.IsBreakTime); - // Bind ScoreProcessor to ourselves ScoreProcessor.AllJudged += onCompletion; ScoreProcessor.Failed += onFail; @@ -506,6 +501,11 @@ namespace osu.Game.Screens.Play Background.EnableUserDim.Value = true; Background.BlurAmount.Value = 0; + // bind component bindables. + Background.IsBreakTime.BindTo(breakOverlay.IsBreakTime); + DimmableStoryboard.IsBreakTime.BindTo(breakOverlay.IsBreakTime); + DimmableVideo.IsBreakTime.BindTo(breakOverlay.IsBreakTime); + Background.StoryboardReplacesBackground.BindTo(storyboardReplacesBackground); DimmableStoryboard.StoryboardReplacesBackground.BindTo(storyboardReplacesBackground); From bc02cfc2e24cdaa26832f004b8ad8910b5b8342c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 12 Dec 2019 00:30:16 +0300 Subject: [PATCH 06/28] TestSceneUserDimContainer -> TestSceneUserDimBackgrounds --- ...tSceneUserDimContainer.cs => TestSceneUserDimBackgrounds.cs} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename osu.Game.Tests/Visual/Background/{TestSceneUserDimContainer.cs => TestSceneUserDimBackgrounds.cs} (99%) diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs similarity index 99% rename from osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs rename to osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs index 910c462718..2d2726bbd3 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs @@ -36,7 +36,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Background { [TestFixture] - public class TestSceneUserDimContainer : ManualInputManagerTestScene + public class TestSceneUserDimBackgrounds : ManualInputManagerTestScene { public override IReadOnlyList RequiredTypes => new[] { From 4f6b85e5ea19381ab19a2ebdab80336bcf4a59e0 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 12 Dec 2019 00:32:39 +0300 Subject: [PATCH 07/28] Add test ensuring correct break lightening behaviour --- .../Background/TestSceneUserDimContainer.cs | 82 +++++++++++++++++++ .../Graphics/Containers/UserDimContainer.cs | 5 +- 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs new file mode 100644 index 0000000000..0aad9bed75 --- /dev/null +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs @@ -0,0 +1,82 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Game.Configuration; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osuTK.Graphics; + +namespace osu.Game.Tests.Visual.Background +{ + public class TestSceneUserDimContainer : OsuTestScene + { + private readonly TestUserDimContainer container; + private readonly BindableBool isBreakTime = new BindableBool(); + private readonly Bindable lightenDuringBreaks = new Bindable(); + + public TestSceneUserDimContainer() + { + Add(container = new TestUserDimContainer + { + RelativeSizeAxes = Axes.Both, + Child = new Box + { + Colour = Color4.White, + RelativeSizeAxes = Axes.Both, + }, + }); + + container.IsBreakTime.BindTo(isBreakTime); + } + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + config.BindWith(OsuSetting.LightenDuringBreaks, lightenDuringBreaks); + } + + [SetUp] + public void SetUp() + { + isBreakTime.Value = false; + lightenDuringBreaks.Value = false; + } + + [TestCase(0.6f, 0.3f)] + [TestCase(0.2f, 0.0f)] + [TestCase(0.0f, 0.0f)] + public void TestBreakLightening(float userDim, float expectedBreakDim) + { + AddStep($"set dim level {userDim}", () => container.UserDimLevel.Value = userDim); + + AddStep("set break", () => isBreakTime.Value = true); + AddWaitStep("wait for dim", 3); + AddAssert($"is current dim {userDim}", () => container.DimEqual(userDim)); + + AddStep("set lighten during break", () => lightenDuringBreaks.Value = true); + AddWaitStep("wait for dim", 3); + AddAssert($"is current dim {expectedBreakDim}", () => container.DimEqual(expectedBreakDim)); + + AddStep("clear lighten during break", () => lightenDuringBreaks.Value = false); + AddWaitStep("wait for dim", 3); + AddAssert($"is current dim {userDim}", () => container.DimEqual(userDim)); + + AddStep("clear break", () => isBreakTime.Value = false); + AddStep("set lighten during break", () => lightenDuringBreaks.Value = true); + AddWaitStep("wait for dim", 3); + AddAssert($"is current dim {userDim}", () => container.DimEqual(userDim)); + } + + private class TestUserDimContainer : UserDimContainer + { + public bool DimEqual(float expectedDimLevel) => Content.Colour == OsuColour.Gray(1f - expectedDimLevel); + + public new Bindable UserDimLevel => base.UserDimLevel; + } + } +} diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index 20f5a4fd83..dcc8a52e9d 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -16,6 +16,9 @@ namespace osu.Game.Graphics.Containers /// public abstract class UserDimContainer : Container { + /// + /// Amount of lightening to apply to current dim level during break times. + /// private const float break_lighten_amount = 0.3f; protected const double BACKGROUND_FADE_DURATION = 800; @@ -34,7 +37,7 @@ namespace osu.Game.Graphics.Containers /// Whether player is in break time. /// Must be bound to to allow for dim adjustments in gameplay. /// - internal readonly IBindable IsBreakTime = new Bindable(); + public readonly IBindable IsBreakTime = new Bindable(); /// /// Whether the content of this container is currently being displayed. From 61265ed452d14b2353bc5957ae5af6b25e442a2b Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 12 Dec 2019 00:52:33 +0300 Subject: [PATCH 08/28] Increase the waiting steps --- .../Visual/Background/TestSceneUserDimContainer.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs index 0aad9bed75..bdbfacaea2 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs @@ -55,20 +55,20 @@ namespace osu.Game.Tests.Visual.Background AddStep($"set dim level {userDim}", () => container.UserDimLevel.Value = userDim); AddStep("set break", () => isBreakTime.Value = true); - AddWaitStep("wait for dim", 3); + AddWaitStep("wait for dim", 5); AddAssert($"is current dim {userDim}", () => container.DimEqual(userDim)); AddStep("set lighten during break", () => lightenDuringBreaks.Value = true); - AddWaitStep("wait for dim", 3); + AddWaitStep("wait for dim", 5); AddAssert($"is current dim {expectedBreakDim}", () => container.DimEqual(expectedBreakDim)); AddStep("clear lighten during break", () => lightenDuringBreaks.Value = false); - AddWaitStep("wait for dim", 3); + AddWaitStep("wait for dim", 5); AddAssert($"is current dim {userDim}", () => container.DimEqual(userDim)); AddStep("clear break", () => isBreakTime.Value = false); AddStep("set lighten during break", () => lightenDuringBreaks.Value = true); - AddWaitStep("wait for dim", 3); + AddWaitStep("wait for dim", 5); AddAssert($"is current dim {userDim}", () => container.DimEqual(userDim)); } From 035a53cb9e2edb0f232369aa933989b2c0b3fdb8 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 12 Dec 2019 01:10:43 +0300 Subject: [PATCH 09/28] Schedule SetUp() --- osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs index bdbfacaea2..25c11d2292 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs @@ -41,11 +41,11 @@ namespace osu.Game.Tests.Visual.Background } [SetUp] - public void SetUp() + public void SetUp() => Schedule(() => { isBreakTime.Value = false; lightenDuringBreaks.Value = false; - } + }); [TestCase(0.6f, 0.3f)] [TestCase(0.2f, 0.0f)] From 6a539e307a2bdab3517ee840ee542dcf462c162c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 12 Dec 2019 09:20:56 +0300 Subject: [PATCH 10/28] Split into small tests and add more cases --- .../Background/TestSceneUserDimContainer.cs | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs index 25c11d2292..03206402c3 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs @@ -53,23 +53,37 @@ namespace osu.Game.Tests.Visual.Background public void TestBreakLightening(float userDim, float expectedBreakDim) { AddStep($"set dim level {userDim}", () => container.UserDimLevel.Value = userDim); + AddStep("set lighten during break", () => lightenDuringBreaks.Value = true); AddStep("set break", () => isBreakTime.Value = true); - AddWaitStep("wait for dim", 5); - AddAssert($"is current dim {userDim}", () => container.DimEqual(userDim)); - - AddStep("set lighten during break", () => lightenDuringBreaks.Value = true); - AddWaitStep("wait for dim", 5); - AddAssert($"is current dim {expectedBreakDim}", () => container.DimEqual(expectedBreakDim)); - - AddStep("clear lighten during break", () => lightenDuringBreaks.Value = false); - AddWaitStep("wait for dim", 5); - AddAssert($"is current dim {userDim}", () => container.DimEqual(userDim)); - + AddUntilStep("has lightened", () => container.DimEqual(expectedBreakDim)); AddStep("clear break", () => isBreakTime.Value = false); + AddUntilStep("not lightened", () => container.DimEqual(userDim)); + } + + [Test] + public void TestEnableSettingDuringBreak() + { + AddStep("set dim level 0.6", () => container.UserDimLevel.Value = 0.6f); + + AddStep("set break", () => isBreakTime.Value = true); + AddUntilStep("not lightened", () => container.DimEqual(0.6f)); AddStep("set lighten during break", () => lightenDuringBreaks.Value = true); - AddWaitStep("wait for dim", 5); - AddAssert($"is current dim {userDim}", () => container.DimEqual(userDim)); + AddUntilStep("has lightened", () => container.DimEqual(0.3f)); + } + + [Test] + public void TestDisableSettingDuringBreak() + { + AddStep("set dim level 0.6", () => container.UserDimLevel.Value = 0.6f); + AddStep("set lighten during break", () => lightenDuringBreaks.Value = true); + + AddStep("set break", () => isBreakTime.Value = true); + AddUntilStep("has lightened", () => container.DimEqual(0.3f)); + AddStep("clear lighten during break", () => lightenDuringBreaks.Value = false); + AddUntilStep("not lightened", () => container.DimEqual(0.6f)); + AddStep("clear break", () => isBreakTime.Value = false); + AddUntilStep("not lightened", () => container.DimEqual(0.6f)); } private class TestUserDimContainer : UserDimContainer From 5861eca80d291bbfd6261ca732d4101012a86713 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Dec 2019 15:58:11 +0900 Subject: [PATCH 11/28] Make DrawableRuleset take a converted beatmap --- .../TestSceneDrawableHitObjects.cs | 2 +- osu.Game.Rulesets.Catch/CatchRuleset.cs | 2 +- .../UI/DrawableCatchRuleset.cs | 4 +- .../Edit/DrawableManiaEditRuleset.cs | 2 +- .../Edit/ManiaHitObjectComposer.cs | 2 +- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- .../UI/DrawableManiaRuleset.cs | 2 +- .../Edit/DrawableOsuEditRuleset.cs | 2 +- .../Edit/OsuHitObjectComposer.cs | 2 +- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- .../UI/DrawableOsuRuleset.cs | 2 +- .../TestSceneTaikoPlayfield.cs | 3 +- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 +- .../UI/DrawableTaikoRuleset.cs | 2 +- .../TestSceneDrawableScrollingRuleset.cs | 6 +-- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/IWorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 4 +- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 8 ++-- osu.Game/Rulesets/Ruleset.cs | 2 +- osu.Game/Rulesets/UI/DrawableRuleset.cs | 18 ++++---- .../UI/Scrolling/DrawableScrollingRuleset.cs | 2 +- osu.Game/Screens/Play/Player.cs | 41 ++++++++++--------- 23 files changed, 59 insertions(+), 57 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs index 0369b6db4e..02a017ce45 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs @@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Catch.Tests RelativeSizeAxes = Axes.Both, Children = new[] { - drawableRuleset = new DrawableCatchRuleset(new CatchRuleset(), beatmap, Array.Empty()) + drawableRuleset = new DrawableCatchRuleset(new CatchRuleset(), beatmap.GetPlayableBeatmap(new CatchRuleset().RulesetInfo)) } }); diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 71d68ace94..506fa23fa9 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Catch { public class CatchRuleset : Ruleset { - public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableCatchRuleset(this, beatmap, mods); + public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList mods = null) => new DrawableCatchRuleset(this, beatmap, mods); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap); public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new CatchBeatmapProcessor(beatmap); diff --git a/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs index f5bddeb2cb..278ff97195 100644 --- a/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs @@ -25,11 +25,11 @@ namespace osu.Game.Rulesets.Catch.UI protected override bool UserScrollSpeedAdjustment => false; - public DrawableCatchRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) + public DrawableCatchRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) : base(ruleset, beatmap, mods) { Direction.Value = ScrollingDirection.Down; - TimeRange.Value = BeatmapDifficulty.DifficultyRange(beatmap.Beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450); + TimeRange.Value = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450); } public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(Beatmap); diff --git a/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs b/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs index 97d8aaa052..445df79f6f 100644 --- a/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs +++ b/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mania.Edit { public new IScrollingInfo ScrollingInfo => base.ScrollingInfo; - public DrawableManiaEditRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) + public DrawableManiaEditRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods) : base(ruleset, beatmap, mods) { } diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs index 0bfe6f9517..1632b6a583 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mania.Edit public int TotalColumns => ((ManiaPlayfield)drawableRuleset.Playfield).TotalColumns; - protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) + protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) { drawableRuleset = new DrawableManiaEditRuleset(ruleset, beatmap, mods); diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index c74a292331..a96c79b40b 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Mania { public class ManiaRuleset : Ruleset { - public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableManiaRuleset(this, beatmap, mods); + public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList mods = null) => new DrawableManiaRuleset(this, beatmap, mods); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap); public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new ManiaPerformanceCalculator(this, beatmap, score); diff --git a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs index 0607bf0abd..cf1970c28b 100644 --- a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.UI private readonly Bindable configDirection = new Bindable(); - public DrawableManiaRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) + public DrawableManiaRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) : base(ruleset, beatmap, mods) { BarLines = new BarLineGenerator(Beatmap).BarLines; diff --git a/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs b/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs index 3437af8c1e..22b4c3e82e 100644 --- a/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs +++ b/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Edit /// private const double editor_hit_object_fade_out_extension = 500; - public DrawableOsuEditRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) + public DrawableOsuEditRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods) : base(ruleset, beatmap, mods) { } diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 812afaaa24..675b09fc6d 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Edit { } - protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) + protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) => new DrawableOsuEditRuleset(ruleset, beatmap, mods); protected override IReadOnlyList CompositionTools => new HitObjectCompositionTool[] diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index fa69cec78d..2f43909332 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu { public class OsuRuleset : Ruleset { - public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableOsuRuleset(this, beatmap, mods); + public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList mods = null) => new DrawableOsuRuleset(this, beatmap, mods); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new OsuBeatmapConverter(beatmap); public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new OsuBeatmapProcessor(beatmap); diff --git a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs index 5bb728a9b0..039d38e4fd 100644 --- a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.UI { protected new OsuRulesetConfigManager Config => (OsuRulesetConfigManager)base.Config; - public DrawableOsuRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) + public DrawableOsuRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) : base(ruleset, beatmap, mods) { } diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs index 8522a42739..b2c8c7feda 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs @@ -11,7 +11,6 @@ using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Judgements; -using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; @@ -91,7 +90,7 @@ namespace osu.Game.Rulesets.Taiko.Tests Origin = Anchor.Centre, RelativeSizeAxes = Axes.X, Height = 768, - Children = new[] { drawableRuleset = new DrawableTaikoRuleset(new TaikoRuleset(), beatmap, Array.Empty()) } + Children = new[] { drawableRuleset = new DrawableTaikoRuleset(new TaikoRuleset(), beatmap.GetPlayableBeatmap(new TaikoRuleset().RulesetInfo)) } }); } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index b2655f592c..ab9c95159c 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Taiko { public class TaikoRuleset : Ruleset { - public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableTaikoRuleset(this, beatmap, mods); + public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList mods = null) => new DrawableTaikoRuleset(this, beatmap, mods); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap); public const string SHORT_NAME = "taiko"; diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs index d4ea9a043a..2233658428 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Taiko.UI protected override bool UserScrollSpeedAdjustment => false; - public DrawableTaikoRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) + public DrawableTaikoRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) : base(ruleset, beatmap, mods) { Direction.Value = ScrollingDirection.Left; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs index 684e79b3f5..071dc381e0 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs @@ -172,7 +172,7 @@ namespace osu.Game.Tests.Visual.Gameplay { var ruleset = new TestScrollingRuleset(); - drawableRuleset = (TestDrawableScrollingRuleset)ruleset.CreateDrawableRulesetWith(CreateWorkingBeatmap(beatmap), Array.Empty()); + drawableRuleset = (TestDrawableScrollingRuleset)ruleset.CreateDrawableRulesetWith(beatmap); drawableRuleset.FrameStablePlayback = false; overrideAction?.Invoke(drawableRuleset); @@ -201,7 +201,7 @@ namespace osu.Game.Tests.Visual.Gameplay public override IEnumerable GetModsFor(ModType type) => throw new NotImplementedException(); - public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList mods) => new TestDrawableScrollingRuleset(this, beatmap, mods); + public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList mods = null) => new TestDrawableScrollingRuleset(this, beatmap, mods); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TestBeatmapConverter(beatmap); @@ -222,7 +222,7 @@ namespace osu.Game.Tests.Visual.Gameplay public new Bindable TimeRange => base.TimeRange; - public TestDrawableScrollingRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) + public TestDrawableScrollingRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) : base(ruleset, beatmap, mods) { TimeRange.Value = time_range; diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index a3ab01c886..59a27e3fde 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -57,7 +57,7 @@ namespace osu.Game.Beatmaps { public override IEnumerable GetModsFor(ModType type) => new Mod[] { }; - public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList mods) + public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList mods = null) { throw new NotImplementedException(); } diff --git a/osu.Game/Beatmaps/IWorkingBeatmap.cs b/osu.Game/Beatmaps/IWorkingBeatmap.cs index a087a52ada..5f1f0d1e40 100644 --- a/osu.Game/Beatmaps/IWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/IWorkingBeatmap.cs @@ -62,6 +62,6 @@ namespace osu.Game.Beatmaps /// The s to apply to the . /// The converted . /// If could not be converted to . - IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods); + IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods = null); } } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 4452d26fcd..1255665cf0 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -99,8 +99,10 @@ namespace osu.Game.Beatmaps /// The applicable . protected virtual IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap, Ruleset ruleset) => ruleset.CreateBeatmapConverter(beatmap); - public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods) + public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods = null) { + mods ??= Array.Empty(); + var rulesetInstance = ruleset.CreateInstance(); IBeatmapConverter converter = CreateBeatmapConverter(Beatmap, rulesetInstance); diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 9ac967ef74..22d94abcb9 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -48,7 +48,6 @@ namespace osu.Game.Rulesets.Edit [Resolved] private BindableBeatDivisor beatDivisor { get; set; } - private IWorkingBeatmap workingBeatmap; private Beatmap playableBeatmap; private IBeatmapProcessor beatmapProcessor; @@ -71,7 +70,7 @@ namespace osu.Game.Rulesets.Edit { try { - drawableRulesetWrapper = new DrawableEditRulesetWrapper(CreateDrawableRuleset(Ruleset, workingBeatmap, Array.Empty())) + drawableRulesetWrapper = new DrawableEditRulesetWrapper(CreateDrawableRuleset(Ruleset, playableBeatmap)) { Clock = framedClock, ProcessCustomClock = false @@ -145,8 +144,7 @@ namespace osu.Game.Rulesets.Edit { var parentWorkingBeatmap = parent.Get>().Value; - playableBeatmap = (Beatmap)parentWorkingBeatmap.GetPlayableBeatmap(Ruleset.RulesetInfo, Array.Empty()); - workingBeatmap = new EditorWorkingBeatmap(playableBeatmap, parentWorkingBeatmap); + playableBeatmap = (Beatmap)parentWorkingBeatmap.GetPlayableBeatmap(Ruleset.RulesetInfo); beatmapProcessor = Ruleset.CreateBeatmapProcessor(playableBeatmap); @@ -250,7 +248,7 @@ namespace osu.Game.Rulesets.Edit protected abstract IReadOnlyList CompositionTools { get; } - protected abstract DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods); + protected abstract DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null); public void BeginPlacement(HitObject hitObject) { diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index dd1b3615c7..45aa904b98 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -60,7 +60,7 @@ namespace osu.Game.Rulesets /// The s to apply. /// Unable to successfully load the beatmap to be usable with this ruleset. /// - public abstract DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList mods); + public abstract DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList mods = null); /// /// Creates a to convert a to one that is applicable for this . diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 10657f6b39..5033fd0686 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -98,7 +98,7 @@ namespace osu.Game.Rulesets.UI /// /// The beatmap. /// - public Beatmap Beatmap; + public readonly Beatmap Beatmap; public override IEnumerable Objects => Beatmap.HitObjects; @@ -118,20 +118,22 @@ namespace osu.Game.Rulesets.UI /// Creates a ruleset visualisation for the provided ruleset and beatmap. /// /// The ruleset being represented. - /// The beatmap to create the hit renderer for. + /// The beatmap to create the hit renderer for. /// The s to apply. - protected DrawableRuleset(Ruleset ruleset, IWorkingBeatmap workingBeatmap, IReadOnlyList mods) + protected DrawableRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) : base(ruleset) { - if (workingBeatmap == null) - throw new ArgumentException("Beatmap cannot be null.", nameof(workingBeatmap)); + if (beatmap == null) + throw new ArgumentNullException(nameof(beatmap), "Beatmap cannot be null."); - this.mods = mods.ToArray(); + if (!(beatmap is Beatmap tBeatmap)) + throw new ArgumentException($"{GetType()} expected the beatmap to contain hitobjects of type {typeof(TObject)}.", nameof(beatmap)); + + Beatmap = tBeatmap; + this.mods = mods?.ToArray() ?? Array.Empty(); RelativeSizeAxes = Axes.Both; - Beatmap = (Beatmap)workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo, mods); - KeyBindingInputManager = CreateInputManager(); playfield = new Lazy(CreatePlayfield); diff --git a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs index cf714b5d46..fda1d7c723 100644 --- a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs +++ b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs @@ -85,7 +85,7 @@ namespace osu.Game.Rulesets.UI.Scrolling [Cached(Type = typeof(IScrollingInfo))] private readonly LocalScrollingInfo scrollingInfo; - protected DrawableScrollingRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) + protected DrawableScrollingRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) : base(ruleset, beatmap, mods) { scrollingInfo = new LocalScrollingInfo(); diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 9f4ca7d817..b65d20dcbb 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -114,26 +114,31 @@ namespace osu.Game.Screens.Play Mods.Value = base.Mods.Value.Select(m => m.CreateCopy()).ToArray(); - WorkingBeatmap working = loadBeatmap(); + if (Beatmap.Value is DummyWorkingBeatmap) + return; - if (working == null) + IBeatmap playableBeatmap = loadPlayableBeatmap(); + + if (playableBeatmap == null) return; sampleRestart = audio.Samples.Get(@"Gameplay/restart"); mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); + DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, Mods.Value); + ScoreProcessor = DrawableRuleset.CreateScoreProcessor(); ScoreProcessor.Mods.BindTo(Mods); if (!ScoreProcessor.Mode.Disabled) config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); - InternalChild = GameplayClockContainer = new GameplayClockContainer(working, Mods.Value, DrawableRuleset.GameplayStartTime); + InternalChild = GameplayClockContainer = new GameplayClockContainer(Beatmap.Value, Mods.Value, DrawableRuleset.GameplayStartTime); addUnderlayComponents(GameplayClockContainer); - addGameplayComponents(GameplayClockContainer, working); - addOverlayComponents(GameplayClockContainer, working); + addGameplayComponents(GameplayClockContainer, Beatmap.Value); + addOverlayComponents(GameplayClockContainer, Beatmap.Value); DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true); @@ -250,36 +255,32 @@ namespace osu.Game.Screens.Play && !DrawableRuleset.HasReplayLoaded.Value && !breakOverlay.IsBreakTime.Value; - private WorkingBeatmap loadBeatmap() + private IBeatmap loadPlayableBeatmap() { - WorkingBeatmap working = Beatmap.Value; - if (working is DummyWorkingBeatmap) - return null; + IBeatmap playable; try { - var beatmap = working.Beatmap; - - if (beatmap == null) + if (Beatmap.Value.Beatmap == null) throw new InvalidOperationException("Beatmap was not loaded"); - rulesetInfo = Ruleset.Value ?? beatmap.BeatmapInfo.Ruleset; + rulesetInfo = Ruleset.Value ?? Beatmap.Value.BeatmapInfo.Ruleset; ruleset = rulesetInfo.CreateInstance(); try { - DrawableRuleset = ruleset.CreateDrawableRulesetWith(working, Mods.Value); + playable = Beatmap.Value.GetPlayableBeatmap(ruleset.RulesetInfo, Mods.Value); } catch (BeatmapInvalidForRulesetException) { - // we may fail to create a DrawableRuleset if the beatmap cannot be loaded with the user's preferred ruleset - // let's try again forcing the beatmap's ruleset. - rulesetInfo = beatmap.BeatmapInfo.Ruleset; + // A playable beatmap may not be creatable with the user's preferred ruleset, so try using the beatmap's default ruleset + rulesetInfo = Beatmap.Value.BeatmapInfo.Ruleset; ruleset = rulesetInfo.CreateInstance(); - DrawableRuleset = ruleset.CreateDrawableRulesetWith(Beatmap.Value, Mods.Value); + + playable = Beatmap.Value.GetPlayableBeatmap(rulesetInfo, Mods.Value); } - if (!DrawableRuleset.Objects.Any()) + if (playable.HitObjects.Count == 0) { Logger.Log("Beatmap contains no hit objects!", level: LogLevel.Error); return null; @@ -292,7 +293,7 @@ namespace osu.Game.Screens.Play return null; } - return working; + return playable; } private void performImmediateExit() From 59345c97e4d3ec412d4d1b519f3021eb3988d70c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Dec 2019 15:58:31 +0900 Subject: [PATCH 12/28] Remove now unnecessary editor working beatmap --- osu.Game/Screens/Edit/EditorWorkingBeatmap.cs | 49 ------------------- 1 file changed, 49 deletions(-) delete mode 100644 osu.Game/Screens/Edit/EditorWorkingBeatmap.cs diff --git a/osu.Game/Screens/Edit/EditorWorkingBeatmap.cs b/osu.Game/Screens/Edit/EditorWorkingBeatmap.cs deleted file mode 100644 index 4b8720fe1c..0000000000 --- a/osu.Game/Screens/Edit/EditorWorkingBeatmap.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.Collections.Generic; -using osu.Framework.Audio.Track; -using osu.Framework.Graphics.Textures; -using osu.Framework.Graphics.Video; -using osu.Game.Beatmaps; -using osu.Game.Rulesets; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Objects; -using osu.Game.Skinning; -using osu.Game.Storyboards; - -namespace osu.Game.Screens.Edit -{ - /// - /// Encapsulates a while providing an overridden . - /// - /// - public class EditorWorkingBeatmap : IWorkingBeatmap - where TObject : HitObject - { - private readonly Beatmap playableBeatmap; - private readonly WorkingBeatmap workingBeatmap; - - public EditorWorkingBeatmap(Beatmap playableBeatmap, WorkingBeatmap workingBeatmap) - { - this.playableBeatmap = playableBeatmap; - this.workingBeatmap = workingBeatmap; - } - - public IBeatmap Beatmap => workingBeatmap.Beatmap; - - public Texture Background => workingBeatmap.Background; - - public VideoSprite Video => workingBeatmap.Video; - - public Track Track => workingBeatmap.Track; - - public Waveform Waveform => workingBeatmap.Waveform; - - public Storyboard Storyboard => workingBeatmap.Storyboard; - - public ISkin Skin => workingBeatmap.Skin; - - public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods) => playableBeatmap; - } -} From 1807fc9b6153e7c02881bae15efd00c5545c4d88 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Dec 2019 16:48:33 +0900 Subject: [PATCH 13/28] Fix testcase not converting beatmap --- .../Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs index 071dc381e0..c958932730 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs @@ -172,7 +172,7 @@ namespace osu.Game.Tests.Visual.Gameplay { var ruleset = new TestScrollingRuleset(); - drawableRuleset = (TestDrawableScrollingRuleset)ruleset.CreateDrawableRulesetWith(beatmap); + drawableRuleset = (TestDrawableScrollingRuleset)ruleset.CreateDrawableRulesetWith(CreateWorkingBeatmap(beatmap).GetPlayableBeatmap(ruleset.RulesetInfo)); drawableRuleset.FrameStablePlayback = false; overrideAction?.Invoke(drawableRuleset); From 5e634c118309cf56ccd14ce43d5681293aff529f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Dec 2019 20:51:58 +0900 Subject: [PATCH 14/28] Move test values to constants --- .../Background/TestSceneUserDimContainer.cs | 19 +++++++++++-------- .../Graphics/Containers/UserDimContainer.cs | 4 ++-- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs index 03206402c3..8eb256538a 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs @@ -47,7 +47,10 @@ namespace osu.Game.Tests.Visual.Background lightenDuringBreaks.Value = false; }); - [TestCase(0.6f, 0.3f)] + private const float test_user_dim = 0.6f; + private const float test_user_dim_lightened = test_user_dim - UserDimContainer.BREAK_LIGHTEN_AMOUNT; + + [TestCase(test_user_dim, test_user_dim_lightened)] [TestCase(0.2f, 0.0f)] [TestCase(0.0f, 0.0f)] public void TestBreakLightening(float userDim, float expectedBreakDim) @@ -64,26 +67,26 @@ namespace osu.Game.Tests.Visual.Background [Test] public void TestEnableSettingDuringBreak() { - AddStep("set dim level 0.6", () => container.UserDimLevel.Value = 0.6f); + AddStep("set dim level 0.6", () => container.UserDimLevel.Value = test_user_dim); AddStep("set break", () => isBreakTime.Value = true); - AddUntilStep("not lightened", () => container.DimEqual(0.6f)); + AddUntilStep("not lightened", () => container.DimEqual(test_user_dim)); AddStep("set lighten during break", () => lightenDuringBreaks.Value = true); - AddUntilStep("has lightened", () => container.DimEqual(0.3f)); + AddUntilStep("has lightened", () => container.DimEqual(test_user_dim_lightened)); } [Test] public void TestDisableSettingDuringBreak() { - AddStep("set dim level 0.6", () => container.UserDimLevel.Value = 0.6f); + AddStep("set dim level 0.6", () => container.UserDimLevel.Value = test_user_dim); AddStep("set lighten during break", () => lightenDuringBreaks.Value = true); AddStep("set break", () => isBreakTime.Value = true); - AddUntilStep("has lightened", () => container.DimEqual(0.3f)); + AddUntilStep("has lightened", () => container.DimEqual(test_user_dim_lightened)); AddStep("clear lighten during break", () => lightenDuringBreaks.Value = false); - AddUntilStep("not lightened", () => container.DimEqual(0.6f)); + AddUntilStep("not lightened", () => container.DimEqual(test_user_dim)); AddStep("clear break", () => isBreakTime.Value = false); - AddUntilStep("not lightened", () => container.DimEqual(0.6f)); + AddUntilStep("not lightened", () => container.DimEqual(test_user_dim)); } private class TestUserDimContainer : UserDimContainer diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index dcc8a52e9d..e67cd94d5c 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -19,7 +19,7 @@ namespace osu.Game.Graphics.Containers /// /// Amount of lightening to apply to current dim level during break times. /// - private const float break_lighten_amount = 0.3f; + public const float BREAK_LIGHTEN_AMOUNT = 0.3f; protected const double BACKGROUND_FADE_DURATION = 800; @@ -52,7 +52,7 @@ namespace osu.Game.Graphics.Containers protected Bindable ShowVideo { get; private set; } - private float breakLightening => LightenDuringBreaks.Value && IsBreakTime.Value ? break_lighten_amount : 0; + private float breakLightening => LightenDuringBreaks.Value && IsBreakTime.Value ? BREAK_LIGHTEN_AMOUNT : 0; protected float DimLevel => Math.Max(EnableUserDim.Value ? (float)UserDimLevel.Value - breakLightening : 0, 0); protected override Container Content => dimContent; From ecc7fdc561a8d98e064fd0b47cc6bc7605dff53e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Dec 2019 21:04:56 +0900 Subject: [PATCH 15/28] Ensure a clean run on each test method --- .../Background/TestSceneUserDimContainer.cs | 55 +++++++++---------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs index 8eb256538a..472c43096f 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs @@ -15,13 +15,22 @@ namespace osu.Game.Tests.Visual.Background { public class TestSceneUserDimContainer : OsuTestScene { - private readonly TestUserDimContainer container; - private readonly BindableBool isBreakTime = new BindableBool(); - private readonly Bindable lightenDuringBreaks = new Bindable(); + private TestUserDimContainer userDimContainer; - public TestSceneUserDimContainer() + private readonly BindableBool isBreakTime = new BindableBool(); + + private Bindable lightenDuringBreaks = new Bindable(); + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) { - Add(container = new TestUserDimContainer + lightenDuringBreaks = config.GetBindable(OsuSetting.LightenDuringBreaks); + } + + [SetUp] + public void SetUp() => Schedule(() => + { + Child = userDimContainer = new TestUserDimContainer { RelativeSizeAxes = Axes.Both, Child = new Box @@ -29,21 +38,11 @@ namespace osu.Game.Tests.Visual.Background Colour = Color4.White, RelativeSizeAxes = Axes.Both, }, - }); + }; - container.IsBreakTime.BindTo(isBreakTime); - } - - [BackgroundDependencyLoader] - private void load(OsuConfigManager config) - { - config.BindWith(OsuSetting.LightenDuringBreaks, lightenDuringBreaks); - } - - [SetUp] - public void SetUp() => Schedule(() => - { + userDimContainer.IsBreakTime.BindTo(isBreakTime); isBreakTime.Value = false; + lightenDuringBreaks.Value = false; }); @@ -55,38 +54,38 @@ namespace osu.Game.Tests.Visual.Background [TestCase(0.0f, 0.0f)] public void TestBreakLightening(float userDim, float expectedBreakDim) { - AddStep($"set dim level {userDim}", () => container.UserDimLevel.Value = userDim); + AddStep($"set dim level {userDim}", () => userDimContainer.UserDimLevel.Value = userDim); AddStep("set lighten during break", () => lightenDuringBreaks.Value = true); AddStep("set break", () => isBreakTime.Value = true); - AddUntilStep("has lightened", () => container.DimEqual(expectedBreakDim)); + AddUntilStep("has lightened", () => userDimContainer.DimEqual(expectedBreakDim)); AddStep("clear break", () => isBreakTime.Value = false); - AddUntilStep("not lightened", () => container.DimEqual(userDim)); + AddUntilStep("not lightened", () => userDimContainer.DimEqual(userDim)); } [Test] public void TestEnableSettingDuringBreak() { - AddStep("set dim level 0.6", () => container.UserDimLevel.Value = test_user_dim); + AddStep("set dim level 0.6", () => userDimContainer.UserDimLevel.Value = test_user_dim); AddStep("set break", () => isBreakTime.Value = true); - AddUntilStep("not lightened", () => container.DimEqual(test_user_dim)); + AddUntilStep("not lightened", () => userDimContainer.DimEqual(test_user_dim)); AddStep("set lighten during break", () => lightenDuringBreaks.Value = true); - AddUntilStep("has lightened", () => container.DimEqual(test_user_dim_lightened)); + AddUntilStep("has lightened", () => userDimContainer.DimEqual(test_user_dim_lightened)); } [Test] public void TestDisableSettingDuringBreak() { - AddStep("set dim level 0.6", () => container.UserDimLevel.Value = test_user_dim); + AddStep("set dim level 0.6", () => userDimContainer.UserDimLevel.Value = test_user_dim); AddStep("set lighten during break", () => lightenDuringBreaks.Value = true); AddStep("set break", () => isBreakTime.Value = true); - AddUntilStep("has lightened", () => container.DimEqual(test_user_dim_lightened)); + AddUntilStep("has lightened", () => userDimContainer.DimEqual(test_user_dim_lightened)); AddStep("clear lighten during break", () => lightenDuringBreaks.Value = false); - AddUntilStep("not lightened", () => container.DimEqual(test_user_dim)); + AddUntilStep("not lightened", () => userDimContainer.DimEqual(test_user_dim)); AddStep("clear break", () => isBreakTime.Value = false); - AddUntilStep("not lightened", () => container.DimEqual(test_user_dim)); + AddUntilStep("not lightened", () => userDimContainer.DimEqual(test_user_dim)); } private class TestUserDimContainer : UserDimContainer From 952bc96bbf3223b2415a486c3b8b922e57328ee4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Dec 2019 20:05:38 +0900 Subject: [PATCH 16/28] Use GameBase data sources for Beatmap/Mods/Ruleset Sourced in via OsuScreenDependencies for management --- osu.Game/Tests/Visual/OsuTestScene.cs | 40 ++++++++++----------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index 4ca0ec0f7e..4a561f17a3 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -12,7 +12,6 @@ using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Textures; using osu.Framework.Platform; using osu.Framework.Testing; using osu.Framework.Timing; @@ -21,6 +20,7 @@ using osu.Game.Database; using osu.Game.Online.API; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; +using osu.Game.Screens; using osu.Game.Storyboards; using osu.Game.Tests.Beatmaps; @@ -28,21 +28,13 @@ namespace osu.Game.Tests.Visual { public abstract class OsuTestScene : TestScene { - [Cached(typeof(Bindable))] - [Cached(typeof(IBindable))] - private NonNullableBindable beatmap; + protected Bindable Beatmap { get; private set; } - protected Bindable Beatmap => beatmap; + protected Bindable Ruleset; - [Cached] - [Cached(typeof(IBindable))] - protected readonly Bindable Ruleset = new Bindable(); + protected Bindable> Mods; - [Cached] - [Cached(Type = typeof(IBindable>))] - protected readonly Bindable> Mods = new Bindable>(Array.Empty()); - - protected new DependencyContainer Dependencies { get; private set; } + protected new OsuScreenDependencies Dependencies { get; private set; } private readonly Lazy localStorage; protected Storage LocalStorage => localStorage.Value; @@ -72,18 +64,16 @@ namespace osu.Game.Tests.Visual protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - // This is the earliest we can get OsuGameBase, which is used by the dummy working beatmap to find textures - var working = new DummyWorkingBeatmap(parent.Get(), parent.Get()); + Dependencies = new OsuScreenDependencies(false, base.CreateChildDependencies(parent)); - beatmap = new NonNullableBindable(working) { Default = working }; - beatmap.BindValueChanged(b => ScheduleAfterChildren(() => - { - // compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo) - if (b.OldValue?.TrackLoaded == true && b.OldValue?.Track != b.NewValue?.Track) - b.OldValue.RecycleTrack(); - })); + Beatmap = Dependencies.Beatmap; + Beatmap.SetDefault(); - Dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); + Ruleset = Dependencies.Ruleset; + Ruleset.SetDefault(); + + Mods = Dependencies.Mods; + Mods.SetDefault(); if (!UseOnlineAPI) { @@ -135,8 +125,8 @@ namespace osu.Game.Tests.Visual { base.Dispose(isDisposing); - if (beatmap?.Value.TrackLoaded == true) - beatmap.Value.Track.Stop(); + if (Beatmap?.Value.TrackLoaded == true) + Beatmap.Value.Track.Stop(); if (contextFactory.IsValueCreated) contextFactory.Value.ResetDatabase(); From 395b058ff872a28cf74554088ec04f26eff319d8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Dec 2019 20:05:54 +0900 Subject: [PATCH 17/28] Fix OsuScreenDependencies not caching non-leased versions --- osu.Game/Screens/OsuScreenDependencies.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game/Screens/OsuScreenDependencies.cs b/osu.Game/Screens/OsuScreenDependencies.cs index 115f4b7e1a..8d54829d49 100644 --- a/osu.Game/Screens/OsuScreenDependencies.cs +++ b/osu.Game/Screens/OsuScreenDependencies.cs @@ -26,16 +26,26 @@ namespace osu.Game.Screens Beatmap = parent.Get>()?.GetBoundCopy(); if (Beatmap == null) + { Cache(Beatmap = parent.Get>().BeginLease(false)); + CacheAs(Beatmap); + } Ruleset = parent.Get>()?.GetBoundCopy(); if (Ruleset == null) + { Cache(Ruleset = parent.Get>().BeginLease(true)); + CacheAs(Ruleset); + } Mods = parent.Get>>()?.GetBoundCopy(); + if (Mods == null) + { Cache(Mods = parent.Get>>().BeginLease(true)); + CacheAs(Mods); + } } else { From 3dc2b59d2a066e4827f52aff6c7951cd72cfddd4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Dec 2019 20:06:12 +0900 Subject: [PATCH 18/28] Move variable above common bindables --- osu.Game/Screens/OsuScreen.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 94165fe4b7..6394fb8d23 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -87,12 +87,12 @@ namespace osu.Game.Screens public virtual float BackgroundParallaxAmount => 1; + public virtual bool AllowRateAdjustments => true; + public Bindable Beatmap { get; private set; } public Bindable Ruleset { get; private set; } - public virtual bool AllowRateAdjustments => true; - public Bindable> Mods { get; private set; } protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) From 7033974733537e4d32984f4efeae2c578534fc04 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Dec 2019 20:06:56 +0900 Subject: [PATCH 19/28] Fix test regressions (incorrect from the start) --- .../TestSceneDrawableHitObjectsHidden.cs | 6 ++++-- osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleHidden.cs | 5 +++-- osu.Game.Rulesets.Osu.Tests/TestSceneSliderHidden.cs | 5 +++-- osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerHidden.cs | 5 +++-- .../Visual/UserInterface/TestSceneModSelectOverlay.cs | 2 +- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjectsHidden.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjectsHidden.cs index f6d26addaa..08107e01eb 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjectsHidden.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjectsHidden.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NUnit.Framework; using osu.Game.Rulesets.Catch.Mods; namespace osu.Game.Rulesets.Catch.Tests @@ -12,9 +13,10 @@ namespace osu.Game.Rulesets.Catch.Tests { public override IReadOnlyList RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(CatchModHidden) }).ToList(); - public TestSceneDrawableHitObjectsHidden() + [SetUp] + public void SetUp() => Schedule(() => { Mods.Value = new[] { new CatchModHidden() }; - } + }); } } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleHidden.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleHidden.cs index 55c6b22146..eaba82a469 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleHidden.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleHidden.cs @@ -14,9 +14,10 @@ namespace osu.Game.Rulesets.Osu.Tests { public override IReadOnlyList RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModHidden) }).ToList(); - public TestSceneHitCircleHidden() + [SetUp] + public void SetUp() => Schedule(() => { Mods.Value = new[] { new OsuModHidden() }; - } + }); } } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderHidden.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderHidden.cs index 2a9c1d167b..a1795fb877 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderHidden.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderHidden.cs @@ -14,9 +14,10 @@ namespace osu.Game.Rulesets.Osu.Tests { public override IReadOnlyList RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModHidden) }).ToList(); - public TestSceneSliderHidden() + [SetUp] + public void SetUp() => Schedule(() => { Mods.Value = new[] { new OsuModHidden() }; - } + }); } } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerHidden.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerHidden.cs index a0ab1908d6..2976d4fdce 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerHidden.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerHidden.cs @@ -14,9 +14,10 @@ namespace osu.Game.Rulesets.Osu.Tests { public override IReadOnlyList RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModHidden) }).ToList(); - public TestSceneSpinnerHidden() + [SetUp] + public void SetUp() => Schedule(() => { Mods.Value = new[] { new OsuModHidden() }; - } + }); } } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs index be50200e1c..8cf2d29906 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs @@ -124,7 +124,7 @@ namespace osu.Game.Tests.Visual.UserInterface var easierMods = instance.GetModsFor(ModType.DifficultyReduction); var noFailMod = easierMods.FirstOrDefault(m => m is OsuModNoFail); - AddStep("set mods externally", () => { modDisplay.Current.Value = new[] { noFailMod }; }); + AddStep("set mods externally", () => { Mods.Value = new[] { noFailMod }; }); changeRuleset(rulesetOsu); From a1f8ab1735b755bd98b27697dbf3f99828716f28 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Dec 2019 20:13:53 +0900 Subject: [PATCH 20/28] Fix unrequired type keyword --- osu.Game/OsuGameBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index f310da3883..207fb91aab 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -80,7 +80,7 @@ namespace osu.Game // todo: move this to SongSelect once Screen has the ability to unsuspend. [Cached] - [Cached(Type = typeof(IBindable>))] + [Cached(typeof(IBindable>))] protected readonly Bindable> Mods = new Bindable>(Array.Empty()); protected Bindable Beatmap { get; private set; } // cached via load() method From 0bbaf9b7fbe760d4b57ca66bf82c114e952cf824 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Dec 2019 20:21:35 +0900 Subject: [PATCH 21/28] Fix mod select overlay tests not running individually --- .../TestSceneModSelectOverlay.cs | 101 +++++++++--------- 1 file changed, 52 insertions(+), 49 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs index 8cf2d29906..5f77116c67 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs @@ -8,13 +8,16 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Testing; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Mods; using osu.Game.Overlays.Mods.Sections; using osu.Game.Rulesets; +using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Mania.Mods; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.UI; using osu.Game.Screens.Play.HUD; @@ -48,42 +51,48 @@ namespace osu.Game.Tests.Visual.UserInterface private void load(RulesetStore rulesets) { this.rulesets = rulesets; + } - Add(modSelect = new TestModSelectOverlay + [SetUp] + public void SetUp() => Schedule(() => + { + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - Origin = Anchor.BottomCentre, - Anchor = Anchor.BottomCentre, - }); + modSelect = new TestModSelectOverlay + { + RelativeSizeAxes = Axes.X, + Origin = Anchor.BottomCentre, + Anchor = Anchor.BottomCentre, + }, - Add(modDisplay = new ModDisplay - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Both, - Position = new Vector2(0, 25), - }); + modDisplay = new ModDisplay + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Position = new Vector2(0, 25), + Current = { BindTarget = modSelect.SelectedMods } + } + }; + }); - modDisplay.Current.UnbindBindings(); - modDisplay.Current.BindTo(modSelect.SelectedMods); - - AddStep("Show", modSelect.Show); - AddStep("Toggle", modSelect.ToggleVisibility); - AddStep("Toggle", modSelect.ToggleVisibility); + [SetUpSteps] + public void SetUpSteps() + { + AddStep("show", () => modSelect.Show()); } [Test] public void TestOsuMods() { - var ruleset = rulesets.AvailableRulesets.First(r => r.ID == 0); - changeRuleset(ruleset); + changeRuleset(0); - var instance = ruleset.CreateInstance(); + var osu = new OsuRuleset(); - var easierMods = instance.GetModsFor(ModType.DifficultyReduction); - var harderMods = instance.GetModsFor(ModType.DifficultyIncrease); + var easierMods = osu.GetModsFor(ModType.DifficultyReduction); + var harderMods = osu.GetModsFor(ModType.DifficultyIncrease); - var noFailMod = easierMods.FirstOrDefault(m => m is OsuModNoFail); + var noFailMod = osu.GetModsFor(ModType.DifficultyReduction).FirstOrDefault(m => m is OsuModNoFail); var hiddenMod = harderMods.FirstOrDefault(m => m is OsuModHidden); var doubleTimeMod = harderMods.OfType().FirstOrDefault(m => m.Mods.Any(a => a is OsuModDoubleTime)); @@ -97,8 +106,8 @@ namespace osu.Game.Tests.Visual.UserInterface testMultiMod(doubleTimeMod); testIncompatibleMods(easy, hardRock); testDeselectAll(easierMods.Where(m => !(m is MultiMod))); - testMultiplierTextColour(noFailMod, modSelect.LowMultiplierColour); - testMultiplierTextColour(hiddenMod, modSelect.HighMultiplierColour); + testMultiplierTextColour(noFailMod, () => modSelect.LowMultiplierColour); + testMultiplierTextColour(hiddenMod, () => modSelect.HighMultiplierColour); testUnimplementedMod(spunOutMod); } @@ -106,37 +115,31 @@ namespace osu.Game.Tests.Visual.UserInterface [Test] public void TestManiaMods() { - var ruleset = rulesets.AvailableRulesets.First(r => r.ID == 3); - changeRuleset(ruleset); + changeRuleset(3); - testRankedText(ruleset.CreateInstance().GetModsFor(ModType.Conversion).First(m => m is ManiaModRandom)); + testRankedText(new ManiaRuleset().GetModsFor(ModType.Conversion).First(m => m is ManiaModRandom)); } [Test] public void TestRulesetChanges() { - var rulesetOsu = rulesets.AvailableRulesets.First(r => r.ID == 0); - var rulesetMania = rulesets.AvailableRulesets.First(r => r.ID == 3); + changeRuleset(0); - changeRuleset(null); - - var instance = rulesetOsu.CreateInstance(); - var easierMods = instance.GetModsFor(ModType.DifficultyReduction); - var noFailMod = easierMods.FirstOrDefault(m => m is OsuModNoFail); + var noFailMod = new OsuRuleset().GetModsFor(ModType.DifficultyReduction).FirstOrDefault(m => m is OsuModNoFail); AddStep("set mods externally", () => { Mods.Value = new[] { noFailMod }; }); - changeRuleset(rulesetOsu); + changeRuleset(0); AddAssert("ensure mods still selected", () => modDisplay.Current.Value.Single(m => m is OsuModNoFail) != null); - changeRuleset(rulesetMania); + changeRuleset(3); - AddAssert("ensure mods not selected", () => !modDisplay.Current.Value.Any(m => m is OsuModNoFail)); + AddAssert("ensure mods not selected", () => modDisplay.Current.Value.Count == 0); - changeRuleset(rulesetOsu); + changeRuleset(0); - AddAssert("ensure mods not selected", () => !modDisplay.Current.Value.Any()); + AddAssert("ensure mods not selected", () => modDisplay.Current.Value.Count == 0); } private void testSingleMod(Mod mod) @@ -198,19 +201,19 @@ namespace osu.Game.Tests.Visual.UserInterface selectNext(mod); AddAssert("check for any selection", () => modSelect.SelectedMods.Value.Any()); - AddStep("deselect all", modSelect.DeselectAllButton.Action.Invoke); + AddStep("deselect all", () => modSelect.DeselectAllButton.Action.Invoke()); AddAssert("check for no selection", () => !modSelect.SelectedMods.Value.Any()); } - private void testMultiplierTextColour(Mod mod, Color4 colour) + private void testMultiplierTextColour(Mod mod, Func getCorrectColour) { - checkLabelColor(Color4.White); + checkLabelColor(() => Color4.White); selectNext(mod); AddWaitStep("wait for changing colour", 1); - checkLabelColor(colour); + checkLabelColor(getCorrectColour); selectPrevious(mod); AddWaitStep("wait for changing colour", 1); - checkLabelColor(Color4.White); + checkLabelColor(() => Color4.White); } private void testRankedText(Mod mod) @@ -235,9 +238,9 @@ namespace osu.Game.Tests.Visual.UserInterface }); } - private void changeRuleset(RulesetInfo ruleset) + private void changeRuleset(int? id) { - AddStep($"change ruleset to {ruleset}", () => { Ruleset.Value = ruleset; }); + AddStep($"change ruleset to {(id.ToString() ?? "none")}", () => { Ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault(r => r.ID == id); }); waitForLoad(); } @@ -253,7 +256,7 @@ namespace osu.Game.Tests.Visual.UserInterface }); } - private void checkLabelColor(Color4 color) => AddAssert("check label has expected colour", () => modSelect.MultiplierLabel.Colour.AverageColour == color); + private void checkLabelColor(Func getColour) => AddAssert("check label has expected colour", () => modSelect.MultiplierLabel.Colour.AverageColour == getColour()); private class TestModSelectOverlay : ModSelectOverlay { From 34f67b9cadf7a01e8bae1a31dcc8e0b2435ca40f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Dec 2019 20:31:20 +0900 Subject: [PATCH 22/28] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 252570a150..8b266b08ba 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -54,6 +54,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index a07348b57c..9ec833c9ac 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -23,7 +23,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 544bba3963..1829cbe32a 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -74,7 +74,7 @@ - + @@ -82,7 +82,7 @@ - + From f349e7ff78f9f3a7dec1851241c5478209dc8ca2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Dec 2019 20:35:34 +0900 Subject: [PATCH 23/28] Fix non-null ?? usage --- .../Visual/UserInterface/TestSceneModSelectOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs index 5f77116c67..2738b5b8fc 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs @@ -240,7 +240,7 @@ namespace osu.Game.Tests.Visual.UserInterface private void changeRuleset(int? id) { - AddStep($"change ruleset to {(id.ToString() ?? "none")}", () => { Ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault(r => r.ID == id); }); + AddStep($"change ruleset to {(id?.ToString() ?? "none")}", () => { Ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault(r => r.ID == id); }); waitForLoad(); } From 440a8470e146276a20899dcb8b8513a02b1fa622 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Dec 2019 18:53:25 +0900 Subject: [PATCH 24/28] Move available mods to global context This also tidies up ModSelectOverlay and setting creation flow in general. --- osu.Game/OsuGameBase.cs | 17 ++++++++ osu.Game/Overlays/Mods/ModControlSection.cs | 10 ++--- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 43 ++++++++------------- 3 files changed, 37 insertions(+), 33 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 207fb91aab..78a035c5d6 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -83,6 +83,11 @@ namespace osu.Game [Cached(typeof(IBindable>))] protected readonly Bindable> Mods = new Bindable>(Array.Empty()); + /// + /// Mods available for the current . + /// + public readonly Bindable>> AvailableMods = new Bindable>>(); + protected Bindable Beatmap { get; private set; } // cached via load() method private Bindable fpsDisplayVisible; @@ -233,6 +238,18 @@ namespace osu.Game PreviewTrackManager previewTrackManager; dependencies.Cache(previewTrackManager = new PreviewTrackManager()); Add(previewTrackManager); + + Ruleset.BindValueChanged(onRulesetChanged); + } + + private void onRulesetChanged(ValueChangedEvent r) + { + var dict = new Dictionary>(); + + foreach (ModType type in Enum.GetValues(typeof(ModType))) dict[type] = r.NewValue?.CreateInstance().GetModsFor(type).ToList(); + + SelectedMods.Value = Array.Empty(); + AvailableMods.Value = dict; } protected virtual Container CreateScalingContainer() => new DrawSizePreservingFillContainer(); diff --git a/osu.Game/Overlays/Mods/ModControlSection.cs b/osu.Game/Overlays/Mods/ModControlSection.cs index f4b588ddb3..10b3bc7c2b 100644 --- a/osu.Game/Overlays/Mods/ModControlSection.cs +++ b/osu.Game/Overlays/Mods/ModControlSection.cs @@ -1,10 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Mods; @@ -12,14 +12,13 @@ using osuTK; namespace osu.Game.Overlays.Mods { - public class ModControlSection : Container + public class ModControlSection : CompositeDrawable { protected FillFlowContainer FlowContent; - protected override Container Content => FlowContent; public readonly Mod Mod; - public ModControlSection(Mod mod) + public ModControlSection(Mod mod, IEnumerable modControls) { Mod = mod; @@ -33,9 +32,8 @@ namespace osu.Game.Overlays.Mods Direction = FillDirection.Vertical, AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, + ChildrenEnumerable = modControls }; - - AddRange(Mod.CreateSettingsControls()); } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index e8ea43e3f2..247f4a2947 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -20,7 +20,6 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Mods.Sections; -using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Screens; using osuTK; @@ -50,7 +49,7 @@ namespace osu.Game.Overlays.Mods protected readonly Bindable> SelectedMods = new Bindable>(Array.Empty()); - protected readonly IBindable Ruleset = new Bindable(); + private Bindable>> availableMods; protected Color4 LowMultiplierColour; protected Color4 HighMultiplierColour; @@ -322,14 +321,14 @@ namespace osu.Game.Overlays.Mods } [BackgroundDependencyLoader(true)] - private void load(OsuColour colours, IBindable ruleset, AudioManager audio, Bindable> mods) + private void load(OsuColour colours, AudioManager audio, Bindable> selectedMods, OsuGameBase osu) { LowMultiplierColour = colours.Red; HighMultiplierColour = colours.Green; UnrankedLabel.Colour = colours.Blue; - Ruleset.BindTo(ruleset); - if (mods != null) SelectedMods.BindTo(mods); + availableMods = osu.AvailableMods.GetBoundCopy(); + SelectedMods.BindTo(selectedMods); sampleOn = audio.Samples.Get(@"UI/check-on"); sampleOff = audio.Samples.Get(@"UI/check-off"); @@ -360,7 +359,7 @@ namespace osu.Game.Overlays.Mods { base.LoadComplete(); - Ruleset.BindValueChanged(rulesetChanged, true); + availableMods.BindValueChanged(availableModsChanged, true); SelectedMods.BindValueChanged(selectedModsChanged, true); } @@ -410,22 +409,12 @@ namespace osu.Game.Overlays.Mods return base.OnKeyDown(e); } - private void rulesetChanged(ValueChangedEvent e) + private void availableModsChanged(ValueChangedEvent>> mods) { - if (e.NewValue == null) return; - - var instance = e.NewValue.CreateInstance(); + if (mods.NewValue == null) return; foreach (var section in ModSectionsContainer.Children) - section.Mods = instance.GetModsFor(section.ModType); - - // attempt to re-select any already selected mods. - // this may be the first time we are receiving the ruleset, in which case they will still match. - selectedModsChanged(new ValueChangedEvent>(SelectedMods.Value, SelectedMods.Value)); - - // write the mods back to the SelectedMods bindable in the case a change was not applicable. - // this generally isn't required as the previous line will perform deselection; just here for safety. - refreshSelectedMods(); + section.Mods = mods.NewValue[section.ModType]; } private void selectedModsChanged(ValueChangedEvent> mods) @@ -462,17 +451,17 @@ namespace osu.Game.Overlays.Mods private void updateModSettings(ValueChangedEvent> selectedMods) { - foreach (var added in selectedMods.NewValue.Except(selectedMods.OldValue)) + ModSettingsContent.Clear(); + + foreach (var mod in selectedMods.NewValue) { - var controls = added.CreateSettingsControls().ToList(); - if (controls.Count > 0) - ModSettingsContent.Add(new ModControlSection(added) { Children = controls }); + var settings = mod.CreateSettingsControls().ToList(); + if (settings.Count > 0) + ModSettingsContent.Add(new ModControlSection(mod, settings)); } - foreach (var removed in selectedMods.OldValue.Except(selectedMods.NewValue)) - ModSettingsContent.RemoveAll(section => section.Mod == removed); + bool hasSettings = ModSettingsContent.Count > 0; - bool hasSettings = ModSettingsContent.Children.Count > 0; CustomiseButton.Enabled.Value = hasSettings; if (!hasSettings) @@ -502,7 +491,7 @@ namespace osu.Game.Overlays.Mods { base.Dispose(isDisposing); - Ruleset.UnbindAll(); + availableMods.UnbindAll(); SelectedMods.UnbindAll(); } From 7fdaf338f3af99870215902b66ff759228d53038 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Dec 2019 17:12:01 +0900 Subject: [PATCH 25/28] Fix test logic and add regression test --- .../UserInterface/TestSceneModSettings.cs | 84 ++++++++++++++----- 1 file changed, 62 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs index fc44c5f595..8117a4ad78 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs @@ -2,15 +2,20 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using System.Linq; -using osu.Framework.Allocation; +using NUnit.Framework; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Mods; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.UI; namespace osu.Game.Tests.Visual.UserInterface { @@ -18,28 +23,51 @@ namespace osu.Game.Tests.Visual.UserInterface { private TestModSelectOverlay modSelect; - [BackgroundDependencyLoader] - private void load() + Mod testCustomisableMod = new TestModCustomisable1(); + + [Test] + public void TestButtonShowsOnCustomisableMod() { - Add(modSelect = new TestModSelectOverlay - { - RelativeSizeAxes = Axes.X, - Origin = Anchor.BottomCentre, - Anchor = Anchor.BottomCentre, - }); + createModSelect(); - var testMod = new TestModCustomisable1(); - - AddStep("open", modSelect.Show); + AddStep("open", () => modSelect.Show()); AddAssert("button disabled", () => !modSelect.CustomiseButton.Enabled.Value); AddUntilStep("wait for button load", () => modSelect.ButtonsLoaded); - AddStep("select mod", () => modSelect.SelectMod(testMod)); + AddStep("select mod", () => modSelect.SelectMod(testCustomisableMod)); AddAssert("button enabled", () => modSelect.CustomiseButton.Enabled.Value); AddStep("open Customisation", () => modSelect.CustomiseButton.Click()); - AddStep("deselect mod", () => modSelect.SelectMod(testMod)); + AddStep("deselect mod", () => modSelect.SelectMod(testCustomisableMod)); AddAssert("controls hidden", () => modSelect.ModSettingsContainer.Alpha == 0); } + [Test] + public void TestButtonShowsOnModAlreadyAdded() + { + AddStep("set active mods", () => Mods.Value = new List { testCustomisableMod }); + + createModSelect(); + + AddAssert("mods still active", () => Mods.Value.Count == 1); + + AddStep("open", () => modSelect.Show()); + AddAssert("button enabled", () => modSelect.CustomiseButton.Enabled.Value); + } + + private void createModSelect() + { + AddStep("create mod select", () => + { + Ruleset.Value = new TestRulesetInfo(); + + Child = modSelect = new TestModSelectOverlay + { + RelativeSizeAxes = Axes.X, + Origin = Anchor.BottomCentre, + Anchor = Anchor.BottomCentre, + }; + }); + } + private class TestModSelectOverlay : ModSelectOverlay { public new Container ModSettingsContainer => base.ModSettingsContainer; @@ -50,24 +78,36 @@ namespace osu.Game.Tests.Visual.UserInterface public void SelectMod(Mod mod) => ModSectionsContainer.Children.Single(s => s.ModType == mod.Type) .ButtonsContainer.OfType().Single(b => b.Mods.Any(m => m.GetType() == mod.GetType())).SelectNext(1); + } - protected override void LoadComplete() + public class TestRulesetInfo : RulesetInfo + { + public override Ruleset CreateInstance() => new TestCustomisableModRuleset(); + + public class TestCustomisableModRuleset : Ruleset { - base.LoadComplete(); - - foreach (var section in ModSectionsContainer) + public override IEnumerable GetModsFor(ModType type) { - if (section.ModType == ModType.Conversion) + if (type == ModType.Conversion) { - section.Mods = new Mod[] + return new Mod[] { new TestModCustomisable1(), new TestModCustomisable2() }; } - else - section.Mods = Array.Empty(); + + return Array.Empty(); } + + public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList mods) => throw new NotImplementedException(); + + public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => throw new NotImplementedException(); + + public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => throw new NotImplementedException(); + + public override string Description { get; } + public override string ShortName { get; } } } From 76aa4f9fb2ecd55d0e209a197d73ad13f5370bbe Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Dec 2019 17:36:37 +0900 Subject: [PATCH 26/28] Fix code style issues --- osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs index 8117a4ad78..d17408ff95 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs @@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual.UserInterface { private TestModSelectOverlay modSelect; - Mod testCustomisableMod = new TestModCustomisable1(); + private readonly Mod testCustomisableMod = new TestModCustomisable1(); [Test] public void TestButtonShowsOnCustomisableMod() @@ -106,8 +106,8 @@ namespace osu.Game.Tests.Visual.UserInterface public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => throw new NotImplementedException(); - public override string Description { get; } - public override string ShortName { get; } + public override string Description { get; } = "test"; + public override string ShortName { get; } = "tst"; } } From 8052aeb2383da8302aa677782acb4f2457edd200 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Dec 2019 00:23:32 +0900 Subject: [PATCH 27/28] Fix potential nullref in disposal logic --- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 247f4a2947..7f07ce620c 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -491,8 +491,8 @@ namespace osu.Game.Overlays.Mods { base.Dispose(isDisposing); - availableMods.UnbindAll(); - SelectedMods.UnbindAll(); + availableMods?.UnbindAll(); + SelectedMods?.UnbindAll(); } #endregion From bc311465609b5ee76dff71e4850feaa409863da6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Dec 2019 21:45:38 +0900 Subject: [PATCH 28/28] Mods -> SelectedMods --- .../TestSceneAutoJuiceStream.cs | 2 +- .../TestSceneDrawableHitObjects.cs | 2 +- .../TestSceneDrawableHitObjectsHidden.cs | 2 +- osu.Game.Rulesets.Osu.Tests/TestSceneHitCircle.cs | 2 +- .../TestSceneHitCircleHidden.cs | 2 +- .../TestSceneOsuFlashlight.cs | 2 +- osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs | 2 +- osu.Game.Rulesets.Osu.Tests/TestSceneSliderHidden.cs | 2 +- osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs | 2 +- .../TestSceneSpinnerHidden.cs | 2 +- .../TestSceneTaikoSuddenDeath.cs | 2 +- .../Visual/Background/TestSceneUserDimBackgrounds.cs | 2 +- osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs | 2 +- .../Visual/Gameplay/TestSceneFailAnimation.cs | 2 +- .../Visual/Gameplay/TestSceneFailJudgement.cs | 2 +- .../Visual/Gameplay/TestSceneGameplayRewinding.cs | 2 +- .../Visual/Gameplay/TestScenePlayerLoader.cs | 6 +++--- .../Visual/SongSelect/TestScenePlaySongSelect.cs | 12 ++++++------ .../UserInterface/TestSceneModSelectOverlay.cs | 2 +- .../Visual/UserInterface/TestSceneModSettings.cs | 6 +++--- osu.Game/OsuGameBase.cs | 2 +- osu.Game/Tests/Visual/AllPlayersTestScene.cs | 2 +- osu.Game/Tests/Visual/OsuTestScene.cs | 6 +++--- osu.Game/Tests/Visual/PlayerTestScene.cs | 4 ++-- 24 files changed, 36 insertions(+), 36 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs index ab3c040b4e..74a9c05bf9 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs @@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Catch.Tests protected override Player CreatePlayer(Ruleset ruleset) { - Mods.Value = Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray(); + SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray(); return base.CreatePlayer(ruleset); } } diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs index 02a017ce45..1eb913e900 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs @@ -151,7 +151,7 @@ namespace osu.Game.Rulesets.Catch.Tests private void addToPlayfield(DrawableCatchHitObject drawable) { - foreach (var mod in Mods.Value.OfType()) + foreach (var mod in SelectedMods.Value.OfType()) mod.ApplyToDrawableHitObjects(new[] { drawable }); drawableRuleset.Playfield.Add(drawable); diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjectsHidden.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjectsHidden.cs index 08107e01eb..8c3dfef39c 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjectsHidden.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjectsHidden.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Catch.Tests [SetUp] public void SetUp() => Schedule(() => { - Mods.Value = new[] { new CatchModHidden() }; + SelectedMods.Value = new[] { new CatchModHidden() }; }); } } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircle.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircle.cs index 64f353c4d9..098e277fff 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircle.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircle.cs @@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.Osu.Tests var drawable = CreateDrawableHitCircle(circle, auto); - foreach (var mod in Mods.Value.OfType()) + foreach (var mod in SelectedMods.Value.OfType()) mod.ApplyToDrawableHitObjects(new[] { drawable }); return drawable; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleHidden.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleHidden.cs index eaba82a469..21ebce8c23 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleHidden.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleHidden.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Tests [SetUp] public void SetUp() => Schedule(() => { - Mods.Value = new[] { new OsuModHidden() }; + SelectedMods.Value = new[] { new OsuModHidden() }; }); } } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuFlashlight.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuFlashlight.cs index 64e7632b1b..412effe176 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuFlashlight.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuFlashlight.cs @@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Osu.Tests { protected override Player CreatePlayer(Ruleset ruleset) { - Mods.Value = new Mod[] { new OsuModAutoplay(), new OsuModFlashlight(), }; + SelectedMods.Value = new Mod[] { new OsuModAutoplay(), new OsuModFlashlight(), }; return base.CreatePlayer(ruleset); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs index a9d5c03517..e8386363be 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs @@ -362,7 +362,7 @@ namespace osu.Game.Rulesets.Osu.Tests var drawable = CreateDrawableSlider(slider); - foreach (var mod in Mods.Value.OfType()) + foreach (var mod in SelectedMods.Value.OfType()) mod.ApplyToDrawableHitObjects(new[] { drawable }); drawable.OnNewResult += onNewResult; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderHidden.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderHidden.cs index a1795fb877..d0ee1bddb5 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderHidden.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderHidden.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Tests [SetUp] public void SetUp() => Schedule(() => { - Mods.Value = new[] { new OsuModHidden() }; + SelectedMods.Value = new[] { new OsuModHidden() }; }); } } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs index 3ed3f3e981..f53b64c729 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Osu.Tests Depth = depthIndex++ }; - foreach (var mod in Mods.Value.OfType()) + foreach (var mod in SelectedMods.Value.OfType()) mod.ApplyToDrawableHitObjects(new[] { drawable }); Add(drawable); diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerHidden.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerHidden.cs index 2976d4fdce..dd863deed2 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerHidden.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerHidden.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Tests [SetUp] public void SetUp() => Schedule(() => { - Mods.Value = new[] { new OsuModHidden() }; + SelectedMods.Value = new[] { new OsuModHidden() }; }); } } diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs index d0db193738..140433a523 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Taiko.Tests protected override Player CreatePlayer(Ruleset ruleset) { - Mods.Value = Mods.Value.Concat(new[] { new TaikoModSuddenDeath() }).ToArray(); + SelectedMods.Value = SelectedMods.Value.Concat(new[] { new TaikoModSuddenDeath() }).ToArray(); return new ScoreAccessiblePlayer(); } diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs index 2d2726bbd3..589ec7e8aa 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs @@ -280,7 +280,7 @@ namespace osu.Game.Tests.Visual.Background AddUntilStep("Song select has selection", () => songSelect.Carousel.SelectedBeatmap != null); AddStep("Set default user settings", () => { - Mods.Value = Mods.Value.Concat(new[] { new OsuModNoFail() }).ToArray(); + SelectedMods.Value = SelectedMods.Value.Concat(new[] { new OsuModNoFail() }).ToArray(); songSelect.DimLevel.Value = 0.7f; songSelect.BlurLevel.Value = 0.4f; }); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs index 5ee109e3dd..069b965d9b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs @@ -18,7 +18,7 @@ namespace osu.Game.Tests.Visual.Gameplay protected override Player CreatePlayer(Ruleset ruleset) { - Mods.Value = Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray(); + SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray(); return new ScoreAccessiblePlayer(); } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneFailAnimation.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneFailAnimation.cs index f4e8a68819..992c47f856 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneFailAnimation.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneFailAnimation.cs @@ -14,7 +14,7 @@ namespace osu.Game.Tests.Visual.Gameplay { protected override Player CreatePlayer(Ruleset ruleset) { - Mods.Value = Array.Empty(); + SelectedMods.Value = Array.Empty(); return new FailPlayer(); } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneFailJudgement.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneFailJudgement.cs index cca6301b02..1580aac8c5 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneFailJudgement.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneFailJudgement.cs @@ -14,7 +14,7 @@ namespace osu.Game.Tests.Visual.Gameplay { protected override Player CreatePlayer(Ruleset ruleset) { - Mods.Value = Array.Empty(); + SelectedMods.Value = Array.Empty(); return new FailPlayer(); } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs index b2b58a63fb..5336c720a1 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs @@ -67,7 +67,7 @@ namespace osu.Game.Tests.Visual.Gameplay protected override Player CreatePlayer(Ruleset ruleset) { - Mods.Value = Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray(); + SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray(); return new RulesetExposingPlayer(); } diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index f02361e685..f68f4b8b83 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -57,7 +57,7 @@ namespace osu.Game.Tests.Visual.Gameplay beforeLoadAction?.Invoke(); Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); - foreach (var mod in Mods.Value.OfType()) + foreach (var mod in SelectedMods.Value.OfType()) mod.ApplyToTrack(Beatmap.Value.Track); InputManager.Child = container = new TestPlayerLoaderContainer( @@ -76,7 +76,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestEarlyExit() { - AddStep("load dummy beatmap", () => ResetPlayer(false, () => Mods.Value = new[] { new OsuModNightcore() })); + AddStep("load dummy beatmap", () => ResetPlayer(false, () => SelectedMods.Value = new[] { new OsuModNightcore() })); AddUntilStep("wait for current", () => loader.IsCurrentScreen()); AddAssert("mod rate applied", () => Beatmap.Value.Track.Rate != 1); AddStep("exit loader", () => loader.Exit()); @@ -123,7 +123,7 @@ namespace osu.Game.Tests.Visual.Gameplay TestMod playerMod1 = null; TestMod playerMod2 = null; - AddStep("load player", () => { ResetPlayer(true, () => Mods.Value = new[] { gameMod = new TestMod() }); }); + AddStep("load player", () => { ResetPlayer(true, () => SelectedMods.Value = new[] { gameMod = new TestMod() }); }); AddUntilStep("wait for loader to become current", () => loader.IsCurrentScreen()); AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre)); diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 5dd02c1ddd..00fa95bedc 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -256,17 +256,17 @@ namespace osu.Game.Tests.Visual.SongSelect AddStep("change ruleset", () => { - Mods.ValueChanged += onModChange; + SelectedMods.ValueChanged += onModChange; songSelect.Ruleset.ValueChanged += onRulesetChange; Ruleset.Value = new TaikoRuleset().RulesetInfo; - Mods.ValueChanged -= onModChange; + SelectedMods.ValueChanged -= onModChange; songSelect.Ruleset.ValueChanged -= onRulesetChange; }); AddAssert("mods changed before ruleset", () => modChangeIndex < rulesetChangeIndex); - AddAssert("empty mods", () => !Mods.Value.Any()); + AddAssert("empty mods", () => !SelectedMods.Value.Any()); void onModChange(ValueChangedEvent> e) => modChangeIndex = actionIndex++; void onRulesetChange(ValueChangedEvent e) => rulesetChangeIndex = actionIndex++; @@ -275,7 +275,7 @@ namespace osu.Game.Tests.Visual.SongSelect [Test] public void TestModsRetainedBetweenSongSelect() { - AddAssert("empty mods", () => !Mods.Value.Any()); + AddAssert("empty mods", () => !SelectedMods.Value.Any()); createSongSelect(); @@ -285,7 +285,7 @@ namespace osu.Game.Tests.Visual.SongSelect createSongSelect(); - AddAssert("mods retained", () => Mods.Value.Any()); + AddAssert("mods retained", () => SelectedMods.Value.Any()); } [Test] @@ -332,7 +332,7 @@ namespace osu.Game.Tests.Visual.SongSelect private void checkMusicPlaying(bool playing) => AddUntilStep($"music {(playing ? "" : "not ")}playing", () => music.IsPlaying == playing); - private void changeMods(params Mod[] mods) => AddStep($"change mods to {string.Join(", ", mods.Select(m => m.Acronym))}", () => Mods.Value = mods); + private void changeMods(params Mod[] mods) => AddStep($"change mods to {string.Join(", ", mods.Select(m => m.Acronym))}", () => SelectedMods.Value = mods); private void changeRuleset(int id) => AddStep($"change ruleset to {id}", () => Ruleset.Value = rulesets.AvailableRulesets.First(r => r.ID == id)); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs index 2738b5b8fc..12ee4ceb2e 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs @@ -127,7 +127,7 @@ namespace osu.Game.Tests.Visual.UserInterface var noFailMod = new OsuRuleset().GetModsFor(ModType.DifficultyReduction).FirstOrDefault(m => m is OsuModNoFail); - AddStep("set mods externally", () => { Mods.Value = new[] { noFailMod }; }); + AddStep("set mods externally", () => { SelectedMods.Value = new[] { noFailMod }; }); changeRuleset(0); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs index d17408ff95..edc749cbaa 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs @@ -43,11 +43,11 @@ namespace osu.Game.Tests.Visual.UserInterface [Test] public void TestButtonShowsOnModAlreadyAdded() { - AddStep("set active mods", () => Mods.Value = new List { testCustomisableMod }); + AddStep("set active mods", () => SelectedMods.Value = new List { testCustomisableMod }); createModSelect(); - AddAssert("mods still active", () => Mods.Value.Count == 1); + AddAssert("mods still active", () => SelectedMods.Value.Count == 1); AddStep("open", () => modSelect.Show()); AddAssert("button enabled", () => modSelect.CustomiseButton.Enabled.Value); @@ -100,7 +100,7 @@ namespace osu.Game.Tests.Visual.UserInterface return Array.Empty(); } - public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList mods) => throw new NotImplementedException(); + public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList mods = null) => throw new NotImplementedException(); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => throw new NotImplementedException(); diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 78a035c5d6..834a64e597 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -81,7 +81,7 @@ namespace osu.Game // todo: move this to SongSelect once Screen has the ability to unsuspend. [Cached] [Cached(typeof(IBindable>))] - protected readonly Bindable> Mods = new Bindable>(Array.Empty()); + protected readonly Bindable> SelectedMods = new Bindable>(Array.Empty()); /// /// Mods available for the current . diff --git a/osu.Game/Tests/Visual/AllPlayersTestScene.cs b/osu.Game/Tests/Visual/AllPlayersTestScene.cs index b7d1979b0d..dd65c8c382 100644 --- a/osu.Game/Tests/Visual/AllPlayersTestScene.cs +++ b/osu.Game/Tests/Visual/AllPlayersTestScene.cs @@ -55,7 +55,7 @@ namespace osu.Game.Tests.Visual var working = CreateWorkingBeatmap(rulesetInfo); Beatmap.Value = working; - Mods.Value = new[] { ruleset.GetAllMods().First(m => m is ModNoFail) }; + SelectedMods.Value = new[] { ruleset.GetAllMods().First(m => m is ModNoFail) }; Player?.Exit(); Player = null; diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index 4a561f17a3..18dbd212cc 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -32,7 +32,7 @@ namespace osu.Game.Tests.Visual protected Bindable Ruleset; - protected Bindable> Mods; + protected Bindable> SelectedMods; protected new OsuScreenDependencies Dependencies { get; private set; } @@ -72,8 +72,8 @@ namespace osu.Game.Tests.Visual Ruleset = Dependencies.Ruleset; Ruleset.SetDefault(); - Mods = Dependencies.Mods; - Mods.SetDefault(); + SelectedMods = Dependencies.Mods; + SelectedMods.SetDefault(); if (!UseOnlineAPI) { diff --git a/osu.Game/Tests/Visual/PlayerTestScene.cs b/osu.Game/Tests/Visual/PlayerTestScene.cs index 2c5a51ca02..3ed65bee61 100644 --- a/osu.Game/Tests/Visual/PlayerTestScene.cs +++ b/osu.Game/Tests/Visual/PlayerTestScene.cs @@ -53,14 +53,14 @@ namespace osu.Game.Tests.Visual { var noFailMod = ruleset.GetAllMods().FirstOrDefault(m => m is ModNoFail); if (noFailMod != null) - Mods.Value = new[] { noFailMod }; + SelectedMods.Value = new[] { noFailMod }; } if (Autoplay) { var mod = ruleset.GetAutoplayMod(); if (mod != null) - Mods.Value = Mods.Value.Concat(mod.Yield()).ToArray(); + SelectedMods.Value = SelectedMods.Value.Concat(mod.Yield()).ToArray(); } Player = CreatePlayer(ruleset);