From bca58ddb42f73cc79116b1450c4db446bd015577 Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 29 Feb 2020 21:07:42 +0530 Subject: [PATCH 01/53] Make KeyCounter stop counting during breaks --- .../Visual/Gameplay/TestSceneAutoplay.cs | 16 ++++++++++++---- osu.Game/Screens/Play/Player.cs | 10 ++++++++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs index 4daab8d137..ebd89039a5 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs @@ -24,10 +24,17 @@ namespace osu.Game.Tests.Visual.Gameplay protected override void AddCheckSteps() { - AddUntilStep("score above zero", () => ((ScoreAccessiblePlayer)Player).ScoreProcessor.TotalScore.Value > 0); - AddUntilStep("key counter counted keys", () => ((ScoreAccessiblePlayer)Player).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 2)); - AddStep("rewind", () => track.Seek(-10000)); - AddUntilStep("key counter reset", () => ((ScoreAccessiblePlayer)Player).HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0)); + ScoreAccessiblePlayer scoreAccessiblePlayer = null; + + AddUntilStep("player loaded", () => (scoreAccessiblePlayer = (ScoreAccessiblePlayer)Player) != null); + AddUntilStep("score above zero", () => scoreAccessiblePlayer.ScoreProcessor.TotalScore.Value > 0); + AddUntilStep("key counter counted keys", () => scoreAccessiblePlayer.HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 2)); + AddStep("seek to break time", () => scoreAccessiblePlayer.GameplayClockContainer.Seek(scoreAccessiblePlayer.BreakOverlay.Breaks.First().StartTime)); + AddUntilStep("wait for seek to complete", () => + scoreAccessiblePlayer.HUDOverlay.Progress.ReferenceClock.CurrentTime >= scoreAccessiblePlayer.BreakOverlay.Breaks.First().StartTime); + AddAssert("test keys not counting", () => !scoreAccessiblePlayer.HUDOverlay.KeyCounter.IsCounting); + AddStep("rewind", () => scoreAccessiblePlayer.GameplayClockContainer.Seek(-80000)); + AddUntilStep("key counter reset", () => scoreAccessiblePlayer.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0)); } protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) @@ -43,6 +50,7 @@ namespace osu.Game.Tests.Visual.Gameplay { public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; public new HUDOverlay HUDOverlay => base.HUDOverlay; + public new BreakOverlay BreakOverlay => base.BreakOverlay; public new GameplayClockContainer GameplayClockContainer => base.GameplayClockContainer; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 11ca36e25f..237e364e69 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -184,7 +184,7 @@ namespace osu.Game.Screens.Play foreach (var mod in Mods.Value.OfType()) mod.ApplyToHealthProcessor(HealthProcessor); - BreakOverlay.IsBreakTime.ValueChanged += _ => updatePauseOnFocusLostState(); + BreakOverlay.IsBreakTime.BindValueChanged(_ => onBreakTimeChanged(), true); } private void addUnderlayComponents(Container target) @@ -229,7 +229,7 @@ namespace osu.Game.Screens.Play IsPaused = { BindTarget = GameplayClockContainer.IsPaused } }, PlayerSettingsOverlay = { PlaybackSettings = { UserPlaybackRate = { BindTarget = GameplayClockContainer.UserPlaybackRate } } }, - KeyCounter = { AlwaysVisible = { BindTarget = DrawableRuleset.HasReplayLoaded } }, + KeyCounter = { AlwaysVisible = { BindTarget = DrawableRuleset.HasReplayLoaded }, IsCounting = false }, RequestSeek = GameplayClockContainer.Seek, Anchor = Anchor.Centre, Origin = Anchor.Centre @@ -286,6 +286,12 @@ namespace osu.Game.Screens.Play HealthProcessor.IsBreakTime.BindTo(BreakOverlay.IsBreakTime); } + private void onBreakTimeChanged() + { + updatePauseOnFocusLostState(); + HUDOverlay.KeyCounter.IsCounting = !BreakOverlay.IsBreakTime.Value; + } + private void updatePauseOnFocusLostState() => HUDOverlay.HoldToQuit.PauseOnFocusLost = PauseOnFocusLost && !DrawableRuleset.HasReplayLoaded.Value From 1ce972dd5b4a06d7ca6774a7daaf79cf3902dc69 Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 29 Feb 2020 21:53:49 +0530 Subject: [PATCH 02/53] Remove unused variable --- osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs index ebd89039a5..8e16d74dca 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs @@ -14,8 +14,6 @@ namespace osu.Game.Tests.Visual.Gameplay [Description("Player instantiated with an autoplay mod.")] public class TestSceneAutoplay : TestSceneAllRulesetPlayers { - private ClockBackedTestWorkingBeatmap.TrackVirtualManual track; - protected override Player CreatePlayer(Ruleset ruleset) { SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray(); @@ -41,8 +39,6 @@ namespace osu.Game.Tests.Visual.Gameplay { var working = base.CreateWorkingBeatmap(beatmap, storyboard); - track = (ClockBackedTestWorkingBeatmap.TrackVirtualManual)working.Track; - return working; } From 089ec4c7922a18fe4f4da718bbc4ede63ddf6289 Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Sat, 29 Feb 2020 21:16:28 -0800 Subject: [PATCH 03/53] Test scene for mod development --- .../TestSceneCatchModSandbox.cs | 28 +++++ .../TestSceneManiaModSandbox.cs | 28 +++++ .../Mods/TestSceneOsuModDifficultyAdjust.cs | 20 ++++ .../TestSceneOsuModSandbox.cs | 28 +++++ .../TestSceneTaikoModSandbox.cs | 28 +++++ osu.Game/Tests/Visual/PlayerTestScene.cs | 4 +- osu.Game/Tests/Visual/TestSceneModSandbox.cs | 108 ++++++++++++++++++ 7 files changed, 242 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Rulesets.Catch.Tests/TestSceneCatchModSandbox.cs create mode 100644 osu.Game.Rulesets.Mania.Tests/TestSceneManiaModSandbox.cs create mode 100644 osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs create mode 100644 osu.Game.Rulesets.Osu.Tests/TestSceneOsuModSandbox.cs create mode 100644 osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModSandbox.cs create mode 100644 osu.Game/Tests/Visual/TestSceneModSandbox.cs diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModSandbox.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModSandbox.cs new file mode 100644 index 0000000000..3abf8163bd --- /dev/null +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModSandbox.cs @@ -0,0 +1,28 @@ +// 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 System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Game.Rulesets.Mods; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Catch.Tests +{ + [TestFixture] + public class TestSceneCatchModSandbox : TestSceneModSandbox + { + public override IReadOnlyList RequiredTypes => base.RequiredTypes.Append(typeof(TestSceneCatchModSandbox)).ToList(); + + public TestSceneCatchModSandbox() + : this(null) + { + } + + public TestSceneCatchModSandbox(Mod mod = null) + : base(new CatchRuleset(), mod) + { + } + } +} diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneManiaModSandbox.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneManiaModSandbox.cs new file mode 100644 index 0000000000..2693cebb43 --- /dev/null +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneManiaModSandbox.cs @@ -0,0 +1,28 @@ +// 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 System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Game.Rulesets.Mods; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Mania.Tests +{ + [TestFixture] + public class TestSceneManiaModSandbox : TestSceneModSandbox + { + public override IReadOnlyList RequiredTypes => base.RequiredTypes.Append(typeof(TestSceneManiaModSandbox)).ToList(); + + public TestSceneManiaModSandbox() + : this(null) + { + } + + public TestSceneManiaModSandbox(Mod mod = null) + : base(new ManiaRuleset(), mod) + { + } + } +} diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs new file mode 100644 index 0000000000..7f09731a11 --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs @@ -0,0 +1,20 @@ +// 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 System.Collections.Generic; +using System.Linq; +using osu.Game.Rulesets.Osu.Mods; + +namespace osu.Game.Rulesets.Osu.Tests.Mods +{ + public class TestSceneOsuModDifficultyAdjust : TestSceneOsuModSandbox + { + public override IReadOnlyList RequiredTypes => base.RequiredTypes.Append(typeof(OsuModDifficultyAdjust)).ToList(); + + public TestSceneOsuModDifficultyAdjust() + : base(new OsuModDifficultyAdjust()) + { + } + } +} diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuModSandbox.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuModSandbox.cs new file mode 100644 index 0000000000..d2a9d1ea6e --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuModSandbox.cs @@ -0,0 +1,28 @@ +// 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 System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Game.Rulesets.Mods; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Osu.Tests +{ + [TestFixture] + public class TestSceneOsuModSandbox : TestSceneModSandbox + { + public override IReadOnlyList RequiredTypes => base.RequiredTypes.Append(typeof(TestSceneOsuModSandbox)).ToList(); + + public TestSceneOsuModSandbox() + : this(null) + { + } + + public TestSceneOsuModSandbox(Mod mod = null) + : base(new OsuRuleset(), mod) + { + } + } +} diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModSandbox.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModSandbox.cs new file mode 100644 index 0000000000..f5481713f5 --- /dev/null +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModSandbox.cs @@ -0,0 +1,28 @@ +// 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 System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Game.Rulesets.Mods; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Taiko.Tests +{ + [TestFixture] + public class TestSceneTaikoModSandbox : TestSceneModSandbox + { + public override IReadOnlyList RequiredTypes => base.RequiredTypes.Append(typeof(TestSceneTaikoModSandbox)).ToList(); + + public TestSceneTaikoModSandbox() + : this(null) + { + } + + public TestSceneTaikoModSandbox(Mod mod = null) + : base(new TaikoRuleset(), mod) + { + } + } +} diff --git a/osu.Game/Tests/Visual/PlayerTestScene.cs b/osu.Game/Tests/Visual/PlayerTestScene.cs index 7c5ba7d30f..1ca5256353 100644 --- a/osu.Game/Tests/Visual/PlayerTestScene.cs +++ b/osu.Game/Tests/Visual/PlayerTestScene.cs @@ -37,7 +37,7 @@ namespace osu.Game.Tests.Visual { base.SetUpSteps(); - AddStep(ruleset.RulesetInfo.Name, loadPlayer); + AddStep(ruleset.RulesetInfo.Name, LoadPlayer); AddUntilStep("player loaded", () => Player.IsLoaded && Player.Alpha == 1); } @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual protected virtual bool Autoplay => false; - private void loadPlayer() + protected void LoadPlayer() { var beatmap = CreateBeatmap(ruleset.RulesetInfo); diff --git a/osu.Game/Tests/Visual/TestSceneModSandbox.cs b/osu.Game/Tests/Visual/TestSceneModSandbox.cs new file mode 100644 index 0000000000..5c32ebadce --- /dev/null +++ b/osu.Game/Tests/Visual/TestSceneModSandbox.cs @@ -0,0 +1,108 @@ +// 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 System.Collections.Generic; +using System.Linq; +using System.Reflection; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; +using osu.Game.Configuration; +using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Mods; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; +using osu.Game.Screens.Play; + +namespace osu.Game.Tests.Visual +{ + public abstract class TestSceneModSandbox : PlayerTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(TestSceneModSandbox) + }; + + protected Mod Mod; + private readonly TriangleButton button; + + protected TestSceneModSandbox(Ruleset ruleset, Mod mod = null) + : base(ruleset) + { + Mod = mod ?? new SandboxMod(); + + var props = Mod.GetType().GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance); + var hasSettings = props.Any(prop => prop.GetCustomAttribute(true) != null); + + Child = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Padding = new MarginPadding(50), + Margin = new MarginPadding { Bottom = 20 }, + Width = 0.4f, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Children = new Drawable[] + { + new ModControlSection(Mod, Mod.CreateSettingsControls()), + button = new TriangleButton + { + RelativeSizeAxes = Axes.X, + Width = 0.5f, + Text = "Start", + Action = () => + { + button.Text = hasSettings ? "Apply Settings" : "Restart"; + LoadPlayer(); + } + } + } + }; + } + + [SetUpSteps] + public override void SetUpSteps() + { + } + + [BackgroundDependencyLoader] + private void load() + { + LocalConfig.GetBindable(OsuSetting.KeyOverlay).Value = true; + } + + protected override Player CreatePlayer(Ruleset ruleset) + { + SelectedMods.Value = SelectedMods.Value.Append(Mod).ToArray(); + + return base.CreatePlayer(ruleset); + } + + protected class SandboxMod : Mod + { + public override string Name => "Sandbox Test"; + public override string Acronym => "ST"; + public override double ScoreMultiplier => 1.0; + + [SettingSource("Test Setting")] + public Bindable TestSetting1 { get; } = new BindableBool + { + Default = true, + Value = true + }; + + [SettingSource("Test Setting 2")] + public Bindable TestSetting2 { get; } = new BindableFloat + { + Precision = 0.1f, + MinValue = 0, + MaxValue = 20 + }; + } + } +} From a02c5710ac07a2486be020a7b0e2d1d4feb035b1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Mar 2020 10:06:49 +0900 Subject: [PATCH 04/53] Rename base class --- osu.Game.Rulesets.Catch.Tests/TestSceneCatchModSandbox.cs | 2 +- osu.Game.Rulesets.Mania.Tests/TestSceneManiaModSandbox.cs | 2 +- osu.Game.Rulesets.Osu.Tests/TestSceneOsuModSandbox.cs | 2 +- osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModSandbox.cs | 2 +- .../{TestSceneModSandbox.cs => ModSandboxTestScene.cs} | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) rename osu.Game/Tests/Visual/{TestSceneModSandbox.cs => ModSandboxTestScene.cs} (95%) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModSandbox.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModSandbox.cs index 3abf8163bd..3e94121fd7 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModSandbox.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModSandbox.cs @@ -11,7 +11,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Catch.Tests { [TestFixture] - public class TestSceneCatchModSandbox : TestSceneModSandbox + public class TestSceneCatchModSandbox : ModSandboxTestScene { public override IReadOnlyList RequiredTypes => base.RequiredTypes.Append(typeof(TestSceneCatchModSandbox)).ToList(); diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneManiaModSandbox.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneManiaModSandbox.cs index 2693cebb43..897e7df1e9 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneManiaModSandbox.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneManiaModSandbox.cs @@ -11,7 +11,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Mania.Tests { [TestFixture] - public class TestSceneManiaModSandbox : TestSceneModSandbox + public class TestSceneManiaModSandbox : ModSandboxTestScene { public override IReadOnlyList RequiredTypes => base.RequiredTypes.Append(typeof(TestSceneManiaModSandbox)).ToList(); diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuModSandbox.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuModSandbox.cs index d2a9d1ea6e..9f816ef2ed 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuModSandbox.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuModSandbox.cs @@ -11,7 +11,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests { [TestFixture] - public class TestSceneOsuModSandbox : TestSceneModSandbox + public class TestSceneOsuModSandbox : ModSandboxTestScene { public override IReadOnlyList RequiredTypes => base.RequiredTypes.Append(typeof(TestSceneOsuModSandbox)).ToList(); diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModSandbox.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModSandbox.cs index f5481713f5..ef62c7ed56 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModSandbox.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModSandbox.cs @@ -11,7 +11,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests { [TestFixture] - public class TestSceneTaikoModSandbox : TestSceneModSandbox + public class TestSceneTaikoModSandbox : ModSandboxTestScene { public override IReadOnlyList RequiredTypes => base.RequiredTypes.Append(typeof(TestSceneTaikoModSandbox)).ToList(); diff --git a/osu.Game/Tests/Visual/TestSceneModSandbox.cs b/osu.Game/Tests/Visual/ModSandboxTestScene.cs similarity index 95% rename from osu.Game/Tests/Visual/TestSceneModSandbox.cs rename to osu.Game/Tests/Visual/ModSandboxTestScene.cs index 5c32ebadce..bb872123c5 100644 --- a/osu.Game/Tests/Visual/TestSceneModSandbox.cs +++ b/osu.Game/Tests/Visual/ModSandboxTestScene.cs @@ -19,17 +19,17 @@ using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual { - public abstract class TestSceneModSandbox : PlayerTestScene + public abstract class ModSandboxTestScene : PlayerTestScene { public override IReadOnlyList RequiredTypes => new[] { - typeof(TestSceneModSandbox) + typeof(ModSandboxTestScene) }; protected Mod Mod; private readonly TriangleButton button; - protected TestSceneModSandbox(Ruleset ruleset, Mod mod = null) + protected ModSandboxTestScene(Ruleset ruleset, Mod mod = null) : base(ruleset) { Mod = mod ?? new SandboxMod(); From 5c15704c819ab25868c48f511a26b417a2bb96d0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Mar 2020 10:28:39 +0900 Subject: [PATCH 05/53] Improve abstract structure for testability --- osu.Game/Tests/Visual/ModSandboxTestScene.cs | 96 ++++++-------------- osu.Game/Tests/Visual/TestReplayPlayer.cs | 24 +++++ 2 files changed, 50 insertions(+), 70 deletions(-) create mode 100644 osu.Game/Tests/Visual/TestReplayPlayer.cs diff --git a/osu.Game/Tests/Visual/ModSandboxTestScene.cs b/osu.Game/Tests/Visual/ModSandboxTestScene.cs index bb872123c5..84bab6a9b9 100644 --- a/osu.Game/Tests/Visual/ModSandboxTestScene.cs +++ b/osu.Game/Tests/Visual/ModSandboxTestScene.cs @@ -4,15 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Reflection; -using osu.Framework.Allocation; -using osu.Framework.Bindables; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Testing; -using osu.Game.Configuration; -using osu.Game.Graphics.UserInterface; -using osu.Game.Overlays.Mods; +using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Play; @@ -26,83 +18,47 @@ namespace osu.Game.Tests.Visual typeof(ModSandboxTestScene) }; - protected Mod Mod; - private readonly TriangleButton button; - - protected ModSandboxTestScene(Ruleset ruleset, Mod mod = null) + protected ModSandboxTestScene(Ruleset ruleset) : base(ruleset) { - Mod = mod ?? new SandboxMod(); - - var props = Mod.GetType().GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance); - var hasSettings = props.Any(prop => prop.GetCustomAttribute(true) != null); - - Child = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Padding = new MarginPadding(50), - Margin = new MarginPadding { Bottom = 20 }, - Width = 0.4f, - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Children = new Drawable[] - { - new ModControlSection(Mod, Mod.CreateSettingsControls()), - button = new TriangleButton - { - RelativeSizeAxes = Axes.X, - Width = 0.5f, - Text = "Start", - Action = () => - { - button.Text = hasSettings ? "Apply Settings" : "Restart"; - LoadPlayer(); - } - } - } - }; } - [SetUpSteps] + private ModTestCaseData currentTest; + public override void SetUpSteps() { + foreach (var testCase in CreateTestCases()) + { + AddStep("set test case", () => currentTest = testCase); + base.SetUpSteps(); + } } - [BackgroundDependencyLoader] - private void load() - { - LocalConfig.GetBindable(OsuSetting.KeyOverlay).Value = true; - } + protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => currentTest.Beatmap; protected override Player CreatePlayer(Ruleset ruleset) { - SelectedMods.Value = SelectedMods.Value.Append(Mod).ToArray(); + SelectedMods.Value = SelectedMods.Value.Append(currentTest.Mod).ToArray(); + + if (currentTest.Autoplay) + { + // We're simulating an auto-play via a replay so that the auto-play mod does not interfere + var beatmap = Beatmap.Value.GetPlayableBeatmap(ruleset.RulesetInfo, SelectedMods.Value); + var score = ruleset.GetAutoplayMod().CreateReplayScore(beatmap); + + return new TestReplayPlayer(score, false, false); + } return base.CreatePlayer(ruleset); } - protected class SandboxMod : Mod + protected abstract ModTestCaseData[] CreateTestCases(); + + protected class ModTestCaseData { - public override string Name => "Sandbox Test"; - public override string Acronym => "ST"; - public override double ScoreMultiplier => 1.0; - - [SettingSource("Test Setting")] - public Bindable TestSetting1 { get; } = new BindableBool - { - Default = true, - Value = true - }; - - [SettingSource("Test Setting 2")] - public Bindable TestSetting2 { get; } = new BindableFloat - { - Precision = 0.1f, - MinValue = 0, - MaxValue = 20 - }; + public Mod Mod; + public bool Autoplay; + public IBeatmap Beatmap; } } } diff --git a/osu.Game/Tests/Visual/TestReplayPlayer.cs b/osu.Game/Tests/Visual/TestReplayPlayer.cs new file mode 100644 index 0000000000..e99fcc1e37 --- /dev/null +++ b/osu.Game/Tests/Visual/TestReplayPlayer.cs @@ -0,0 +1,24 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Rulesets.UI; +using osu.Game.Scoring; +using osu.Game.Screens.Play; + +namespace osu.Game.Tests.Visual +{ + public class TestReplayPlayer : ReplayPlayer + { + protected override bool PauseOnFocusLost { get; } + + public new DrawableRuleset DrawableRuleset => base.DrawableRuleset; + + public new GameplayClockContainer GameplayClockContainer => base.GameplayClockContainer; + + public TestReplayPlayer(Score score, bool allowPause = true, bool showResults = true, bool pauseOnFocusLost = false) + : base(score, allowPause, showResults) + { + PauseOnFocusLost = pauseOnFocusLost; + } + } +} From 239cfddcbb92503b662d89750953950b6a11a12d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Mar 2020 10:50:41 +0900 Subject: [PATCH 06/53] Improve test scenes/cases --- .../TestSceneCatchModSandbox.cs | 28 ------- .../TestSceneManiaModSandbox.cs | 28 ------- .../Mods/TestSceneOsuModDifficultyAdjust.cs | 38 +++++++++- .../TestSceneOsuModSandbox.cs | 28 ------- .../TestSceneTaikoModSandbox.cs | 28 ------- osu.Game/Tests/Visual/ModSandboxTestScene.cs | 73 +++++++++++++++---- 6 files changed, 95 insertions(+), 128 deletions(-) delete mode 100644 osu.Game.Rulesets.Catch.Tests/TestSceneCatchModSandbox.cs delete mode 100644 osu.Game.Rulesets.Mania.Tests/TestSceneManiaModSandbox.cs delete mode 100644 osu.Game.Rulesets.Osu.Tests/TestSceneOsuModSandbox.cs delete mode 100644 osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModSandbox.cs diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModSandbox.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModSandbox.cs deleted file mode 100644 index 3e94121fd7..0000000000 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModSandbox.cs +++ /dev/null @@ -1,28 +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; -using System.Collections.Generic; -using System.Linq; -using NUnit.Framework; -using osu.Game.Rulesets.Mods; -using osu.Game.Tests.Visual; - -namespace osu.Game.Rulesets.Catch.Tests -{ - [TestFixture] - public class TestSceneCatchModSandbox : ModSandboxTestScene - { - public override IReadOnlyList RequiredTypes => base.RequiredTypes.Append(typeof(TestSceneCatchModSandbox)).ToList(); - - public TestSceneCatchModSandbox() - : this(null) - { - } - - public TestSceneCatchModSandbox(Mod mod = null) - : base(new CatchRuleset(), mod) - { - } - } -} diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneManiaModSandbox.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneManiaModSandbox.cs deleted file mode 100644 index 897e7df1e9..0000000000 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneManiaModSandbox.cs +++ /dev/null @@ -1,28 +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; -using System.Collections.Generic; -using System.Linq; -using NUnit.Framework; -using osu.Game.Rulesets.Mods; -using osu.Game.Tests.Visual; - -namespace osu.Game.Rulesets.Mania.Tests -{ - [TestFixture] - public class TestSceneManiaModSandbox : ModSandboxTestScene - { - public override IReadOnlyList RequiredTypes => base.RequiredTypes.Append(typeof(TestSceneManiaModSandbox)).ToList(); - - public TestSceneManiaModSandbox() - : this(null) - { - } - - public TestSceneManiaModSandbox(Mod mod = null) - : base(new ManiaRuleset(), mod) - { - } - } -} diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs index 7f09731a11..46a3c1dff3 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs @@ -5,16 +5,50 @@ using System; using System.Collections.Generic; using System.Linq; using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Rulesets.Scoring; +using osu.Game.Scoring; +using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests.Mods { - public class TestSceneOsuModDifficultyAdjust : TestSceneOsuModSandbox + public class TestSceneOsuModDifficultyAdjust : ModSandboxTestScene { public override IReadOnlyList RequiredTypes => base.RequiredTypes.Append(typeof(OsuModDifficultyAdjust)).ToList(); public TestSceneOsuModDifficultyAdjust() - : base(new OsuModDifficultyAdjust()) + : base(new OsuRuleset()) { } + + protected override ModTestCaseData[] CreateTestCases() => new[] + { + new ModTestCaseData("no adjustment", new OsuModDifficultyAdjust()) + { + Autoplay = true, + PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 + }, + new ModTestCaseData("cs = 10", new OsuModDifficultyAdjust { CircleSize = { Value = 10 } }) + { + Autoplay = true, + PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 + }, + new ModTestCaseData("ar = 10", new OsuModDifficultyAdjust { ApproachRate = { Value = 10 } }) + { + Autoplay = true, + PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 + }, + }; + + protected override TestPlayer CreateReplayPlayer(Score score) => new ScoreAccessibleTestPlayer(score); + + private class ScoreAccessibleTestPlayer : TestPlayer + { + public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; + + public ScoreAccessibleTestPlayer(Score score) + : base(score) + { + } + } } } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuModSandbox.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuModSandbox.cs deleted file mode 100644 index 9f816ef2ed..0000000000 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuModSandbox.cs +++ /dev/null @@ -1,28 +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; -using System.Collections.Generic; -using System.Linq; -using NUnit.Framework; -using osu.Game.Rulesets.Mods; -using osu.Game.Tests.Visual; - -namespace osu.Game.Rulesets.Osu.Tests -{ - [TestFixture] - public class TestSceneOsuModSandbox : ModSandboxTestScene - { - public override IReadOnlyList RequiredTypes => base.RequiredTypes.Append(typeof(TestSceneOsuModSandbox)).ToList(); - - public TestSceneOsuModSandbox() - : this(null) - { - } - - public TestSceneOsuModSandbox(Mod mod = null) - : base(new OsuRuleset(), mod) - { - } - } -} diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModSandbox.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModSandbox.cs deleted file mode 100644 index ef62c7ed56..0000000000 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModSandbox.cs +++ /dev/null @@ -1,28 +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; -using System.Collections.Generic; -using System.Linq; -using NUnit.Framework; -using osu.Game.Rulesets.Mods; -using osu.Game.Tests.Visual; - -namespace osu.Game.Rulesets.Taiko.Tests -{ - [TestFixture] - public class TestSceneTaikoModSandbox : ModSandboxTestScene - { - public override IReadOnlyList RequiredTypes => base.RequiredTypes.Append(typeof(TestSceneTaikoModSandbox)).ToList(); - - public TestSceneTaikoModSandbox() - : this(null) - { - } - - public TestSceneTaikoModSandbox(Mod mod = null) - : base(new TaikoRuleset(), mod) - { - } - } -} diff --git a/osu.Game/Tests/Visual/ModSandboxTestScene.cs b/osu.Game/Tests/Visual/ModSandboxTestScene.cs index 84bab6a9b9..0610a145ae 100644 --- a/osu.Game/Tests/Visual/ModSandboxTestScene.cs +++ b/osu.Game/Tests/Visual/ModSandboxTestScene.cs @@ -4,9 +4,12 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using osu.Game.Beatmaps; +using osu.Game.Replays; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; +using osu.Game.Scoring; using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual @@ -29,36 +32,78 @@ namespace osu.Game.Tests.Visual { foreach (var testCase in CreateTestCases()) { - AddStep("set test case", () => currentTest = testCase); + AddStep(testCase.Name, () => currentTest = testCase); base.SetUpSteps(); + AddUntilStep("test passed", () => testCase.PassCondition?.Invoke() ?? true); } } - protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => currentTest.Beatmap; + protected sealed override IBeatmap CreateBeatmap(RulesetInfo ruleset) => currentTest?.Beatmap ?? base.CreateBeatmap(ruleset); - protected override Player CreatePlayer(Ruleset ruleset) + protected sealed override Player CreatePlayer(Ruleset ruleset) { SelectedMods.Value = SelectedMods.Value.Append(currentTest.Mod).ToArray(); - if (currentTest.Autoplay) - { - // We're simulating an auto-play via a replay so that the auto-play mod does not interfere - var beatmap = Beatmap.Value.GetPlayableBeatmap(ruleset.RulesetInfo, SelectedMods.Value); - var score = ruleset.GetAutoplayMod().CreateReplayScore(beatmap); + var score = currentTest.Autoplay + ? ruleset.GetAutoplayMod().CreateReplayScore(Beatmap.Value.GetPlayableBeatmap(ruleset.RulesetInfo, SelectedMods.Value)) + : new Score { Replay = new Replay() }; - return new TestReplayPlayer(score, false, false); - } - - return base.CreatePlayer(ruleset); + return CreateReplayPlayer(score); } + /// + /// Creates the test cases for this test scene. + /// protected abstract ModTestCaseData[] CreateTestCases(); + /// + /// Creates the for a test case. + /// + /// The . + protected virtual TestPlayer CreateReplayPlayer(Score score) => new TestPlayer(score); + + protected class TestPlayer : TestReplayPlayer + { + public TestPlayer(Score score) + : base(score, false, false) + { + } + } + protected class ModTestCaseData { - public Mod Mod; - public bool Autoplay; + /// + /// Whether to use a replay to simulate an auto-play. True by default. + /// + public bool Autoplay = true; + + /// + /// The beatmap for this test case. + /// + [CanBeNull] public IBeatmap Beatmap; + + /// + /// The conditions that cause this test case to pass. + /// + [CanBeNull] + public Func PassCondition; + + /// + /// The name of this test case, displayed in the test browser. + /// + public readonly string Name; + + /// + /// The this test case tests. + /// + public readonly Mod Mod; + + public ModTestCaseData(string name, Mod mod) + { + Name = name; + Mod = mod; + } } } } From ce7cbf29ca1546f4fc8f1d81ca8cbb401537dfdf Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Mar 2020 12:20:25 +0900 Subject: [PATCH 07/53] Move to using test methods for better separation --- .../Mods/TestSceneOsuModDifficultyAdjust.cs | 37 ++++++++++--------- osu.Game/Tests/Visual/ModSandboxTestScene.cs | 22 +++++------ osu.Game/Tests/Visual/PlayerTestScene.cs | 17 +++++++++ osu.Game/Tests/Visual/ScreenTestScene.cs | 2 +- 4 files changed, 48 insertions(+), 30 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs index 46a3c1dff3..1fc9ccccd1 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NUnit.Framework; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Scoring; @@ -20,24 +21,26 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods { } - protected override ModTestCaseData[] CreateTestCases() => new[] + [Test] + public void TestNoAdjustment() => CreateModTest(new ModTestCaseData("no adjustment", new OsuModDifficultyAdjust()) { - new ModTestCaseData("no adjustment", new OsuModDifficultyAdjust()) - { - Autoplay = true, - PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 - }, - new ModTestCaseData("cs = 10", new OsuModDifficultyAdjust { CircleSize = { Value = 10 } }) - { - Autoplay = true, - PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 - }, - new ModTestCaseData("ar = 10", new OsuModDifficultyAdjust { ApproachRate = { Value = 10 } }) - { - Autoplay = true, - PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 - }, - }; + Autoplay = true, + PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 + }); + + [Test] + public void TestCircleSize10() => CreateModTest(new ModTestCaseData("cs = 10", new OsuModDifficultyAdjust { CircleSize = { Value = 10 } }) + { + Autoplay = true, + PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 + }); + + [Test] + public void TestApproachRate10() => CreateModTest(new ModTestCaseData("ar = 10", new OsuModDifficultyAdjust { ApproachRate = { Value = 10 } }) + { + Autoplay = true, + PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 + }); protected override TestPlayer CreateReplayPlayer(Score score) => new ScoreAccessibleTestPlayer(score); diff --git a/osu.Game/Tests/Visual/ModSandboxTestScene.cs b/osu.Game/Tests/Visual/ModSandboxTestScene.cs index 0610a145ae..a1fa757452 100644 --- a/osu.Game/Tests/Visual/ModSandboxTestScene.cs +++ b/osu.Game/Tests/Visual/ModSandboxTestScene.cs @@ -16,6 +16,8 @@ namespace osu.Game.Tests.Visual { public abstract class ModSandboxTestScene : PlayerTestScene { + protected sealed override bool HasCustomSteps => true; + public override IReadOnlyList RequiredTypes => new[] { typeof(ModSandboxTestScene) @@ -28,14 +30,15 @@ namespace osu.Game.Tests.Visual private ModTestCaseData currentTest; - public override void SetUpSteps() + protected void CreateModTest(ModTestCaseData testCaseData) => CreateTest(() => { - foreach (var testCase in CreateTestCases()) - { - AddStep(testCase.Name, () => currentTest = testCase); - base.SetUpSteps(); - AddUntilStep("test passed", () => testCase.PassCondition?.Invoke() ?? true); - } + AddStep("set test data", () => currentTest = testCaseData); + }); + + public override void TearDownSteps() + { + AddUntilStep("test passed", () => currentTest?.PassCondition?.Invoke() ?? true); + base.TearDownSteps(); } protected sealed override IBeatmap CreateBeatmap(RulesetInfo ruleset) => currentTest?.Beatmap ?? base.CreateBeatmap(ruleset); @@ -51,11 +54,6 @@ namespace osu.Game.Tests.Visual return CreateReplayPlayer(score); } - /// - /// Creates the test cases for this test scene. - /// - protected abstract ModTestCaseData[] CreateTestCases(); - /// /// Creates the for a test case. /// diff --git a/osu.Game/Tests/Visual/PlayerTestScene.cs b/osu.Game/Tests/Visual/PlayerTestScene.cs index 1ca5256353..0d5aac8cfd 100644 --- a/osu.Game/Tests/Visual/PlayerTestScene.cs +++ b/osu.Game/Tests/Visual/PlayerTestScene.cs @@ -1,6 +1,7 @@ // 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 System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; @@ -14,6 +15,11 @@ namespace osu.Game.Tests.Visual { public abstract class PlayerTestScene : RateAdjustedBeatmapTestScene { + /// + /// Whether custom test steps are provided. Custom tests should invoke to create the test steps. + /// + protected virtual bool HasCustomSteps { get; } = false; + private readonly Ruleset ruleset; protected Player Player; @@ -37,6 +43,17 @@ namespace osu.Game.Tests.Visual { base.SetUpSteps(); + if (!HasCustomSteps) + CreateTest(null); + } + + protected void CreateTest(Action action) + { + if (action != null && !HasCustomSteps) + throw new InvalidOperationException($"Cannot add custom test steps without {nameof(HasCustomSteps)} being set."); + + action?.Invoke(); + AddStep(ruleset.RulesetInfo.Name, LoadPlayer); AddUntilStep("player loaded", () => Player.IsLoaded && Player.Alpha == 1); } diff --git a/osu.Game/Tests/Visual/ScreenTestScene.cs b/osu.Game/Tests/Visual/ScreenTestScene.cs index feca592049..d26aacf2bc 100644 --- a/osu.Game/Tests/Visual/ScreenTestScene.cs +++ b/osu.Game/Tests/Visual/ScreenTestScene.cs @@ -34,7 +34,7 @@ namespace osu.Game.Tests.Visual public virtual void SetUpSteps() => addExitAllScreensStep(); [TearDownSteps] - public void TearDownSteps() => addExitAllScreensStep(); + public virtual void TearDownSteps() => addExitAllScreensStep(); private void addExitAllScreensStep() { From 3d344a076de0a934a5adfb92f2d1d01a3e1da31d Mon Sep 17 00:00:00 2001 From: naoey Date: Tue, 3 Mar 2020 06:17:25 +0530 Subject: [PATCH 08/53] Add test for disabled keycounter, don't discard change event values --- .../Visual/Gameplay/TestSceneKeyCounter.cs | 23 ++++++++++--------- osu.Game/Screens/Play/Player.cs | 19 ++++++++------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs index e7b3e007fc..10827bc0b9 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs @@ -47,21 +47,22 @@ namespace osu.Game.Tests.Visual.Gameplay Key testKey = ((KeyCounterKeyboard)kc.Children.First()).Key; - AddStep($"Press {testKey} key", () => + void addPressKeyStep() { - InputManager.PressKey(testKey); - InputManager.ReleaseKey(testKey); - }); + AddStep($"Press {testKey} key", () => + { + InputManager.PressKey(testKey); + InputManager.ReleaseKey(testKey); + }); + } + addPressKeyStep(); AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses == 1); - - AddStep($"Press {testKey} key", () => - { - InputManager.PressKey(testKey); - InputManager.ReleaseKey(testKey); - }); - + addPressKeyStep(); AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses == 2); + AddStep($"Disable counting", () => testCounter.IsCounting = false); + addPressKeyStep(); + AddAssert($"Check {testKey} count has not changed", () => testCounter.CountPresses == 2); Add(kc); } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 237e364e69..2d49c707ec 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -157,7 +157,10 @@ namespace osu.Game.Screens.Play addGameplayComponents(GameplayClockContainer, Beatmap.Value); addOverlayComponents(GameplayClockContainer, Beatmap.Value); - DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true); + DrawableRuleset.HasReplayLoaded.BindValueChanged(e => + { + updatePauseOnFocusLostState(e.NewValue, BreakOverlay.IsBreakTime.Value); + }, true); // bind clock into components that require it DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused); @@ -184,7 +187,7 @@ namespace osu.Game.Screens.Play foreach (var mod in Mods.Value.OfType()) mod.ApplyToHealthProcessor(HealthProcessor); - BreakOverlay.IsBreakTime.BindValueChanged(_ => onBreakTimeChanged(), true); + BreakOverlay.IsBreakTime.BindValueChanged(onBreakTimeChanged, true); } private void addUnderlayComponents(Container target) @@ -286,16 +289,16 @@ namespace osu.Game.Screens.Play HealthProcessor.IsBreakTime.BindTo(BreakOverlay.IsBreakTime); } - private void onBreakTimeChanged() + private void onBreakTimeChanged(ValueChangedEvent changeEvent) { - updatePauseOnFocusLostState(); - HUDOverlay.KeyCounter.IsCounting = !BreakOverlay.IsBreakTime.Value; + updatePauseOnFocusLostState(DrawableRuleset.HasReplayLoaded.Value, changeEvent.NewValue); + HUDOverlay.KeyCounter.IsCounting = !changeEvent.NewValue; } - private void updatePauseOnFocusLostState() => + private void updatePauseOnFocusLostState(bool replayLoaded, bool isBreakTime) => HUDOverlay.HoldToQuit.PauseOnFocusLost = PauseOnFocusLost - && !DrawableRuleset.HasReplayLoaded.Value - && !BreakOverlay.IsBreakTime.Value; + && !replayLoaded + && !isBreakTime; private IBeatmap loadPlayableBeatmap() { From 90c2f7bd89620bc05cd0529f3a74780199e2fa0a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 3 Mar 2020 12:13:36 +0900 Subject: [PATCH 09/53] Fail tests by default --- osu.Game/Tests/Visual/ModSandboxTestScene.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Tests/Visual/ModSandboxTestScene.cs b/osu.Game/Tests/Visual/ModSandboxTestScene.cs index a1fa757452..8bfa373e46 100644 --- a/osu.Game/Tests/Visual/ModSandboxTestScene.cs +++ b/osu.Game/Tests/Visual/ModSandboxTestScene.cs @@ -37,7 +37,7 @@ namespace osu.Game.Tests.Visual public override void TearDownSteps() { - AddUntilStep("test passed", () => currentTest?.PassCondition?.Invoke() ?? true); + AddUntilStep("test passed", () => currentTest?.PassCondition?.Invoke() ?? false); base.TearDownSteps(); } From 1e26df64b6cc022123222e4e104fbb382670037d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 3 Mar 2020 12:58:07 +0900 Subject: [PATCH 10/53] Fix constructor test failures --- osu.Game/Tests/Visual/ModSandboxTestScene.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Tests/Visual/ModSandboxTestScene.cs b/osu.Game/Tests/Visual/ModSandboxTestScene.cs index 8bfa373e46..11612d0eca 100644 --- a/osu.Game/Tests/Visual/ModSandboxTestScene.cs +++ b/osu.Game/Tests/Visual/ModSandboxTestScene.cs @@ -37,7 +37,14 @@ namespace osu.Game.Tests.Visual public override void TearDownSteps() { - AddUntilStep("test passed", () => currentTest?.PassCondition?.Invoke() ?? false); + AddUntilStep("test passed", () => + { + if (currentTest == null) + return true; + + return currentTest.PassCondition?.Invoke() ?? false; + }); + base.TearDownSteps(); } From a1aecd4c3905bbd9cd9d9e1925d257ff40e6419a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 3 Mar 2020 12:59:41 +0900 Subject: [PATCH 11/53] Fix TrackVirtualManual not respecting rate adjustments --- osu.Game/Tests/Visual/OsuTestScene.cs | 57 ++++++--------------------- 1 file changed, 11 insertions(+), 46 deletions(-) diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index b203557fab..3faecc87d2 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -229,17 +229,10 @@ namespace osu.Game.Tests.Visual /// public class TrackVirtualManual : Track { + private readonly StopwatchClock stopwatchClock = new StopwatchClock(); + private readonly IFrameBasedClock referenceClock; - private readonly ManualClock clock = new ManualClock(); - - private bool running; - - /// - /// Local offset added to the reference clock to resolve correct time. - /// - private double offset; - public TrackVirtualManual(IFrameBasedClock referenceClock) { this.referenceClock = referenceClock; @@ -248,60 +241,32 @@ namespace osu.Game.Tests.Visual public override bool Seek(double seek) { - offset = Math.Clamp(seek, 0, Length); - lastReferenceTime = null; + var offset = Math.Clamp(seek, 0, Length); + + stopwatchClock.Seek(offset); return offset == seek; } - public override void Start() - { - running = true; - } + public override void Start() => stopwatchClock.Start(); public override void Reset() { - Seek(0); + stopwatchClock.Seek(0); base.Reset(); } - public override void Stop() - { - if (running) - { - running = false; - // on stopping, the current value should be transferred out of the clock, as we can no longer rely on - // the referenceClock (which will still be counting time). - offset = clock.CurrentTime; - lastReferenceTime = null; - } - } + public override void Stop() => stopwatchClock.Stop(); - public override bool IsRunning => running; + public override bool IsRunning => stopwatchClock.IsRunning; - private double? lastReferenceTime; - - public override double CurrentTime => clock.CurrentTime; + public override double CurrentTime => stopwatchClock.CurrentTime; protected override void UpdateState() { base.UpdateState(); - if (running) - { - double refTime = referenceClock.CurrentTime; - - if (!lastReferenceTime.HasValue) - { - // if the clock just started running, the current value should be transferred to the offset - // (to zero the progression of time). - offset -= refTime; - } - - lastReferenceTime = refTime; - } - - clock.CurrentTime = Math.Min((lastReferenceTime ?? 0) + offset, Length); + stopwatchClock.Rate = Rate * referenceClock.Rate; if (CurrentTime >= Length) { From cc5b44e46681eb6b46c6c0fc1109cd5b64dd108b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 3 Mar 2020 13:36:55 +0900 Subject: [PATCH 12/53] Add test scene --- .../Mods/TestSceneOsuModDoubleTime.cs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDoubleTime.cs diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDoubleTime.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDoubleTime.cs new file mode 100644 index 0000000000..deb733c581 --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDoubleTime.cs @@ -0,0 +1,41 @@ +// 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.Game.Rulesets.Osu.Mods; +using osu.Game.Rulesets.Scoring; +using osu.Game.Scoring; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Osu.Tests.Mods +{ + public class TestSceneOsuModDoubleTime : ModSandboxTestScene + { + public TestSceneOsuModDoubleTime() + : base(new OsuRuleset()) + { + } + + [TestCase(0.5)] + [TestCase(1.01)] + [TestCase(1.5)] + [TestCase(2)] + [TestCase(5)] + public void TestDefaultRate(double rate) => CreateModTest(new ModTestCaseData("1.5x", new OsuModDoubleTime { SpeedChange = { Value = rate } }) + { + PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 + }); + + protected override TestPlayer CreateReplayPlayer(Score score) => new ScoreAccessibleTestPlayer(score); + + private class ScoreAccessibleTestPlayer : TestPlayer + { + public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; + + public ScoreAccessibleTestPlayer(Score score) + : base(score) + { + } + } + } +} From c3f840cc1a5071ee92c758315d5c41ee12cd1dec Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Tue, 3 Mar 2020 17:12:01 -0800 Subject: [PATCH 13/53] Fix Autoplay = false and AllowFail behavior --- .../Mods/TestSceneOsuModDifficultyAdjust.cs | 6 +++--- osu.Game/Tests/Visual/ModSandboxTestScene.cs | 13 ++++++++----- osu.Game/Tests/Visual/PlayerTestScene.cs | 2 ++ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs index 1fc9ccccd1..20cb9ef05d 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs @@ -42,14 +42,14 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 }); - protected override TestPlayer CreateReplayPlayer(Score score) => new ScoreAccessibleTestPlayer(score); + protected override TestPlayer CreateReplayPlayer(Score score, bool allowFail) => new ScoreAccessibleTestPlayer(score, allowFail); private class ScoreAccessibleTestPlayer : TestPlayer { public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; - public ScoreAccessibleTestPlayer(Score score) - : base(score) + public ScoreAccessibleTestPlayer(Score score, bool allowFail) + : base(score, allowFail) { } } diff --git a/osu.Game/Tests/Visual/ModSandboxTestScene.cs b/osu.Game/Tests/Visual/ModSandboxTestScene.cs index 11612d0eca..8a9cdf009b 100644 --- a/osu.Game/Tests/Visual/ModSandboxTestScene.cs +++ b/osu.Game/Tests/Visual/ModSandboxTestScene.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; using osu.Game.Beatmaps; -using osu.Game.Replays; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Scoring; @@ -56,22 +55,26 @@ namespace osu.Game.Tests.Visual var score = currentTest.Autoplay ? ruleset.GetAutoplayMod().CreateReplayScore(Beatmap.Value.GetPlayableBeatmap(ruleset.RulesetInfo, SelectedMods.Value)) - : new Score { Replay = new Replay() }; + : null; - return CreateReplayPlayer(score); + return CreateReplayPlayer(score, AllowFail); } /// /// Creates the for a test case. /// /// The . - protected virtual TestPlayer CreateReplayPlayer(Score score) => new TestPlayer(score); + /// Whether the player can fail. + protected virtual TestPlayer CreateReplayPlayer(Score score, bool allowFail) => new TestPlayer(score, allowFail); protected class TestPlayer : TestReplayPlayer { - public TestPlayer(Score score) + protected override bool AllowFail { get; } + + public TestPlayer(Score score, bool allowFail) : base(score, false, false) { + AllowFail = allowFail; } } diff --git a/osu.Game/Tests/Visual/PlayerTestScene.cs b/osu.Game/Tests/Visual/PlayerTestScene.cs index 0d5aac8cfd..17ad6e80df 100644 --- a/osu.Game/Tests/Visual/PlayerTestScene.cs +++ b/osu.Game/Tests/Visual/PlayerTestScene.cs @@ -68,6 +68,8 @@ namespace osu.Game.Tests.Visual Beatmap.Value = CreateWorkingBeatmap(beatmap); + SelectedMods.Value = Array.Empty(); + if (!AllowFail) { var noFailMod = ruleset.GetAllMods().FirstOrDefault(m => m is ModNoFail); From 7464a486d980a4180aa86f3404a77e8234688bcd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Mar 2020 16:35:45 +0900 Subject: [PATCH 14/53] Fix DummyWorkingBeatmap's track completion attempting to change game-wide beatmap --- osu.Game/OsuGame.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 5781a7fbc4..69d5a9a583 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -428,11 +428,17 @@ namespace osu.Game } } - private void currentTrackCompleted() => Schedule(() => + private void currentTrackCompleted() { - if (!Beatmap.Value.Track.Looping && !Beatmap.Disabled) - musicController.NextTrack(); - }); + if (Beatmap.Value is DummyWorkingBeatmap) + return; + + Schedule(() => + { + if (Beatmap.Value.Track.Looping && !Beatmap.Disabled) + musicController.NextTrack(); + }); + } #endregion From 184d10a75a9f0c4cdc839d8b62d1540ac2650781 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Wed, 4 Mar 2020 15:45:22 +0700 Subject: [PATCH 15/53] Revert "Reduce social overlay/direct overlay paddings" This reverts commit cb1129218135bd2b1e2d3a287d381c13e08725d6. --- osu.Game/Overlays/SearchableList/SearchableListOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs index 72796df6d5..0783c64c20 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs @@ -15,7 +15,7 @@ namespace osu.Game.Overlays.SearchableList { public abstract class SearchableListOverlay : FullscreenOverlay { - public const float WIDTH_PADDING = 10; + public const float WIDTH_PADDING = 80; protected SearchableListOverlay(OverlayColourScheme colourScheme) : base(colourScheme) From a1dc59500699d1d83875c58a48bf9b0e489ec187 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Wed, 4 Mar 2020 15:46:35 +0700 Subject: [PATCH 16/53] Change scroll container padding --- osu.Game/Overlays/SearchableList/SearchableListOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs index 0783c64c20..d6174e0733 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs @@ -80,7 +80,7 @@ namespace osu.Game.Overlays.SearchableList { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Horizontal = WIDTH_PADDING, Bottom = 50 }, + Padding = new MarginPadding { Horizontal = 10, Bottom = 50 }, Direction = FillDirection.Vertical, }, }, From bac35b2a68f15a0abe079f94a17883e6c040ef68 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Mar 2020 19:09:52 +0900 Subject: [PATCH 17/53] Handle beatmap track changing in a saner way --- osu.Game/OsuGame.cs | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 69d5a9a583..0be9e6cdaa 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -396,18 +396,27 @@ namespace osu.Game private void beatmapChanged(ValueChangedEvent beatmap) { - var nextBeatmap = beatmap.NewValue; - if (nextBeatmap?.Track != null) - nextBeatmap.Track.Completed += currentTrackCompleted; - - var oldBeatmap = beatmap.OldValue; - if (oldBeatmap?.Track != null) - oldBeatmap.Track.Completed -= currentTrackCompleted; + beatmap.OldValue?.CancelAsyncLoad(); updateModDefaults(); - oldBeatmap?.CancelAsyncLoad(); - nextBeatmap?.BeginAsyncLoad(); + var newBeatmap = beatmap.NewValue; + + if (newBeatmap != null) + { + newBeatmap.Track.Completed += () => Scheduler.AddOnce(() => trackCompleted(newBeatmap)); + newBeatmap.BeginAsyncLoad(); + } + + void trackCompleted(WorkingBeatmap b) + { + // the source of track completion is the audio thread, so the beatmap may have changed before a firing. + if (Beatmap.Value != b) + return; + + if (Beatmap.Value.Track.Looping && !Beatmap.Disabled) + musicController.NextTrack(); + } } private void modsChanged(ValueChangedEvent> mods) @@ -428,18 +437,6 @@ namespace osu.Game } } - private void currentTrackCompleted() - { - if (Beatmap.Value is DummyWorkingBeatmap) - return; - - Schedule(() => - { - if (Beatmap.Value.Track.Looping && !Beatmap.Disabled) - musicController.NextTrack(); - }); - } - #endregion private ScheduledDelegate performFromMainMenuTask; From 38d91ccd0d20dcd4f9f4e016f03da00da2ba8152 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Mar 2020 19:07:34 +0900 Subject: [PATCH 18/53] Add comment regarding no-longer-required schedule --- osu.Game/OsuGameBase.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index a890331f05..67aa4a8d4d 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -211,6 +211,10 @@ namespace osu.Game Audio.Tracks.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8)); Beatmap = new NonNullableBindable(defaultBeatmap); + + // ScheduleAfterChildren is safety against something in the current frame accessing the previous beatmap's track + // and potentially causing a reload of it after just unloading. + // Note that the reason for this being added *has* been resolved, so it may be feasible to remover this if required. Beatmap.BindValueChanged(b => ScheduleAfterChildren(() => { // compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo) From 11ffe6a072e935cbcfeaef5546754c0359770470 Mon Sep 17 00:00:00 2001 From: McEndu Date: Wed, 4 Mar 2020 21:45:01 +0800 Subject: [PATCH 19/53] Remove LD_LIBRARY_PATH from vscode launch.json --- .vscode/launch.json | 42 +----------------------------------------- 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 6480612b2e..4e8af405a2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,11 +11,6 @@ ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build osu! (Debug)", - "linux": { - "env": { - "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}" - } - }, "console": "internalConsole" }, { @@ -28,11 +23,6 @@ ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build osu! (Release)", - "linux": { - "env": { - "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.1:${env:LD_LIBRARY_PATH}" - } - }, "console": "internalConsole" }, { @@ -45,11 +35,6 @@ ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build tests (Debug)", - "linux": { - "env": { - "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}" - } - }, "console": "internalConsole" }, { @@ -62,11 +47,6 @@ ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build tests (Release)", - "linux": { - "env": { - "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp3.1:${env:LD_LIBRARY_PATH}" - } - }, "console": "internalConsole" }, { @@ -80,11 +60,6 @@ ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build osu! (Debug)", - "linux": { - "env": { - "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}" - } - }, "console": "internalConsole" }, { @@ -98,11 +73,6 @@ ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build osu! (Release)", - "linux": { - "env": { - "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.1:${env:LD_LIBRARY_PATH}" - } - }, "console": "internalConsole" }, { @@ -116,11 +86,6 @@ ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build tournament tests (Debug)", - "linux": { - "env": { - "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}" - } - }, "console": "internalConsole" }, { @@ -134,11 +99,6 @@ ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build tournament tests (Release)", - "linux": { - "env": { - "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}" - } - }, "console": "internalConsole" }, { @@ -169,4 +129,4 @@ "externalConsole": false } ] -} \ No newline at end of file +} From ce3786cfd912b2cff9e7431e13cb7761352de8af Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 10:11:27 +0900 Subject: [PATCH 20/53] Rename to ModTestScene (is no longer a sandbox) --- .../Mods/TestSceneOsuModDifficultyAdjust.cs | 2 +- .../Visual/{ModSandboxTestScene.cs => ModTestScene.cs} | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename osu.Game/Tests/Visual/{ModSandboxTestScene.cs => ModTestScene.cs} (95%) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs index 20cb9ef05d..c2a7a5003f 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs @@ -12,7 +12,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests.Mods { - public class TestSceneOsuModDifficultyAdjust : ModSandboxTestScene + public class TestSceneOsuModDifficultyAdjust : ModTestScene { public override IReadOnlyList RequiredTypes => base.RequiredTypes.Append(typeof(OsuModDifficultyAdjust)).ToList(); diff --git a/osu.Game/Tests/Visual/ModSandboxTestScene.cs b/osu.Game/Tests/Visual/ModTestScene.cs similarity index 95% rename from osu.Game/Tests/Visual/ModSandboxTestScene.cs rename to osu.Game/Tests/Visual/ModTestScene.cs index 8a9cdf009b..1ff061dfac 100644 --- a/osu.Game/Tests/Visual/ModSandboxTestScene.cs +++ b/osu.Game/Tests/Visual/ModTestScene.cs @@ -13,16 +13,16 @@ using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual { - public abstract class ModSandboxTestScene : PlayerTestScene + public abstract class ModTestScene : PlayerTestScene { protected sealed override bool HasCustomSteps => true; public override IReadOnlyList RequiredTypes => new[] { - typeof(ModSandboxTestScene) + typeof(ModTestScene) }; - protected ModSandboxTestScene(Ruleset ruleset) + protected ModTestScene(Ruleset ruleset) : base(ruleset) { } From 2a581ef24786102d41709f08cde6747060418ed1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 10:15:17 +0900 Subject: [PATCH 21/53] Remove required types --- .../Mods/TestSceneOsuModDifficultyAdjust.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs index c2a7a5003f..4a284022e2 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs @@ -1,9 +1,6 @@ // 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 System.Collections.Generic; -using System.Linq; using NUnit.Framework; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Scoring; @@ -14,8 +11,6 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods { public class TestSceneOsuModDifficultyAdjust : ModTestScene { - public override IReadOnlyList RequiredTypes => base.RequiredTypes.Append(typeof(OsuModDifficultyAdjust)).ToList(); - public TestSceneOsuModDifficultyAdjust() : base(new OsuRuleset()) { From 0f1f1d1a6b91ce361913fbf2aa8bb6fe8a23fa01 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 10:18:37 +0900 Subject: [PATCH 22/53] Remove unused "name" parameter --- .../Mods/TestSceneOsuModDifficultyAdjust.cs | 6 +++--- osu.Game/Tests/Visual/ModTestScene.cs | 8 +------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs index 4a284022e2..8ff55c9728 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs @@ -17,21 +17,21 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods } [Test] - public void TestNoAdjustment() => CreateModTest(new ModTestCaseData("no adjustment", new OsuModDifficultyAdjust()) + public void TestNoAdjustment() => CreateModTest(new ModTestCaseData(new OsuModDifficultyAdjust()) { Autoplay = true, PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 }); [Test] - public void TestCircleSize10() => CreateModTest(new ModTestCaseData("cs = 10", new OsuModDifficultyAdjust { CircleSize = { Value = 10 } }) + public void TestCircleSize10() => CreateModTest(new ModTestCaseData(new OsuModDifficultyAdjust { CircleSize = { Value = 10 } }) { Autoplay = true, PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 }); [Test] - public void TestApproachRate10() => CreateModTest(new ModTestCaseData("ar = 10", new OsuModDifficultyAdjust { ApproachRate = { Value = 10 } }) + public void TestApproachRate10() => CreateModTest(new ModTestCaseData(new OsuModDifficultyAdjust { ApproachRate = { Value = 10 } }) { Autoplay = true, PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 diff --git a/osu.Game/Tests/Visual/ModTestScene.cs b/osu.Game/Tests/Visual/ModTestScene.cs index 1ff061dfac..04f93fc683 100644 --- a/osu.Game/Tests/Visual/ModTestScene.cs +++ b/osu.Game/Tests/Visual/ModTestScene.cs @@ -97,19 +97,13 @@ namespace osu.Game.Tests.Visual [CanBeNull] public Func PassCondition; - /// - /// The name of this test case, displayed in the test browser. - /// - public readonly string Name; - /// /// The this test case tests. /// public readonly Mod Mod; - public ModTestCaseData(string name, Mod mod) + public ModTestCaseData(Mod mod) { - Name = name; Mod = mod; } } From 3b19467eadbcdf0bec89b240a7d981a599391acd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 10:19:42 +0900 Subject: [PATCH 23/53] ModTestCaseData -> ModTestData --- .../Mods/TestSceneOsuModDifficultyAdjust.cs | 6 +++--- osu.Game/Tests/Visual/ModTestScene.cs | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs index 8ff55c9728..427f25fe11 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs @@ -17,21 +17,21 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods } [Test] - public void TestNoAdjustment() => CreateModTest(new ModTestCaseData(new OsuModDifficultyAdjust()) + public void TestNoAdjustment() => CreateModTest(new ModTestData(new OsuModDifficultyAdjust()) { Autoplay = true, PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 }); [Test] - public void TestCircleSize10() => CreateModTest(new ModTestCaseData(new OsuModDifficultyAdjust { CircleSize = { Value = 10 } }) + public void TestCircleSize10() => CreateModTest(new ModTestData(new OsuModDifficultyAdjust { CircleSize = { Value = 10 } }) { Autoplay = true, PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 }); [Test] - public void TestApproachRate10() => CreateModTest(new ModTestCaseData(new OsuModDifficultyAdjust { ApproachRate = { Value = 10 } }) + public void TestApproachRate10() => CreateModTest(new ModTestData(new OsuModDifficultyAdjust { ApproachRate = { Value = 10 } }) { Autoplay = true, PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 diff --git a/osu.Game/Tests/Visual/ModTestScene.cs b/osu.Game/Tests/Visual/ModTestScene.cs index 04f93fc683..a8b40a5a68 100644 --- a/osu.Game/Tests/Visual/ModTestScene.cs +++ b/osu.Game/Tests/Visual/ModTestScene.cs @@ -27,11 +27,11 @@ namespace osu.Game.Tests.Visual { } - private ModTestCaseData currentTest; + private ModTestData currentTest; - protected void CreateModTest(ModTestCaseData testCaseData) => CreateTest(() => + protected void CreateModTest(ModTestData testData) => CreateTest(() => { - AddStep("set test data", () => currentTest = testCaseData); + AddStep("set test data", () => currentTest = testData); }); public override void TearDownSteps() @@ -78,7 +78,7 @@ namespace osu.Game.Tests.Visual } } - protected class ModTestCaseData + protected class ModTestData { /// /// Whether to use a replay to simulate an auto-play. True by default. @@ -102,7 +102,7 @@ namespace osu.Game.Tests.Visual /// public readonly Mod Mod; - public ModTestCaseData(Mod mod) + public ModTestData(Mod mod) { Mod = mod; } From fadebcdc03188cb171f453153530e55c6be6c7a9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 10:21:25 +0900 Subject: [PATCH 24/53] Move all sets to object initialiser for code formatting reasons --- .../Mods/TestSceneOsuModDifficultyAdjust.cs | 9 ++++++--- osu.Game/Tests/Visual/ModTestScene.cs | 7 +------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs index 427f25fe11..e4b1e30bcd 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs @@ -17,22 +17,25 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods } [Test] - public void TestNoAdjustment() => CreateModTest(new ModTestData(new OsuModDifficultyAdjust()) + public void TestNoAdjustment() => CreateModTest(new ModTestData() { + Mod = new OsuModDifficultyAdjust(), Autoplay = true, PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 }); [Test] - public void TestCircleSize10() => CreateModTest(new ModTestData(new OsuModDifficultyAdjust { CircleSize = { Value = 10 } }) + public void TestCircleSize10() => CreateModTest(new ModTestData { + Mod = new OsuModDifficultyAdjust { CircleSize = { Value = 10 } }, Autoplay = true, PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 }); [Test] - public void TestApproachRate10() => CreateModTest(new ModTestData(new OsuModDifficultyAdjust { ApproachRate = { Value = 10 } }) + public void TestApproachRate10() => CreateModTest(new ModTestData { + Mod = new OsuModDifficultyAdjust { ApproachRate = { Value = 10 } }, Autoplay = true, PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 }); diff --git a/osu.Game/Tests/Visual/ModTestScene.cs b/osu.Game/Tests/Visual/ModTestScene.cs index a8b40a5a68..3d12001cca 100644 --- a/osu.Game/Tests/Visual/ModTestScene.cs +++ b/osu.Game/Tests/Visual/ModTestScene.cs @@ -100,12 +100,7 @@ namespace osu.Game.Tests.Visual /// /// The this test case tests. /// - public readonly Mod Mod; - - public ModTestData(Mod mod) - { - Mod = mod; - } + public Mod Mod; } } } From 5200633f9fa19b8f6994ed6b7ef0ec51d18befdf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 11:25:07 +0900 Subject: [PATCH 25/53] Centralise TestPlayer implementations as much as possible --- .../TestSceneAutoJuiceStream.cs | 3 +- .../TestSceneOsuFlashlight.cs | 4 +- .../TestSceneSkinFallbacks.cs | 5 +- .../TestSceneSpinnerRotation.cs | 5 +- .../TestSceneSwellJudgements.cs | 27 ---------- .../TestSceneTaikoSuddenDeath.cs | 18 ++----- .../Background/TestSceneUserDimBackgrounds.cs | 10 ++-- .../Visual/Gameplay/TestSceneAutoplay.cs | 24 +++------ .../Gameplay/TestSceneGameplayRewinding.cs | 49 ++++--------------- .../Visual/Gameplay/TestScenePause.cs | 7 +-- .../Gameplay/TestScenePauseWhenInactive.cs | 5 +- .../Visual/Gameplay/TestScenePlayerLoader.cs | 13 +---- osu.Game/Tests/Visual/PlayerTestScene.cs | 5 +- osu.Game/Tests/Visual/TestPlayer.cs | 28 +++++++++++ 14 files changed, 63 insertions(+), 140 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs index 74a9c05bf9..ed7bfb9a44 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs @@ -7,7 +7,6 @@ using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; -using osu.Game.Screens.Play; using osu.Game.Tests.Visual; using osuTK; @@ -51,7 +50,7 @@ namespace osu.Game.Rulesets.Catch.Tests return beatmap; } - protected override Player CreatePlayer(Ruleset ruleset) + protected override TestPlayer CreatePlayer(Ruleset ruleset) { SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray(); return base.CreatePlayer(ruleset); diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuFlashlight.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuFlashlight.cs index 412effe176..19736a7709 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuFlashlight.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuFlashlight.cs @@ -3,13 +3,13 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; -using osu.Game.Screens.Play; +using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests { public class TestSceneOsuFlashlight : TestSceneOsuPlayer { - protected override Player CreatePlayer(Ruleset ruleset) + protected override TestPlayer CreatePlayer(Ruleset ruleset) { SelectedMods.Value = new Mod[] { new OsuModAutoplay(), new OsuModFlashlight(), }; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs index 4da1b1dae0..d39e24fc1f 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs @@ -18,7 +18,6 @@ using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Osu.Objects.Drawables; -using osu.Game.Screens.Play; using osu.Game.Skinning; using osu.Game.Storyboards; using osu.Game.Tests.Visual; @@ -56,7 +55,7 @@ namespace osu.Game.Rulesets.Osu.Tests private void checkNextHitObject(string skin) => AddUntilStep($"check skin from {skin}", () => { - var firstObject = ((TestPlayer)Player).DrawableRuleset.Playfield.HitObjectContainer.AliveObjects.OfType().FirstOrDefault(); + var firstObject = Player.DrawableRuleset.Playfield.HitObjectContainer.AliveObjects.OfType().FirstOrDefault(); if (firstObject == null) return false; @@ -75,7 +74,7 @@ namespace osu.Game.Rulesets.Osu.Tests [Resolved] private AudioManager audio { get; set; } - protected override Player CreatePlayer(Ruleset ruleset) => new SkinProvidingPlayer(testUserSkin); + protected override TestPlayer CreatePlayer(Ruleset ruleset) => new SkinProvidingPlayer(testUserSkin); protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) => new CustomSkinWorkingBeatmap(beatmap, storyboard, Clock, audio, testBeatmapSkin); diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs index 5cf571d961..ea006ec607 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs @@ -11,7 +11,6 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; -using osu.Game.Tests.Visual; using osuTK; using System.Collections.Generic; using System.Linq; @@ -44,7 +43,7 @@ namespace osu.Game.Rulesets.Osu.Tests base.SetUpSteps(); AddUntilStep("wait for track to start running", () => track.IsRunning); - AddStep("retrieve spinner", () => drawableSpinner = (DrawableSpinner)((TestPlayer)Player).DrawableRuleset.Playfield.AllHitObjects.First()); + AddStep("retrieve spinner", () => drawableSpinner = (DrawableSpinner)Player.DrawableRuleset.Playfield.AllHitObjects.First()); } [Test] @@ -89,7 +88,7 @@ namespace osu.Game.Rulesets.Osu.Tests { AddStep($"seek to {time}", () => track.Seek(time)); - AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, ((TestPlayer)Player).DrawableRuleset.FrameStableClock.CurrentTime, 100)); + AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100)); } protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new Beatmap diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneSwellJudgements.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneSwellJudgements.cs index ccacc50de1..303f0163b1 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneSwellJudgements.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneSwellJudgements.cs @@ -1,23 +1,16 @@ // 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 System.Linq; using NUnit.Framework; -using osu.Framework.Allocation; using osu.Game.Beatmaps; -using osu.Game.Rulesets.Judgements; -using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Objects; -using osu.Game.Screens.Play; using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests { public class TestSceneSwellJudgements : PlayerTestScene { - protected new TestPlayer Player => (TestPlayer)base.Player; - public TestSceneSwellJudgements() : base(new TaikoRuleset()) { @@ -49,25 +42,5 @@ namespace osu.Game.Rulesets.Taiko.Tests return beatmap; } - - protected override Player CreatePlayer(Ruleset ruleset) => new TestPlayer(); - - protected class TestPlayer : Player - { - public readonly List Results = new List(); - - public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; - - public TestPlayer() - : base(false, false) - { - } - - [BackgroundDependencyLoader] - private void load() - { - ScoreProcessor.NewJudgement += r => Results.Add(r); - } - } } } diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs index 140433a523..2ab041e191 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs @@ -4,11 +4,9 @@ using System.Linq; using NUnit.Framework; using osu.Game.Beatmaps; -using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Beatmaps; using osu.Game.Rulesets.Taiko.Mods; using osu.Game.Rulesets.Taiko.Objects; -using osu.Game.Screens.Play; using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests @@ -22,10 +20,10 @@ namespace osu.Game.Rulesets.Taiko.Tests protected override bool AllowFail => true; - protected override Player CreatePlayer(Ruleset ruleset) + protected override TestPlayer CreatePlayer(Ruleset ruleset) { SelectedMods.Value = SelectedMods.Value.Concat(new[] { new TaikoModSuddenDeath() }).ToArray(); - return new ScoreAccessiblePlayer(); + return base.CreatePlayer(ruleset); } protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => @@ -49,20 +47,10 @@ namespace osu.Game.Rulesets.Taiko.Tests AddStep("Setup judgements", () => { judged = false; - ((ScoreAccessiblePlayer)Player).ScoreProcessor.NewJudgement += b => judged = true; + Player.ScoreProcessor.NewJudgement += b => judged = true; }); AddUntilStep("swell judged", () => judged); AddAssert("not failed", () => !Player.HasFailed); } - - private class ScoreAccessiblePlayer : TestPlayer - { - public ScoreAccessiblePlayer() - : base(false, false) - { - } - - public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; - } } } diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs index 6d014ca1ca..06a155e78b 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs @@ -49,7 +49,7 @@ namespace osu.Game.Tests.Visual.Background private DummySongSelect songSelect; private TestPlayerLoader playerLoader; - private TestPlayer player; + private LoadBlockingTestPlayer player; private BeatmapManager manager; private RulesetStore rulesets; @@ -81,7 +81,7 @@ namespace osu.Game.Tests.Visual.Background public void PlayerLoaderSettingsHoverTest() { setupUserSettings(); - AddStep("Start player loader", () => songSelect.Push(playerLoader = new TestPlayerLoader(player = new TestPlayer { BlockLoad = true }))); + AddStep("Start player loader", () => songSelect.Push(playerLoader = new TestPlayerLoader(player = new LoadBlockingTestPlayer { BlockLoad = true }))); AddUntilStep("Wait for Player Loader to load", () => playerLoader?.IsLoaded ?? false); AddAssert("Background retained from song select", () => songSelect.IsBackgroundCurrent()); AddStep("Trigger background preview", () => @@ -268,7 +268,7 @@ namespace osu.Game.Tests.Visual.Background { setupUserSettings(); - AddStep("Start player loader", () => songSelect.Push(playerLoader = new TestPlayerLoader(player = new TestPlayer(allowPause)))); + AddStep("Start player loader", () => songSelect.Push(playerLoader = new TestPlayerLoader(player = new LoadBlockingTestPlayer(allowPause)))); AddUntilStep("Wait for Player Loader to load", () => playerLoader.IsLoaded); AddStep("Move mouse to center of screen", () => InputManager.MoveMouseTo(playerLoader.ScreenPos)); @@ -347,7 +347,7 @@ namespace osu.Game.Tests.Visual.Background public bool IsBlurCorrect() => ((FadeAccessibleBackground)Background).CurrentBlur == new Vector2(BACKGROUND_BLUR); } - private class TestPlayer : Visual.TestPlayer + private class LoadBlockingTestPlayer : TestPlayer { protected override BackgroundScreen CreateBackground() => new FadeAccessibleBackground(Beatmap.Value); @@ -360,7 +360,7 @@ namespace osu.Game.Tests.Visual.Background public readonly Bindable ReplacesBackground = new Bindable(); public readonly Bindable IsPaused = new Bindable(); - public TestPlayer(bool allowPause = true) + public LoadBlockingTestPlayer(bool allowPause = true) : base(allowPause) { } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs index 4daab8d137..756f31e0bf 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs @@ -5,7 +5,6 @@ using System.ComponentModel; using System.Linq; using osu.Game.Beatmaps; using osu.Game.Rulesets; -using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play; using osu.Game.Storyboards; @@ -14,20 +13,22 @@ namespace osu.Game.Tests.Visual.Gameplay [Description("Player instantiated with an autoplay mod.")] public class TestSceneAutoplay : TestSceneAllRulesetPlayers { + protected new TestPlayer Player => (TestPlayer)base.Player; + private ClockBackedTestWorkingBeatmap.TrackVirtualManual track; protected override Player CreatePlayer(Ruleset ruleset) { SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray(); - return new ScoreAccessiblePlayer(); + return new TestPlayer(false, false); } protected override void AddCheckSteps() { - AddUntilStep("score above zero", () => ((ScoreAccessiblePlayer)Player).ScoreProcessor.TotalScore.Value > 0); - AddUntilStep("key counter counted keys", () => ((ScoreAccessiblePlayer)Player).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 2)); + AddUntilStep("score above zero", () => Player.ScoreProcessor.TotalScore.Value > 0); + AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 2)); AddStep("rewind", () => track.Seek(-10000)); - AddUntilStep("key counter reset", () => ((ScoreAccessiblePlayer)Player).HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0)); + AddUntilStep("key counter reset", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0)); } protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) @@ -38,18 +39,5 @@ namespace osu.Game.Tests.Visual.Gameplay return working; } - - private class ScoreAccessiblePlayer : TestPlayer - { - public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; - public new HUDOverlay HUDOverlay => base.HUDOverlay; - - public new GameplayClockContainer GameplayClockContainer => base.GameplayClockContainer; - - public ScoreAccessiblePlayer() - : base(false, false) - { - } - } } } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs index 78c3b22fb9..310746d179 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs @@ -1,7 +1,6 @@ // 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 System.Linq; using NUnit.Framework; using osu.Framework.Allocation; @@ -11,12 +10,8 @@ using osu.Framework.Utils; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Rulesets; -using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.UI; -using osu.Game.Screens.Play; using osu.Game.Storyboards; using osuTK; @@ -24,8 +19,6 @@ namespace osu.Game.Tests.Visual.Gameplay { public class TestSceneGameplayRewinding : PlayerTestScene { - private RulesetExposingPlayer player => (RulesetExposingPlayer)Player; - [Resolved] private AudioManager audioManager { get; set; } @@ -48,13 +41,13 @@ namespace osu.Game.Tests.Visual.Gameplay { AddUntilStep("wait for track to start running", () => track.IsRunning); addSeekStep(3000); - AddAssert("all judged", () => player.DrawableRuleset.Playfield.AllHitObjects.All(h => h.Judged)); - AddUntilStep("key counter counted keys", () => player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses >= 7)); - AddStep("clear results", () => player.AppliedResults.Clear()); + AddAssert("all judged", () => Player.DrawableRuleset.Playfield.AllHitObjects.All(h => h.Judged)); + AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses >= 7)); + AddStep("clear results", () => Player.Results.Clear()); addSeekStep(0); - AddAssert("none judged", () => player.DrawableRuleset.Playfield.AllHitObjects.All(h => !h.Judged)); - AddUntilStep("key counters reset", () => player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0)); - AddAssert("no results triggered", () => player.AppliedResults.Count == 0); + AddAssert("none judged", () => Player.DrawableRuleset.Playfield.AllHitObjects.All(h => !h.Judged)); + AddUntilStep("key counters reset", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0)); + AddAssert("no results triggered", () => Player.Results.Count == 0); } private void addSeekStep(double time) @@ -62,13 +55,13 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep($"seek to {time}", () => track.Seek(time)); // Allow a few frames of lenience - AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, player.DrawableRuleset.FrameStableClock.CurrentTime, 100)); + AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100)); } - protected override Player CreatePlayer(Ruleset ruleset) + protected override TestPlayer CreatePlayer(Ruleset ruleset) { SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray(); - return new RulesetExposingPlayer(); + return base.CreatePlayer(ruleset); } protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) @@ -89,29 +82,5 @@ namespace osu.Game.Tests.Visual.Gameplay return beatmap; } - - private class RulesetExposingPlayer : Player - { - public readonly List AppliedResults = new List(); - - public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; - - public new HUDOverlay HUDOverlay => base.HUDOverlay; - - public new GameplayClockContainer GameplayClockContainer => base.GameplayClockContainer; - - public new DrawableRuleset DrawableRuleset => base.DrawableRuleset; - - public RulesetExposingPlayer() - : base(false, false) - { - } - - [BackgroundDependencyLoader] - private void load() - { - ScoreProcessor.NewJudgement += r => AppliedResults.Add(r); - } - } } } diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs index ad5bab4681..944e6ca6be 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs @@ -11,7 +11,6 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.Cursor; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; -using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play; using osuTK; using osuTK.Input; @@ -282,14 +281,10 @@ namespace osu.Game.Tests.Visual.Gameplay protected override bool AllowFail => true; - protected override Player CreatePlayer(Ruleset ruleset) => new PausePlayer(); + protected override TestPlayer CreatePlayer(Ruleset ruleset) => new PausePlayer(); protected class PausePlayer : TestPlayer { - public new HealthProcessor HealthProcessor => base.HealthProcessor; - - public new HUDOverlay HUDOverlay => base.HUDOverlay; - public bool FailOverlayVisible => FailOverlay.State.Value == Visibility.Visible; public bool PauseOverlayVisible => PauseOverlay.State.Value == Visibility.Visible; diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePauseWhenInactive.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePauseWhenInactive.cs index 3513b6c25a..a83320048b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePauseWhenInactive.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePauseWhenInactive.cs @@ -9,15 +9,12 @@ using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; -using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual.Gameplay { [HeadlessTest] // we alter unsafe properties on the game host to test inactive window state. public class TestScenePauseWhenInactive : PlayerTestScene { - protected new TestPlayer Player => (TestPlayer)base.Player; - protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) { var beatmap = (Beatmap)base.CreateBeatmap(ruleset); @@ -46,6 +43,6 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("time of pause is after gameplay start time", () => Player.GameplayClockContainer.GameplayClock.CurrentTime >= Player.DrawableRuleset.GameplayStartTime); } - protected override Player CreatePlayer(Ruleset ruleset) => new TestPlayer(true, true, true); + protected override TestPlayer CreatePlayer(Ruleset ruleset) => new TestPlayer(true, true, true); } } diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index 100f99d130..175f909a5a 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -9,7 +9,6 @@ using System.Threading.Tasks; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Utils; @@ -307,17 +306,7 @@ namespace osu.Game.Tests.Visual.Gameplay public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank; } - private class TestPlayer : Visual.TestPlayer - { - public new Bindable> Mods => base.Mods; - - public TestPlayer(bool allowPause = true, bool showResults = true) - : base(allowPause, showResults) - { - } - } - - protected class SlowLoadPlayer : Visual.TestPlayer + protected class SlowLoadPlayer : TestPlayer { public readonly ManualResetEventSlim AllowLoad = new ManualResetEventSlim(false); diff --git a/osu.Game/Tests/Visual/PlayerTestScene.cs b/osu.Game/Tests/Visual/PlayerTestScene.cs index 7c5ba7d30f..eee31fe014 100644 --- a/osu.Game/Tests/Visual/PlayerTestScene.cs +++ b/osu.Game/Tests/Visual/PlayerTestScene.cs @@ -8,7 +8,6 @@ using osu.Framework.Testing; using osu.Game.Configuration; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; -using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual { @@ -16,7 +15,7 @@ namespace osu.Game.Tests.Visual { private readonly Ruleset ruleset; - protected Player Player; + protected TestPlayer Player; protected PlayerTestScene(Ruleset ruleset) { @@ -69,6 +68,6 @@ namespace osu.Game.Tests.Visual LoadScreen(Player); } - protected virtual Player CreatePlayer(Ruleset ruleset) => new TestPlayer(false, false); + protected virtual TestPlayer CreatePlayer(Ruleset ruleset) => new TestPlayer(false, false); } } diff --git a/osu.Game/Tests/Visual/TestPlayer.cs b/osu.Game/Tests/Visual/TestPlayer.cs index 8e3821f1a0..f016d29f38 100644 --- a/osu.Game/Tests/Visual/TestPlayer.cs +++ b/osu.Game/Tests/Visual/TestPlayer.cs @@ -1,23 +1,51 @@ // 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.Bindables; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual { + /// + /// A player that exposes many components that would otherwise not be available, for testing purposes. + /// public class TestPlayer : Player { protected override bool PauseOnFocusLost { get; } public new DrawableRuleset DrawableRuleset => base.DrawableRuleset; + /// + /// Mods from *player* (not OsuScreen). + /// + public new Bindable> Mods => base.Mods; + + public new HUDOverlay HUDOverlay => base.HUDOverlay; + public new GameplayClockContainer GameplayClockContainer => base.GameplayClockContainer; + public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; + + public new HealthProcessor HealthProcessor => base.HealthProcessor; + + public readonly List Results = new List(); + public TestPlayer(bool allowPause = true, bool showResults = true, bool pauseOnFocusLost = false) : base(allowPause, showResults) { PauseOnFocusLost = pauseOnFocusLost; } + + [BackgroundDependencyLoader] + private void load() + { + ScoreProcessor.NewJudgement += r => Results.Add(r); + } } } From 26ce0d05d6f45f07cb6214b3f1036200f98513e6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 11:33:30 +0900 Subject: [PATCH 26/53] Use autoplay mod rather than local replay provider --- .../Mods/TestSceneOsuModDifficultyAdjust.cs | 22 ++-------- osu.Game/Tests/Visual/ModTestScene.cs | 41 ++++++++----------- osu.Game/Tests/Visual/TestReplayPlayer.cs | 24 ----------- 3 files changed, 21 insertions(+), 66 deletions(-) delete mode 100644 osu.Game/Tests/Visual/TestReplayPlayer.cs diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs index e4b1e30bcd..0a98f49526 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs @@ -3,8 +3,6 @@ using NUnit.Framework; using osu.Game.Rulesets.Osu.Mods; -using osu.Game.Rulesets.Scoring; -using osu.Game.Scoring; using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests.Mods @@ -17,11 +15,11 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods } [Test] - public void TestNoAdjustment() => CreateModTest(new ModTestData() + public void TestNoAdjustment() => CreateModTest(new ModTestData { Mod = new OsuModDifficultyAdjust(), Autoplay = true, - PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 + PassCondition = () => Player.ScoreProcessor.JudgedHits >= 2 }); [Test] @@ -29,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods { Mod = new OsuModDifficultyAdjust { CircleSize = { Value = 10 } }, Autoplay = true, - PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 + PassCondition = () => Player.ScoreProcessor.JudgedHits >= 2 }); [Test] @@ -37,19 +35,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods { Mod = new OsuModDifficultyAdjust { ApproachRate = { Value = 10 } }, Autoplay = true, - PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 + PassCondition = () => Player.ScoreProcessor.JudgedHits >= 2 }); - - protected override TestPlayer CreateReplayPlayer(Score score, bool allowFail) => new ScoreAccessibleTestPlayer(score, allowFail); - - private class ScoreAccessibleTestPlayer : TestPlayer - { - public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; - - public ScoreAccessibleTestPlayer(Score score, bool allowFail) - : base(score, allowFail) - { - } - } } } diff --git a/osu.Game/Tests/Visual/ModTestScene.cs b/osu.Game/Tests/Visual/ModTestScene.cs index 3d12001cca..9abe543bf6 100644 --- a/osu.Game/Tests/Visual/ModTestScene.cs +++ b/osu.Game/Tests/Visual/ModTestScene.cs @@ -3,13 +3,10 @@ using System; using System.Collections.Generic; -using System.Linq; using JetBrains.Annotations; using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; -using osu.Game.Scoring; -using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual { @@ -27,52 +24,48 @@ namespace osu.Game.Tests.Visual { } - private ModTestData currentTest; + private ModTestData currentTestData; protected void CreateModTest(ModTestData testData) => CreateTest(() => { - AddStep("set test data", () => currentTest = testData); + AddStep("set test data", () => currentTestData = testData); }); public override void TearDownSteps() { AddUntilStep("test passed", () => { - if (currentTest == null) + if (currentTestData == null) return true; - return currentTest.PassCondition?.Invoke() ?? false; + return currentTestData.PassCondition?.Invoke() ?? false; }); base.TearDownSteps(); } - protected sealed override IBeatmap CreateBeatmap(RulesetInfo ruleset) => currentTest?.Beatmap ?? base.CreateBeatmap(ruleset); + protected sealed override IBeatmap CreateBeatmap(RulesetInfo ruleset) => currentTestData?.Beatmap ?? base.CreateBeatmap(ruleset); - protected sealed override Player CreatePlayer(Ruleset ruleset) + protected sealed override TestPlayer CreatePlayer(Ruleset ruleset) { - SelectedMods.Value = SelectedMods.Value.Append(currentTest.Mod).ToArray(); + var mods = new List(SelectedMods.Value); - var score = currentTest.Autoplay - ? ruleset.GetAutoplayMod().CreateReplayScore(Beatmap.Value.GetPlayableBeatmap(ruleset.RulesetInfo, SelectedMods.Value)) - : null; + if (currentTestData.Mod != null) + mods.Add(currentTestData.Mod); + if (currentTestData.Autoplay) + mods.Add(ruleset.GetAutoplayMod()); - return CreateReplayPlayer(score, AllowFail); + SelectedMods.Value = mods; + + return new ModTestPlayer(AllowFail); } - /// - /// Creates the for a test case. - /// - /// The . - /// Whether the player can fail. - protected virtual TestPlayer CreateReplayPlayer(Score score, bool allowFail) => new TestPlayer(score, allowFail); - - protected class TestPlayer : TestReplayPlayer + protected class ModTestPlayer : TestPlayer { protected override bool AllowFail { get; } - public TestPlayer(Score score, bool allowFail) - : base(score, false, false) + public ModTestPlayer(bool allowFail) + : base(false, false) { AllowFail = allowFail; } diff --git a/osu.Game/Tests/Visual/TestReplayPlayer.cs b/osu.Game/Tests/Visual/TestReplayPlayer.cs deleted file mode 100644 index e99fcc1e37..0000000000 --- a/osu.Game/Tests/Visual/TestReplayPlayer.cs +++ /dev/null @@ -1,24 +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 osu.Game.Rulesets.UI; -using osu.Game.Scoring; -using osu.Game.Screens.Play; - -namespace osu.Game.Tests.Visual -{ - public class TestReplayPlayer : ReplayPlayer - { - protected override bool PauseOnFocusLost { get; } - - public new DrawableRuleset DrawableRuleset => base.DrawableRuleset; - - public new GameplayClockContainer GameplayClockContainer => base.GameplayClockContainer; - - public TestReplayPlayer(Score score, bool allowPause = true, bool showResults = true, bool pauseOnFocusLost = false) - : base(score, allowPause, showResults) - { - PauseOnFocusLost = pauseOnFocusLost; - } - } -} From 9a12909f09a377f9348a496f0e95a52c2b51cedf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 11:53:04 +0900 Subject: [PATCH 27/53] Test ModDifficultyAdjust is actually taking effect --- .../Mods/TestSceneOsuModDifficultyAdjust.cs | 51 +++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs index 0a98f49526..69415b70e3 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs @@ -1,8 +1,14 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Linq; using NUnit.Framework; +using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; +using osu.Framework.Utils; +using osu.Game.Graphics.Containers; using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests.Mods @@ -19,7 +25,15 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods { Mod = new OsuModDifficultyAdjust(), Autoplay = true, - PassCondition = () => Player.ScoreProcessor.JudgedHits >= 2 + PassCondition = checkSomeHit + }); + + [Test] + public void TestCircleSize1() => CreateModTest(new ModTestData + { + Mod = new OsuModDifficultyAdjust { CircleSize = { Value = 1 } }, + Autoplay = true, + PassCondition = () => checkSomeHit() && checkObjectsScale(0.78f) }); [Test] @@ -27,7 +41,15 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods { Mod = new OsuModDifficultyAdjust { CircleSize = { Value = 10 } }, Autoplay = true, - PassCondition = () => Player.ScoreProcessor.JudgedHits >= 2 + PassCondition = () => checkSomeHit() && checkObjectsScale(0.15f) + }); + + [Test] + public void TestApproachRate1() => CreateModTest(new ModTestData + { + Mod = new OsuModDifficultyAdjust { ApproachRate = { Value = 1 } }, + Autoplay = true, + PassCondition = () => checkSomeHit() && checkObjectsPreempt(1680) }); [Test] @@ -35,7 +57,30 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods { Mod = new OsuModDifficultyAdjust { ApproachRate = { Value = 10 } }, Autoplay = true, - PassCondition = () => Player.ScoreProcessor.JudgedHits >= 2 + PassCondition = () => checkSomeHit() && checkObjectsPreempt(450) }); + + private bool checkObjectsPreempt(double target) + { + var objects = Player.ChildrenOfType(); + if (!objects.Any()) + return false; + + return objects.All(o => o.HitObject.TimePreempt == target); + } + + private bool checkObjectsScale(float target) + { + var objects = Player.ChildrenOfType(); + if (!objects.Any()) + return false; + + return objects.All(o => Precision.AlmostEquals(o.ChildrenOfType().First().Children.OfType().Single().Scale.X, target)); + } + + private bool checkSomeHit() + { + return Player.ScoreProcessor.JudgedHits >= 2; + } } } From 7229131d369c19ac8b54ab840c125e3bc83ee9a6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 13:18:42 +0900 Subject: [PATCH 28/53] Fix song select max displayable star difficulty getting stuck at wrong maximum --- osu.Game/Configuration/OsuConfigManager.cs | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index ce959e9057..c5d68e4efe 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Bindables; using osu.Framework.Configuration; using osu.Framework.Configuration.Tracking; using osu.Framework.Extensions; @@ -126,6 +127,34 @@ namespace osu.Game.Configuration public OsuConfigManager(Storage storage) : base(storage) { + Migrate(); + } + + public void Migrate() + { + // arrives as 2020.123.0 + var rawVersion = Get(OsuSetting.Version); + + if (rawVersion.Length < 6) + return; + + var pieces = rawVersion.Split('.'); + + if (!int.TryParse(pieces[0], out int year)) return; + if (!int.TryParse(pieces[1], out int monthDay)) return; + if (!int.TryParse(pieces[2], out int minor)) return; + + int combined = (year * 10000) + monthDay; + + if (combined < 20200305) + { + // the maximum value of this setting was changed. + // if we don't manually increase this, it causes song select to filter out beatmaps the user expects to see. + var maxStars = (BindableDouble)GetOriginalBindable(OsuSetting.DisplayStarsMaximum); + + if (maxStars.Value == 10) + maxStars.Value = maxStars.MaxValue; + } } public override TrackedSettings CreateTrackedSettings() => new TrackedSettings From 6477a7b73e1d7ede6f77cfb76b15e63d1be20bdb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 13:34:04 +0900 Subject: [PATCH 29/53] Centralise creation of UpdateManagers --- osu.Android/OsuGameAndroid.cs | 7 +------ osu.Desktop/OsuGameDesktop.cs | 19 ++++++++++++------- osu.Game/OsuGame.cs | 4 ++++ osu.iOS/OsuGameIOS.cs | 7 ------- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/osu.Android/OsuGameAndroid.cs b/osu.Android/OsuGameAndroid.cs index a91c010809..84f215f930 100644 --- a/osu.Android/OsuGameAndroid.cs +++ b/osu.Android/OsuGameAndroid.cs @@ -30,11 +30,6 @@ namespace osu.Android } } - protected override void LoadComplete() - { - base.LoadComplete(); - - Add(new SimpleUpdateManager()); - } + protected override UpdateManager CreateUpdateManager() => new SimpleUpdateManager(); } } \ No newline at end of file diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index f70cc24159..f05ee48914 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -47,20 +47,25 @@ namespace osu.Desktop return null; } + protected override UpdateManager CreateUpdateManager() + { + switch (RuntimeInfo.OS) + { + case RuntimeInfo.Platform.Windows: + return new SquirrelUpdateManager(); + + default: + return new SimpleUpdateManager(); + } + } + protected override void LoadComplete() { base.LoadComplete(); if (!noVersionOverlay) - { LoadComponentAsync(versionManager = new VersionManager { Depth = int.MinValue }, Add); - if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows) - Add(new SquirrelUpdateManager()); - else - Add(new SimpleUpdateManager()); - } - LoadComponentAsync(new DiscordRichPresence(), Add); } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 5781a7fbc4..916464ff53 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -43,6 +43,7 @@ using osu.Game.Overlays.Volume; using osu.Game.Rulesets.Mods; using osu.Game.Scoring; using osu.Game.Screens.Select; +using osu.Game.Updater; using osu.Game.Utils; using LogLevel = osu.Framework.Logging.LogLevel; @@ -390,6 +391,8 @@ namespace osu.Game protected virtual Loader CreateLoader() => new Loader(); + protected virtual UpdateManager CreateUpdateManager() => new UpdateManager(); + protected override Container CreateScalingContainer() => new ScalingContainer(ScalingMode.Everything); #region Beatmap progression @@ -528,6 +531,7 @@ namespace osu.Game AddRange(new Drawable[] { + CreateUpdateManager(), new VolumeControlReceptor { RelativeSizeAxes = Axes.Both, diff --git a/osu.iOS/OsuGameIOS.cs b/osu.iOS/OsuGameIOS.cs index e5ff4aec95..3a16f81530 100644 --- a/osu.iOS/OsuGameIOS.cs +++ b/osu.iOS/OsuGameIOS.cs @@ -11,12 +11,5 @@ namespace osu.iOS public class OsuGameIOS : OsuGame { public override Version AssemblyVersion => new Version(NSBundle.MainBundle.InfoDictionary["CFBundleVersion"].ToString()); - - protected override void LoadComplete() - { - base.LoadComplete(); - - Add(new UpdateManager()); - } } } From 74b5e76c0ebec3360fb998f4743e461329a12083 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 13:39:55 +0900 Subject: [PATCH 30/53] Fix dependency initialisation ordering --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 916464ff53..50aefb4dd2 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -531,7 +531,6 @@ namespace osu.Game AddRange(new Drawable[] { - CreateUpdateManager(), new VolumeControlReceptor { RelativeSizeAxes = Axes.Both, @@ -632,6 +631,7 @@ namespace osu.Game chatOverlay.State.ValueChanged += state => channelManager.HighPollRate.Value = state.NewValue == Visibility.Visible; Add(externalLinkOpener = new ExternalLinkOpener()); + Add(CreateUpdateManager()); // dependency on notification overlay // side overlays which cancel each other. var singleDisplaySideOverlays = new OverlayContainer[] { Settings, notifications }; From 1e6710020e3adc3da750730ab6f66802dc50488f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 13:46:25 +0900 Subject: [PATCH 31/53] Remove minor version for now --- osu.Game/Configuration/OsuConfigManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index c5d68e4efe..5b20700086 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -142,7 +142,6 @@ namespace osu.Game.Configuration if (!int.TryParse(pieces[0], out int year)) return; if (!int.TryParse(pieces[1], out int monthDay)) return; - if (!int.TryParse(pieces[2], out int minor)) return; int combined = (year * 10000) + monthDay; From 1e1e8cbcb5915ad1d0db77d34926ebc54d0218aa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 14:46:38 +0900 Subject: [PATCH 32/53] Always update version --- osu.Game/Updater/UpdateManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Updater/UpdateManager.cs b/osu.Game/Updater/UpdateManager.cs index 48505a9891..f7a7795d9b 100644 --- a/osu.Game/Updater/UpdateManager.cs +++ b/osu.Game/Updater/UpdateManager.cs @@ -34,12 +34,12 @@ namespace osu.Game.Updater if (game.IsDeployedBuild && version != lastVersion) { - config.Set(OsuSetting.Version, version); - // only show a notification if we've previously saved a version to the config file (ie. not the first run). if (!string.IsNullOrEmpty(lastVersion)) Notifications.Post(new UpdateCompleteNotification(version)); } + + config.Set(OsuSetting.Version, version); } private class UpdateCompleteNotification : SimpleNotification From a311ace62656d854b8136c93ad7f7dcb91e1e9ce Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 14:46:07 +0900 Subject: [PATCH 33/53] Add migration test --- .../Visual/Navigation/OsuGameTestScene.cs | 23 +++++++---- .../Navigation/TestSettingsMigration.cs | 41 +++++++++++++++++++ osu.Game/OsuGameBase.cs | 2 +- osu.Game/Tests/Visual/OsuTestScene.cs | 2 +- 4 files changed, 58 insertions(+), 10 deletions(-) create mode 100644 osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs diff --git a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs index 70d71d0952..b0bfb64d61 100644 --- a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs +++ b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs @@ -62,14 +62,7 @@ namespace osu.Game.Tests.Visual.Navigation var frameworkConfig = host.Dependencies.Get(); frameworkConfig.GetBindable(FrameworkSetting.CursorSensitivity).Disabled = false; - Game = new TestOsuGame(LocalStorage, API); - Game.SetHost(host); - - // todo: this can be removed once we can run audio tracks without a device present - // see https://github.com/ppy/osu/issues/1302 - Game.LocalConfig.Set(OsuSetting.IntroSequence, IntroSequence.Circles); - - Add(Game); + CreateGame(); }); AddUntilStep("Wait for load", () => Game.IsLoaded); @@ -78,6 +71,18 @@ namespace osu.Game.Tests.Visual.Navigation ConfirmAtMainMenu(); } + protected void CreateGame() + { + Game = new TestOsuGame(LocalStorage, API); + Game.SetHost(host); + + // todo: this can be removed once we can run audio tracks without a device present + // see https://github.com/ppy/osu/issues/1302 + Game.LocalConfig.Set(OsuSetting.IntroSequence, IntroSequence.Circles); + + Add(Game); + } + protected void PushAndConfirm(Func newScreen) { Screen screen = null; @@ -103,6 +108,8 @@ namespace osu.Game.Tests.Visual.Navigation public new Bindable Ruleset => base.Ruleset; + public override string Version => "test game"; + protected override Loader CreateLoader() => new TestLoader(); public new void PerformFromScreen(Action action, IEnumerable validScreens = null) => base.PerformFromScreen(action, validScreens); diff --git a/osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs b/osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs new file mode 100644 index 0000000000..c0b77b580e --- /dev/null +++ b/osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs @@ -0,0 +1,41 @@ +// 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.Utils; +using osu.Game.Configuration; + +namespace osu.Game.Tests.Visual.Navigation +{ + public class TestSettingsMigration : OsuGameTestScene + { + public override void RecycleLocalStorage() + { + base.RecycleLocalStorage(); + + using (var config = new OsuConfigManager(LocalStorage)) + { + config.Set(OsuSetting.Version, "2020.101.0"); + config.Set(OsuSetting.DisplayStarsMaximum, 10.0); + } + } + + [Test] + public void TestDisplayStarsMigration() + { + AddAssert("config has migrated value", () => Precision.AlmostEquals(Game.LocalConfig.Get(OsuSetting.DisplayStarsMaximum), 10.1)); + + AddStep("set value again", () => Game.LocalConfig.Set(OsuSetting.DisplayStarsMaximum, 10)); + + AddStep("force save config", () => Game.LocalConfig.Save()); + + AddStep("remove game", () => Remove(Game)); + + AddStep("create game again", CreateGame); + + AddUntilStep("Wait for load", () => Game.IsLoaded); + + AddAssert("config did not migrate value", () => Precision.AlmostEquals(Game.LocalConfig.Get(OsuSetting.DisplayStarsMaximum), 10)); + } + } +} diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index a890331f05..33333e592e 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -97,7 +97,7 @@ namespace osu.Game public bool IsDeployedBuild => AssemblyVersion.Major > 0; - public string Version + public virtual string Version { get { diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index b203557fab..f102e2ece3 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -104,7 +104,7 @@ namespace osu.Game.Tests.Visual base.Content.Add(content = new DrawSizePreservingFillContainer()); } - public void RecycleLocalStorage() + public virtual void RecycleLocalStorage() { if (localStorage?.IsValueCreated == true) { From 507af4fa72cb9c7e98733eb5925198ab4caac756 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 15:35:27 +0900 Subject: [PATCH 34/53] Add comment about rationale behind always updating version in config --- osu.Game/Updater/UpdateManager.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Updater/UpdateManager.cs b/osu.Game/Updater/UpdateManager.cs index f7a7795d9b..28a295215f 100644 --- a/osu.Game/Updater/UpdateManager.cs +++ b/osu.Game/Updater/UpdateManager.cs @@ -39,6 +39,8 @@ namespace osu.Game.Updater Notifications.Post(new UpdateCompleteNotification(version)); } + // debug / local compilations will reset to a non-release string. + // can be useful to check when an install has transitioned between release and otherwise (see OsuConfigManager's migrations). config.Set(OsuSetting.Version, version); } From 5b8037ea7d2b69e29ae82eb54aba16e2bd07efe9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 15:36:36 +0900 Subject: [PATCH 35/53] Add note about early migration return on non-release transitions --- osu.Game/Configuration/OsuConfigManager.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 5b20700086..21de654670 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -140,6 +140,8 @@ namespace osu.Game.Configuration var pieces = rawVersion.Split('.'); + // on a fresh install or when coming from a non-release build, execution will end here. + // we don't want to run migrations in such cases. if (!int.TryParse(pieces[0], out int year)) return; if (!int.TryParse(pieces[1], out int monthDay)) return; From 646c8fe077eca5b6630b397e38fc5b3c6330e7ac Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 15:40:48 +0900 Subject: [PATCH 36/53] Add note about version override --- osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs index b0bfb64d61..ea8a06e990 100644 --- a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs +++ b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs @@ -108,6 +108,7 @@ namespace osu.Game.Tests.Visual.Navigation public new Bindable Ruleset => base.Ruleset; + // if we don't do this, when running under nUnit the version that gets populated is that of nUnit. public override string Version => "test game"; protected override Loader CreateLoader() => new TestLoader(); From 9307caa3bfb60e7636033fe78311549da1653487 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Mar 2020 16:58:07 +0900 Subject: [PATCH 37/53] Fix typos --- osu.Game/OsuGame.cs | 2 +- osu.Game/OsuGameBase.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 0be9e6cdaa..e54bbaabb2 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -410,7 +410,7 @@ namespace osu.Game void trackCompleted(WorkingBeatmap b) { - // the source of track completion is the audio thread, so the beatmap may have changed before a firing. + // the source of track completion is the audio thread, so the beatmap may have changed before firing. if (Beatmap.Value != b) return; diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 67aa4a8d4d..1048b37348 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -214,7 +214,7 @@ namespace osu.Game // ScheduleAfterChildren is safety against something in the current frame accessing the previous beatmap's track // and potentially causing a reload of it after just unloading. - // Note that the reason for this being added *has* been resolved, so it may be feasible to remover this if required. + // Note that the reason for this being added *has* been resolved, so it may be feasible to removed this if required. Beatmap.BindValueChanged(b => ScheduleAfterChildren(() => { // compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo) From 0c1775b52281517e8f6f0518fc930b42b0f26aca Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Mar 2020 17:12:14 +0900 Subject: [PATCH 38/53] Fix incorrect condition and add test --- .../Visual/Navigation/OsuGameTestScene.cs | 2 ++ .../Navigation/TestSceneScreenNavigation.cs | 16 ++++++++++++++++ osu.Game/OsuGame.cs | 10 +++++----- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs index 70d71d0952..e984806dc9 100644 --- a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs +++ b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs @@ -97,6 +97,8 @@ namespace osu.Game.Tests.Visual.Navigation public new SettingsPanel Settings => base.Settings; + public new MusicController MusicController => base.MusicController; + public new OsuConfigManager LocalConfig => base.LocalConfig; public new Bindable Beatmap => base.Beatmap; diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 8258cc9465..9d603ac471 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -114,6 +114,22 @@ namespace osu.Game.Tests.Visual.Navigation AddAssert("Options overlay was closed", () => Game.Settings.State.Value == Visibility.Hidden); } + [Test] + public void TestWaitForNextTrackInMenu() + { + bool trackCompleted = false; + + AddUntilStep("Wait for music controller", () => Game.MusicController.IsLoaded); + AddStep("Seek close to end", () => + { + Game.MusicController.SeekTo(Game.Beatmap.Value.Track.Length - 1000); + Game.Beatmap.Value.Track.Completed += () => trackCompleted = true; + }); + + AddUntilStep("Track was completed", () => trackCompleted); + AddUntilStep("Track was restarted", () => Game.Beatmap.Value.Track.IsRunning); + } + private void pushEscape() => AddStep("Press escape", () => pressAndRelease(Key.Escape)); diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index e54bbaabb2..19602d524e 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -414,8 +414,8 @@ namespace osu.Game if (Beatmap.Value != b) return; - if (Beatmap.Value.Track.Looping && !Beatmap.Disabled) - musicController.NextTrack(); + if (!Beatmap.Value.Track.Looping && !Beatmap.Disabled) + MusicController.NextTrack(); } } @@ -588,7 +588,7 @@ namespace osu.Game loadComponentSingleFile(new OnScreenDisplay(), Add, true); - loadComponentSingleFile(musicController = new MusicController(), Add, true); + loadComponentSingleFile(MusicController = new MusicController(), Add, true); loadComponentSingleFile(notifications = new NotificationOverlay { @@ -896,7 +896,7 @@ namespace osu.Game private ScalingContainer screenContainer; - private MusicController musicController; + protected MusicController MusicController { get; private set; } protected override bool OnExiting() { @@ -954,7 +954,7 @@ namespace osu.Game { OverlayActivationMode.Value = newOsuScreen.InitialOverlayActivationMode; - musicController.AllowRateAdjustments = newOsuScreen.AllowRateAdjustments; + MusicController.AllowRateAdjustments = newOsuScreen.AllowRateAdjustments; if (newOsuScreen.HideOverlaysOnEnter) CloseAllOverlays(); From 583e2c3f4a616fea8d2b9abc7065135e917217d3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Mar 2020 00:10:05 +0900 Subject: [PATCH 39/53] Actually check rate is applied --- .../Mods/TestSceneOsuModDoubleTime.cs | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDoubleTime.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDoubleTime.cs index deb733c581..dcf19ad993 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDoubleTime.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDoubleTime.cs @@ -2,14 +2,13 @@ // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; +using osu.Framework.Utils; using osu.Game.Rulesets.Osu.Mods; -using osu.Game.Rulesets.Scoring; -using osu.Game.Scoring; using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests.Mods { - public class TestSceneOsuModDoubleTime : ModSandboxTestScene + public class TestSceneOsuModDoubleTime : ModTestScene { public TestSceneOsuModDoubleTime() : base(new OsuRuleset()) @@ -21,21 +20,16 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods [TestCase(1.5)] [TestCase(2)] [TestCase(5)] - public void TestDefaultRate(double rate) => CreateModTest(new ModTestCaseData("1.5x", new OsuModDoubleTime { SpeedChange = { Value = rate } }) + public void TestSpeedChangeCustomisation(double rate) { - PassCondition = () => ((ScoreAccessibleTestPlayer)Player).ScoreProcessor.JudgedHits >= 2 - }); + var mod = new OsuModDoubleTime { SpeedChange = { Value = rate } }; - protected override TestPlayer CreateReplayPlayer(Score score) => new ScoreAccessibleTestPlayer(score); - - private class ScoreAccessibleTestPlayer : TestPlayer - { - public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; - - public ScoreAccessibleTestPlayer(Score score) - : base(score) + CreateModTest(new ModTestData { - } + Mod = mod, + PassCondition = () => Player.ScoreProcessor.JudgedHits >= 2 && + Precision.AlmostEquals(Player.GameplayClockContainer.GameplayClock.Rate, mod.SpeedChange.Value) + }); } } } From e3509c742c4ec1bb9df56d4a3c1f733ad4587f58 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Mar 2020 01:28:59 +0900 Subject: [PATCH 40/53] Track time in a simpler way in TrackVirtualManual --- osu.Game/Tests/Visual/OsuTestScene.cs | 47 ++++++++++++++++++++------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index 917d12ebb1..3c95b990e1 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -229,10 +229,10 @@ namespace osu.Game.Tests.Visual /// public class TrackVirtualManual : Track { - private readonly StopwatchClock stopwatchClock = new StopwatchClock(); - private readonly IFrameBasedClock referenceClock; + private bool running; + public TrackVirtualManual(IFrameBasedClock referenceClock) { this.referenceClock = referenceClock; @@ -241,32 +241,55 @@ namespace osu.Game.Tests.Visual public override bool Seek(double seek) { - var offset = Math.Clamp(seek, 0, Length); + accumulated = Math.Min(seek, Length); + lastReferenceTime = null; - stopwatchClock.Seek(offset); - - return offset == seek; + return accumulated == seek; } - public override void Start() => stopwatchClock.Start(); + public override void Start() + { + running = true; + } public override void Reset() { - stopwatchClock.Seek(0); + Seek(0); base.Reset(); } - public override void Stop() => stopwatchClock.Stop(); + public override void Stop() + { + if (running) + { + running = false; + lastReferenceTime = null; + } + } - public override bool IsRunning => stopwatchClock.IsRunning; + public override bool IsRunning => running; - public override double CurrentTime => stopwatchClock.CurrentTime; + private double? lastReferenceTime; + + private double accumulated; + + public override double CurrentTime => Math.Min(accumulated, Length); protected override void UpdateState() { base.UpdateState(); - stopwatchClock.Rate = Rate * referenceClock.Rate; + if (running) + { + double refTime = referenceClock.CurrentTime; + + if (lastReferenceTime.HasValue) + accumulated += (refTime - lastReferenceTime.Value) * Rate; + + lastReferenceTime = refTime; + } + + Console.WriteLine($"t={CurrentTime}"); if (CurrentTime >= Length) { From ebc86c10754ede8686e06b06682c272ff117b562 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Mar 2020 02:08:49 +0900 Subject: [PATCH 41/53] Fix random test failure --- osu.Game/Screens/Play/SkipOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/SkipOverlay.cs b/osu.Game/Screens/Play/SkipOverlay.cs index 3daf5b1ff1..ac7e509c2c 100644 --- a/osu.Game/Screens/Play/SkipOverlay.cs +++ b/osu.Game/Screens/Play/SkipOverlay.cs @@ -116,7 +116,7 @@ namespace osu.Game.Screens.Play { base.Update(); - var progress = Math.Max(0, 1 - (gameplayClock.CurrentTime - displayTime) / (fadeOutBeginTime - displayTime)); + var progress = fadeOutBeginTime <= displayTime ? 1 : Math.Max(0, 1 - (gameplayClock.CurrentTime - displayTime) / (fadeOutBeginTime - displayTime)); remainingTimeBox.Width = (float)Interpolation.Lerp(remainingTimeBox.Width, progress, Math.Clamp(Time.Elapsed / 40, 0, 1)); From c3ad08f230b635f4dcc8582c5ee2028f04cd25c8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Mar 2020 02:18:35 +0900 Subject: [PATCH 42/53] Remove wild writeline --- osu.Game/Tests/Visual/OsuTestScene.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index 3c95b990e1..5623435da4 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -289,8 +289,6 @@ namespace osu.Game.Tests.Visual lastReferenceTime = refTime; } - Console.WriteLine($"t={CurrentTime}"); - if (CurrentTime >= Length) { Stop(); From ac88ba717b7f6589b01950ac915a4801eac4a007 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Mar 2020 16:03:26 +0900 Subject: [PATCH 43/53] Ensure screens respect aspect ratio in tests --- osu.Game.Tournament/Screens/TournamentScreen.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game.Tournament/Screens/TournamentScreen.cs b/osu.Game.Tournament/Screens/TournamentScreen.cs index 0b5b3e728b..5da7c7a5d2 100644 --- a/osu.Game.Tournament/Screens/TournamentScreen.cs +++ b/osu.Game.Tournament/Screens/TournamentScreen.cs @@ -18,6 +18,9 @@ namespace osu.Game.Tournament.Screens protected TournamentScreen() { RelativeSizeAxes = Axes.Both; + + FillMode = FillMode.Fit; + FillAspectRatio = 16 / 9f; } public override void Hide() => this.FadeOut(FADE_DELAY); From 8ff3370273fb9c857e0117bab3235b6408caf6c7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Mar 2020 16:27:38 +0900 Subject: [PATCH 44/53] Add a short load delay for avatars to avoid unnecessary fetching --- osu.Game/Users/Drawables/UpdateableAvatar.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Users/Drawables/UpdateableAvatar.cs b/osu.Game/Users/Drawables/UpdateableAvatar.cs index 59fbb5f910..171462f3fc 100644 --- a/osu.Game/Users/Drawables/UpdateableAvatar.cs +++ b/osu.Game/Users/Drawables/UpdateableAvatar.cs @@ -43,6 +43,8 @@ namespace osu.Game.Users.Drawables set => base.EdgeEffect = value; } + protected override double LoadDelay => 200; + /// /// Whether to show a default guest representation on null user (as opposed to nothing). /// From 88759e65a0b2702defc8e036561ad2d18fbb02dc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Mar 2020 16:31:36 +0900 Subject: [PATCH 45/53] Remove layout durations from tournament editor screns for better performance --- osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs | 2 -- osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs | 2 -- osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs | 2 -- osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs | 2 -- 4 files changed, 8 deletions(-) diff --git a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs index 7119533743..8b8078e119 100644 --- a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs @@ -129,8 +129,6 @@ namespace osu.Game.Tournament.Screens.Editors RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, - LayoutDuration = 200, - LayoutEasing = Easing.OutQuint, ChildrenEnumerable = round.Beatmaps.Select(p => new RoundBeatmapRow(round, p)) }; } diff --git a/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs index e68946aaf2..46bb7b83e3 100644 --- a/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs @@ -124,8 +124,6 @@ namespace osu.Game.Tournament.Screens.Editors RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, - LayoutDuration = 200, - LayoutEasing = Easing.OutQuint, ChildrenEnumerable = round.Beatmaps.Select(p => new SeedingBeatmapRow(round, p)) }; } diff --git a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs index ca8bce1cca..631393c6f4 100644 --- a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs @@ -202,8 +202,6 @@ namespace osu.Game.Tournament.Screens.Editors RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, - LayoutDuration = 200, - LayoutEasing = Easing.OutQuint, ChildrenEnumerable = team.Players.Select(p => new PlayerRow(team, p)) }; } diff --git a/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs index 5598910824..e4256e727d 100644 --- a/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs @@ -48,8 +48,6 @@ namespace osu.Game.Tournament.Screens.Editors Direction = FillDirection.Vertical, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - LayoutDuration = 200, - LayoutEasing = Easing.OutQuint, Spacing = new Vector2(20) }, }, From 40074f10dbd5999dca3f38dc0a6de093c28de463 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Mar 2020 17:55:05 +0900 Subject: [PATCH 46/53] Remove unnecessary override --- osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs index 9140cccafd..2a8f77210a 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs @@ -32,12 +32,5 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("rewind", () => Player.GameplayClockContainer.Seek(-80000)); AddUntilStep("key counter reset", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0)); } - - protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) - { - var working = base.CreateWorkingBeatmap(beatmap, storyboard); - - return working; - } } } From 3b0e3cd71a3ae257ec3f21f774c1ba2c63cf8e53 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Mar 2020 17:55:57 +0900 Subject: [PATCH 47/53] Remove using statements --- osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs index 2a8f77210a..afeda5fb7c 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs @@ -3,10 +3,8 @@ using System.ComponentModel; using System.Linq; -using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Screens.Play; -using osu.Game.Storyboards; namespace osu.Game.Tests.Visual.Gameplay { From 0ccf691c972f3de8253c357b101e2f5c8ba5e93d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Mar 2020 18:00:07 +0900 Subject: [PATCH 48/53] Remove unnecessary interpolation --- osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs index 10827bc0b9..227ada70fe 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs @@ -60,7 +60,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses == 1); addPressKeyStep(); AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses == 2); - AddStep($"Disable counting", () => testCounter.IsCounting = false); + AddStep("Disable counting", () => testCounter.IsCounting = false); addPressKeyStep(); AddAssert($"Check {testKey} count has not changed", () => testCounter.CountPresses == 2); From a59c3d997da57bcfa33e2f3342222ccaa825d674 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Mar 2020 18:00:17 +0900 Subject: [PATCH 49/53] Refactor implementation to better match what already existed --- osu.Game/Screens/Play/Player.cs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 2d49c707ec..bcadba14af 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -157,10 +157,7 @@ namespace osu.Game.Screens.Play addGameplayComponents(GameplayClockContainer, Beatmap.Value); addOverlayComponents(GameplayClockContainer, Beatmap.Value); - DrawableRuleset.HasReplayLoaded.BindValueChanged(e => - { - updatePauseOnFocusLostState(e.NewValue, BreakOverlay.IsBreakTime.Value); - }, true); + DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true); // bind clock into components that require it DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused); @@ -232,7 +229,11 @@ namespace osu.Game.Screens.Play IsPaused = { BindTarget = GameplayClockContainer.IsPaused } }, PlayerSettingsOverlay = { PlaybackSettings = { UserPlaybackRate = { BindTarget = GameplayClockContainer.UserPlaybackRate } } }, - KeyCounter = { AlwaysVisible = { BindTarget = DrawableRuleset.HasReplayLoaded }, IsCounting = false }, + KeyCounter = + { + AlwaysVisible = { BindTarget = DrawableRuleset.HasReplayLoaded }, + IsCounting = false + }, RequestSeek = GameplayClockContainer.Seek, Anchor = Anchor.Centre, Origin = Anchor.Centre @@ -289,16 +290,16 @@ namespace osu.Game.Screens.Play HealthProcessor.IsBreakTime.BindTo(BreakOverlay.IsBreakTime); } - private void onBreakTimeChanged(ValueChangedEvent changeEvent) + private void onBreakTimeChanged(ValueChangedEvent isBreakTime) { - updatePauseOnFocusLostState(DrawableRuleset.HasReplayLoaded.Value, changeEvent.NewValue); - HUDOverlay.KeyCounter.IsCounting = !changeEvent.NewValue; + updatePauseOnFocusLostState(); + HUDOverlay.KeyCounter.IsCounting = !isBreakTime.NewValue; } - private void updatePauseOnFocusLostState(bool replayLoaded, bool isBreakTime) => + private void updatePauseOnFocusLostState() => HUDOverlay.HoldToQuit.PauseOnFocusLost = PauseOnFocusLost - && !replayLoaded - && !isBreakTime; + && !DrawableRuleset.HasReplayLoaded.Value + && !BreakOverlay.IsBreakTime.Value; private IBeatmap loadPlayableBeatmap() { From 2d95f2992534444949ebbf6a66dd53b333a94c9f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Mar 2020 16:06:23 +0900 Subject: [PATCH 50/53] Add gameplay screen specific video --- osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs index 6a3095d42d..c74302a869 100644 --- a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs +++ b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs @@ -6,6 +6,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Platform; using osu.Framework.Threading; using osu.Game.Graphics.UserInterface; using osu.Game.Tournament.Components; @@ -19,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Tournament.Screens.Gameplay { - public class GameplayScreen : BeatmapInfoScreen + public class GameplayScreen : BeatmapInfoScreen, IProvideVideo { private readonly BindableBool warmup = new BindableBool(); @@ -39,12 +40,17 @@ namespace osu.Game.Tournament.Screens.Gameplay private TournamentMatchChatDisplay chat { get; set; } [BackgroundDependencyLoader] - private void load(LadderInfo ladder, MatchIPCInfo ipc) + private void load(LadderInfo ladder, MatchIPCInfo ipc, Storage storage) { this.ipc = ipc; AddRangeInternal(new Drawable[] { + new TourneyVideo(storage.GetStream("videos/gameplay.m4v")) + { + Loop = true, + RelativeSizeAxes = Axes.Both, + }, new MatchHeader(), new Container { From 0a72fa69ab70bbb14fa7742e19a6d0075aefa21f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Mar 2020 18:38:29 +0900 Subject: [PATCH 51/53] Simplify video creation (and handle fallback better) --- .../Components/TourneyVideo.cs | 38 ++++++++++++------- .../Screens/Gameplay/GameplayScreen.cs | 2 +- .../Screens/Ladder/LadderScreen.cs | 2 +- .../Screens/Schedule/ScheduleScreen.cs | 4 +- .../Screens/TeamIntro/SeedingScreen.cs | 2 +- .../Screens/TeamIntro/TeamIntroScreen.cs | 2 +- .../Screens/TeamWin/TeamWinScreen.cs | 4 +- osu.Game.Tournament/TournamentSceneManager.cs | 2 +- 8 files changed, 34 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tournament/Components/TourneyVideo.cs b/osu.Game.Tournament/Components/TourneyVideo.cs index 206689ca1a..7d2eaff515 100644 --- a/osu.Game.Tournament/Components/TourneyVideo.cs +++ b/osu.Game.Tournament/Components/TourneyVideo.cs @@ -1,12 +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.IO; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Video; +using osu.Framework.Platform; using osu.Framework.Timing; using osu.Game.Graphics; @@ -14,21 +15,24 @@ namespace osu.Game.Tournament.Components { public class TourneyVideo : CompositeDrawable { - private readonly VideoSprite video; + private readonly string filename; + private readonly bool drawFallbackGradient; + private VideoSprite video; - private readonly ManualClock manualClock; + private ManualClock manualClock; - public TourneyVideo(Stream stream) + public TourneyVideo(string filename, bool drawFallbackGradient = false) { - if (stream == null) - { - InternalChild = new Box - { - Colour = ColourInfo.GradientVertical(OsuColour.Gray(0.3f), OsuColour.Gray(0.6f)), - RelativeSizeAxes = Axes.Both, - }; - } - else + this.filename = filename; + this.drawFallbackGradient = drawFallbackGradient; + } + + [BackgroundDependencyLoader] + private void load(Storage storage) + { + var stream = storage.GetStream($@"videos/{filename}.m4v"); + + if (stream != null) { InternalChild = video = new VideoSprite(stream) { @@ -37,6 +41,14 @@ namespace osu.Game.Tournament.Components Clock = new FramedClock(manualClock = new ManualClock()) }; } + else if (drawFallbackGradient) + { + InternalChild = new Box + { + Colour = ColourInfo.GradientVertical(OsuColour.Gray(0.3f), OsuColour.Gray(0.6f)), + RelativeSizeAxes = Axes.Both, + }; + } } public bool Loop diff --git a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs index c74302a869..d632e7c5f3 100644 --- a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs +++ b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs @@ -46,7 +46,7 @@ namespace osu.Game.Tournament.Screens.Gameplay AddRangeInternal(new Drawable[] { - new TourneyVideo(storage.GetStream("videos/gameplay.m4v")) + new TourneyVideo("gameplay") { Loop = true, RelativeSizeAxes = Axes.Both, diff --git a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs index 293f6e0068..7b265ded32 100644 --- a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs +++ b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs @@ -42,7 +42,7 @@ namespace osu.Game.Tournament.Screens.Ladder RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - new TourneyVideo(storage.GetStream(@"videos/ladder.m4v")) + new TourneyVideo("ladder") { RelativeSizeAxes = Axes.Both, Loop = true, diff --git a/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs b/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs index 080570eac4..4c93c04fcf 100644 --- a/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs +++ b/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Tournament.Screens.Schedule { - public class ScheduleScreen : TournamentScreen, IProvideVideo + public class ScheduleScreen : TournamentScreen { private readonly Bindable currentMatch = new Bindable(); private Container mainContainer; @@ -33,7 +33,7 @@ namespace osu.Game.Tournament.Screens.Schedule InternalChildren = new Drawable[] { - new TourneyVideo(storage.GetStream(@"videos/schedule.m4v")) + new TourneyVideo("schedule") { RelativeSizeAxes = Axes.Both, Loop = true, diff --git a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs index db5363c155..513d84b594 100644 --- a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs +++ b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs @@ -34,7 +34,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro InternalChildren = new Drawable[] { - new TourneyVideo(storage.GetStream(@"videos/seeding.m4v")) + new TourneyVideo("seeding") { RelativeSizeAxes = Axes.Both, Loop = true, diff --git a/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs index 6559113f55..d584c21058 100644 --- a/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs +++ b/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs @@ -26,7 +26,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro InternalChildren = new Drawable[] { - new TourneyVideo(storage.GetStream(@"videos/teamintro.m4v")) + new TourneyVideo("teamintro") { RelativeSizeAxes = Axes.Both, Loop = true, diff --git a/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs b/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs index 30b86f8421..1765ab7ba2 100644 --- a/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs +++ b/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs @@ -31,13 +31,13 @@ namespace osu.Game.Tournament.Screens.TeamWin InternalChildren = new Drawable[] { - blueWinVideo = new TourneyVideo(storage.GetStream(@"videos/teamwin-blue.m4v")) + blueWinVideo = new TourneyVideo("teamwin-blue") { Alpha = 1, RelativeSizeAxes = Axes.Both, Loop = true, }, - redWinVideo = new TourneyVideo(storage.GetStream(@"videos/teamwin-red.m4v")) + redWinVideo = new TourneyVideo("teamwin-red") { Alpha = 0, RelativeSizeAxes = Axes.Both, diff --git a/osu.Game.Tournament/TournamentSceneManager.cs b/osu.Game.Tournament/TournamentSceneManager.cs index 9f5f2b6827..287e25b1fb 100644 --- a/osu.Game.Tournament/TournamentSceneManager.cs +++ b/osu.Game.Tournament/TournamentSceneManager.cs @@ -61,7 +61,7 @@ namespace osu.Game.Tournament //Masking = true, Children = new Drawable[] { - video = new TourneyVideo(storage.GetStream("videos/main.m4v")) + video = new TourneyVideo("main", true) { Loop = true, RelativeSizeAxes = Axes.Both, From 16cc49daa00d3c4af18130162ccee7f74a1bf098 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Mar 2020 18:47:31 +0900 Subject: [PATCH 52/53] 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 1c4a6ffe75..97f7a7edb1 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 4d59b709aa..855bda3679 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 6897d3e625..e2c4c09047 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -71,7 +71,7 @@ - + @@ -79,7 +79,7 @@ - + From 3295f8657ac3d74a95c10016273068fbbdedde26 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Mar 2020 22:44:11 +0900 Subject: [PATCH 53/53] Restore clamp behaviour --- osu.Game/Tests/Visual/OsuTestScene.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index 5623435da4..d1d8059cb1 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -241,7 +241,7 @@ namespace osu.Game.Tests.Visual public override bool Seek(double seek) { - accumulated = Math.Min(seek, Length); + accumulated = Math.Clamp(seek, 0, Length); lastReferenceTime = null; return accumulated == seek;