From e14a35b469de3841c3d573758b9a5266d99abb93 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 2 Mar 2022 20:32:03 +0300 Subject: [PATCH 1/8] Add failing test case --- .../Gameplay/TestSceneStoryboardSamples.cs | 59 ------------- .../TestSceneStoryboardSamplePlayback.cs | 83 +++++++++++++++++-- osu.Game/Tests/Visual/TestPlayer.cs | 3 - 3 files changed, 78 insertions(+), 67 deletions(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index 88862ea28b..6457a23a1b 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -1,29 +1,23 @@ // 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.IO; -using System.Linq; using System.Threading; using System.Threading.Tasks; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; -using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; using osu.Framework.Testing; -using osu.Framework.Utils; using osu.Game.Audio; using osu.Game.Configuration; using osu.Game.Database; using osu.Game.IO; using osu.Game.Rulesets; -using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; -using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.UI; using osu.Game.Screens.Play; using osu.Game.Skinning; @@ -118,59 +112,6 @@ namespace osu.Game.Tests.Gameplay AddUntilStep("sample has lifetime end", () => sample.LifetimeEnd < double.MaxValue); } - [TestCase(typeof(OsuModDoubleTime), 1.5)] - [TestCase(typeof(OsuModHalfTime), 0.75)] - [TestCase(typeof(ModWindUp), 1.5)] - [TestCase(typeof(ModWindDown), 0.75)] - [TestCase(typeof(OsuModDoubleTime), 2)] - [TestCase(typeof(OsuModHalfTime), 0.5)] - [TestCase(typeof(ModWindUp), 2)] - [TestCase(typeof(ModWindDown), 0.5)] - public void TestSamplePlaybackWithRateMods(Type expectedMod, double expectedRate) - { - GameplayClockContainer gameplayContainer = null; - StoryboardSampleInfo sampleInfo = null; - TestDrawableStoryboardSample sample = null; - - Mod testedMod = Activator.CreateInstance(expectedMod) as Mod; - - switch (testedMod) - { - case ModRateAdjust m: - m.SpeedChange.Value = expectedRate; - break; - - case ModTimeRamp m: - m.FinalRate.Value = m.InitialRate.Value = expectedRate; - break; - } - - AddStep("setup storyboard sample", () => - { - Beatmap.Value = new TestCustomSkinWorkingBeatmap(new OsuRuleset().RulesetInfo, this); - SelectedMods.Value = new[] { testedMod }; - - var beatmapSkinSourceContainer = new BeatmapSkinProvidingContainer(Beatmap.Value.Skin); - - Add(gameplayContainer = new MasterGameplayClockContainer(Beatmap.Value, 0) - { - Child = beatmapSkinSourceContainer - }); - - beatmapSkinSourceContainer.Add(sample = new TestDrawableStoryboardSample(sampleInfo = new StoryboardSampleInfo("test-sample", 1, 1)) - { - Clock = gameplayContainer.GameplayClock - }); - }); - - AddStep("start", () => gameplayContainer.Start()); - - AddAssert("sample playback rate matches mod rates", () => - testedMod != null && Precision.AlmostEquals( - sample.ChildrenOfType().First().AggregateFrequency.Value, - ((IApplicableToRate)testedMod).ApplyToRate(sampleInfo.StartTime))); - } - [Test] public void TestSamplePlaybackWithBeatmapHitsoundsOff() { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs index 95603b5c04..7a74a00c68 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs @@ -1,17 +1,23 @@ // 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.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; +using osu.Framework.Graphics.Audio; using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Osu.Mods; using osu.Game.Storyboards; using osu.Game.Storyboards.Drawables; +using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { @@ -19,6 +25,10 @@ namespace osu.Game.Tests.Visual.Gameplay { private Storyboard storyboard; + private IReadOnlyList storyboardMods; + + protected override bool HasCustomSteps => true; + [BackgroundDependencyLoader] private void load(OsuConfigManager config) { @@ -31,10 +41,13 @@ namespace osu.Game.Tests.Visual.Gameplay backgroundLayer.Add(new StoryboardSampleInfo("Intro/welcome.mp3", time: 0, volume: 20)); } + [SetUp] + public void SetUp() => Schedule(() => storyboardMods = Array.Empty()); + [Test] public void TestStoryboardSamplesStopDuringPause() { - checkForFirstSamplePlayback(); + createPlayerTest(); AddStep("player paused", () => Player.Pause()); AddAssert("player is currently paused", () => Player.GameplayClockContainer.IsPaused.Value); @@ -47,26 +60,86 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestStoryboardSamplesStopOnSkip() { - checkForFirstSamplePlayback(); + createPlayerTest(true); - AddStep("skip intro", () => InputManager.Key(osuTK.Input.Key.Space)); AddAssert("all storyboard samples stopped immediately", () => allStoryboardSamples.All(sound => !sound.IsPlaying)); AddUntilStep("any storyboard samples playing after skip", () => allStoryboardSamples.Any(sound => sound.IsPlaying)); } - private void checkForFirstSamplePlayback() + [TestCase(typeof(OsuModDoubleTime), 1.5)] + [TestCase(typeof(OsuModDoubleTime), 2)] + [TestCase(typeof(OsuModHalfTime), 0.75)] + [TestCase(typeof(OsuModHalfTime), 0.5)] + public void TestStoryboardSamplesPlaybackWithRateAdjustMods(Type expectedMod, double expectedRate) { + AddStep("setup mod", () => + { + ModRateAdjust testedMod = (ModRateAdjust)Activator.CreateInstance(expectedMod).AsNonNull(); + testedMod.SpeedChange.Value = expectedRate; + storyboardMods = new[] { testedMod }; + }); + + createPlayerTest(true); + + AddAssert("sample playback rate matches mod rates", () => allStoryboardSamples.All(sound => + { + return sound.ChildrenOfType().All(s => s.AggregateFrequency.Value == expectedRate); + })); + } + + [TestCase(typeof(ModWindUp), 0.5, 2)] + [TestCase(typeof(ModWindUp), 1.51, 2)] + [TestCase(typeof(ModWindDown), 2, 0.5)] + [TestCase(typeof(ModWindDown), 0.99, 0.5)] + public void TestStoryboardSamplesPlaybackWithTimeRampMods(Type expectedMod, double initialRate, double finalRate) + { + AddStep("setup mod", () => + { + ModTimeRamp testedMod = (ModTimeRamp)Activator.CreateInstance(expectedMod).AsNonNull(); + testedMod.InitialRate.Value = initialRate; + testedMod.FinalRate.Value = finalRate; + storyboardMods = new[] { testedMod }; + }); + + createPlayerTest(true); + + ModTimeRamp gameplayMod = null; + + AddUntilStep("mod speed change updated", () => + { + gameplayMod = Player.GameplayState.Mods.OfType().Single(); + return gameplayMod.SpeedChange.Value != initialRate; + }); + + AddAssert("sample playback rate matches mod rates", () => allStoryboardSamples.All(sound => + { + return sound.ChildrenOfType().All(s => s.AggregateFrequency.Value == gameplayMod.SpeedChange.Value); + })); + } + + private void createPlayerTest(bool skipIntro = false) + { + CreateTest(null); + AddAssert("storyboard loaded", () => Player.Beatmap.Value.Storyboard != null); AddUntilStep("any storyboard samples playing", () => allStoryboardSamples.Any(sound => sound.IsPlaying)); + + if (skipIntro) + AddStep("skip intro", () => InputManager.Key(Key.Space)); } private IEnumerable allStoryboardSamples => Player.ChildrenOfType(); protected override bool AllowFail => false; + protected override TestPlayer CreatePlayer(Ruleset ruleset) + { + SelectedMods.Value = SelectedMods.Value.Concat(storyboardMods).ToArray(); + return new TestPlayer(true, false); + } + protected override Ruleset CreatePlayerRuleset() => new OsuRuleset(); - protected override TestPlayer CreatePlayer(Ruleset ruleset) => new TestPlayer(true, false); protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) => new ClockBackedTestWorkingBeatmap(beatmap, storyboard ?? this.storyboard, Clock, Audio); diff --git a/osu.Game/Tests/Visual/TestPlayer.cs b/osu.Game/Tests/Visual/TestPlayer.cs index 368f792e28..d463905cf4 100644 --- a/osu.Game/Tests/Visual/TestPlayer.cs +++ b/osu.Game/Tests/Visual/TestPlayer.cs @@ -26,9 +26,6 @@ namespace osu.Game.Tests.Visual public new DrawableRuleset DrawableRuleset => base.DrawableRuleset; - /// - /// Mods from *player* (not OsuScreen). - /// public new Bindable> Mods => base.Mods; public new HUDOverlay HUDOverlay => base.HUDOverlay; From cbb8dc28914a4c7a8cb636ea5b58534869eea934 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 2 Mar 2022 20:33:46 +0300 Subject: [PATCH 2/8] Fix storyboard samples rate not adjusted from actual gameplay mods --- .../Visual/Gameplay/TestSceneStoryboard.cs | 4 ++-- .../Backgrounds/BeatmapBackgroundWithStoryboard.cs | 8 +++++++- osu.Game/Screens/Play/DimmableStoryboard.cs | 9 +++++++-- osu.Game/Screens/Play/Player.cs | 2 +- .../Storyboards/Drawables/DrawableStoryboard.cs | 9 ++++++++- .../Drawables/DrawableStoryboardSample.cs | 13 ++++++++----- osu.Game/Storyboards/Storyboard.cs | 5 +++-- 7 files changed, 36 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs index 3b6d02c67c..014ccb1652 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs @@ -94,7 +94,7 @@ namespace osu.Game.Tests.Visual.Gameplay var decoupledClock = new DecoupleableInterpolatingFramedClock { IsCoupled = true }; storyboardContainer.Clock = decoupledClock; - storyboard = working.Storyboard.CreateDrawable(Beatmap.Value); + storyboard = working.Storyboard.CreateDrawable(SelectedMods.Value); storyboard.Passing = false; storyboardContainer.Add(storyboard); @@ -118,7 +118,7 @@ namespace osu.Game.Tests.Visual.Gameplay sb = decoder.Decode(bfr); } - storyboard = sb.CreateDrawable(Beatmap.Value); + storyboard = sb.CreateDrawable(SelectedMods.Value); storyboardContainer.Add(storyboard); decoupledClock.ChangeSource(Beatmap.Value.Track); diff --git a/osu.Game/Graphics/Backgrounds/BeatmapBackgroundWithStoryboard.cs b/osu.Game/Graphics/Backgrounds/BeatmapBackgroundWithStoryboard.cs index 56ef87c1f4..7aed442800 100644 --- a/osu.Game/Graphics/Backgrounds/BeatmapBackgroundWithStoryboard.cs +++ b/osu.Game/Graphics/Backgrounds/BeatmapBackgroundWithStoryboard.cs @@ -3,12 +3,15 @@ #nullable enable +using System.Collections.Generic; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Overlays; +using osu.Game.Rulesets.Mods; using osu.Game.Storyboards.Drawables; namespace osu.Game.Graphics.Backgrounds @@ -20,6 +23,9 @@ namespace osu.Game.Graphics.Backgrounds [Resolved(CanBeNull = true)] private MusicController? musicController { get; set; } + [Resolved] + private IBindable> mods { get; set; } = null!; + public BeatmapBackgroundWithStoryboard(WorkingBeatmap beatmap, string fallbackTextureName = "Backgrounds/bg1") : base(beatmap, fallbackTextureName) { @@ -39,7 +45,7 @@ namespace osu.Game.Graphics.Backgrounds { RelativeSizeAxes = Axes.Both, Volume = { Value = 0 }, - Child = new DrawableStoryboard(Beatmap.Storyboard) { Clock = storyboardClock } + Child = new DrawableStoryboard(Beatmap.Storyboard, mods.Value) { Clock = storyboardClock } }, AddInternal); } diff --git a/osu.Game/Screens/Play/DimmableStoryboard.cs b/osu.Game/Screens/Play/DimmableStoryboard.cs index f8cedddfbe..5a3ef1e9d3 100644 --- a/osu.Game/Screens/Play/DimmableStoryboard.cs +++ b/osu.Game/Screens/Play/DimmableStoryboard.cs @@ -1,10 +1,12 @@ // 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.Framework.Graphics.Containers; using osu.Game.Graphics.Containers; +using osu.Game.Rulesets.Mods; using osu.Game.Storyboards; using osu.Game.Storyboards.Drawables; @@ -18,6 +20,8 @@ namespace osu.Game.Screens.Play public Container OverlayLayerContainer { get; private set; } private readonly Storyboard storyboard; + private readonly IReadOnlyList mods; + private DrawableStoryboard drawableStoryboard; /// @@ -28,9 +32,10 @@ namespace osu.Game.Screens.Play /// public IBindable HasStoryboardEnded = new BindableBool(true); - public DimmableStoryboard(Storyboard storyboard) + public DimmableStoryboard(Storyboard storyboard, IReadOnlyList mods) { this.storyboard = storyboard; + this.mods = mods; } [BackgroundDependencyLoader] @@ -57,7 +62,7 @@ namespace osu.Game.Screens.Play if (!ShowStoryboard.Value && !IgnoreUserSettings.Value) return; - drawableStoryboard = storyboard.CreateDrawable(); + drawableStoryboard = storyboard.CreateDrawable(mods); HasStoryboardEnded.BindTo(drawableStoryboard.HasStoryboardEnded); if (async) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index d4b02622d3..8ce3f1587d 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -355,7 +355,7 @@ namespace osu.Game.Screens.Play protected virtual GameplayClockContainer CreateGameplayClockContainer(WorkingBeatmap beatmap, double gameplayStart) => new MasterGameplayClockContainer(beatmap, gameplayStart); private Drawable createUnderlayComponents() => - DimmableStoryboard = new DimmableStoryboard(Beatmap.Value.Storyboard) { RelativeSizeAxes = Axes.Both }; + DimmableStoryboard = new DimmableStoryboard(Beatmap.Value.Storyboard, GameplayState.Mods) { RelativeSizeAxes = Axes.Both }; private Drawable createGameplayComponents(IWorkingBeatmap working) => new ScalingContainer(ScalingMode.Gameplay) { diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs index e6528a83bd..840500347f 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs @@ -1,6 +1,8 @@ // 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.Threading; using osuTK; @@ -11,6 +13,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Textures; using osu.Framework.Platform; using osu.Game.Database; +using osu.Game.Rulesets.Mods; using osu.Game.Screens.Play; using osu.Game.Stores; @@ -50,14 +53,18 @@ namespace osu.Game.Storyboards.Drawables private double? lastEventEndTime; + [Cached(typeof(IReadOnlyList))] + public IReadOnlyList Mods { get; } + private DependencyContainer dependencies; protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); - public DrawableStoryboard(Storyboard storyboard) + public DrawableStoryboard(Storyboard storyboard, IReadOnlyList mods) { Storyboard = storyboard; + Mods = mods ?? Array.Empty(); Size = new Vector2(640, 480); diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs index 672274a2ad..4e3f72512c 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs @@ -28,17 +28,20 @@ namespace osu.Game.Storyboards.Drawables LifetimeStart = sampleInfo.StartTime; } - [Resolved] - private IBindable> mods { get; set; } + [Resolved(CanBeNull = true)] + private IReadOnlyList mods { get; set; } protected override void SkinChanged(ISkinSource skin) { base.SkinChanged(skin); - foreach (var mod in mods.Value.OfType()) + if (mods != null) { - foreach (var sample in DrawableSamples) - mod.ApplyToSample(sample); + foreach (var mod in mods.OfType()) + { + foreach (var sample in DrawableSamples) + mod.ApplyToSample(sample); + } } } diff --git a/osu.Game/Storyboards/Storyboard.cs b/osu.Game/Storyboards/Storyboard.cs index c4864c0334..2faed98ae0 100644 --- a/osu.Game/Storyboards/Storyboard.cs +++ b/osu.Game/Storyboards/Storyboard.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps; using osu.Game.Extensions; +using osu.Game.Rulesets.Mods; using osu.Game.Skinning; using osu.Game.Storyboards.Drawables; @@ -90,8 +91,8 @@ namespace osu.Game.Storyboards } } - public DrawableStoryboard CreateDrawable(IWorkingBeatmap working = null) => - new DrawableStoryboard(this); + public DrawableStoryboard CreateDrawable(IReadOnlyList mods = null) => + new DrawableStoryboard(this, mods); public Drawable CreateSpriteFromResourcePath(string path, TextureStore textureStore) { From a812ed4462a5126ff9ba2eb2d858814e59a2ddee Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 2 Mar 2022 23:40:14 +0300 Subject: [PATCH 3/8] Ensure there is at least one sample during rate assertion --- .../Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs index 7a74a00c68..44529aa78c 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs @@ -83,9 +83,7 @@ namespace osu.Game.Tests.Visual.Gameplay createPlayerTest(true); AddAssert("sample playback rate matches mod rates", () => allStoryboardSamples.All(sound => - { - return sound.ChildrenOfType().All(s => s.AggregateFrequency.Value == expectedRate); - })); + sound.ChildrenOfType().First().AggregateFrequency.Value == expectedRate)); } [TestCase(typeof(ModWindUp), 0.5, 2)] @@ -113,9 +111,7 @@ namespace osu.Game.Tests.Visual.Gameplay }); AddAssert("sample playback rate matches mod rates", () => allStoryboardSamples.All(sound => - { - return sound.ChildrenOfType().All(s => s.AggregateFrequency.Value == gameplayMod.SpeedChange.Value); - })); + sound.ChildrenOfType().First().AggregateFrequency.Value == gameplayMod.SpeedChange.Value)); } private void createPlayerTest(bool skipIntro = false) From 82bbc32d74147ce99680e4a5c99e4ffed1bb00b9 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 2 Mar 2022 23:44:58 +0300 Subject: [PATCH 4/8] Remove unnecessary `Schedule` during setup --- .../Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs index 44529aa78c..1d50901fec 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs @@ -42,7 +42,7 @@ namespace osu.Game.Tests.Visual.Gameplay } [SetUp] - public void SetUp() => Schedule(() => storyboardMods = Array.Empty()); + public void SetUp() => storyboardMods = Array.Empty(); [Test] public void TestStoryboardSamplesStopDuringPause() From bb94d68139478a11054f76dc0258e590997e6b4c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 2 Mar 2022 23:55:42 +0300 Subject: [PATCH 5/8] Separate storyboard samples and skip intro steps to own methods --- .../TestSceneStoryboardSamplePlayback.cs | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs index 1d50901fec..6b74868944 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs @@ -51,20 +51,21 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("player paused", () => Player.Pause()); AddAssert("player is currently paused", () => Player.GameplayClockContainer.IsPaused.Value); - AddAssert("all storyboard samples stopped immediately", () => allStoryboardSamples.All(sound => !sound.IsPlaying)); + allStoryobardSamplesStopped(); AddStep("player resume", () => Player.Resume()); - AddUntilStep("any storyboard samples playing after resume", () => allStoryboardSamples.Any(sound => sound.IsPlaying)); + waitUntilStoryboardSamplesPlay(); } [Test] public void TestStoryboardSamplesStopOnSkip() { - createPlayerTest(true); + createPlayerTest(); - AddAssert("all storyboard samples stopped immediately", () => allStoryboardSamples.All(sound => !sound.IsPlaying)); + skipIntro(); + allStoryobardSamplesStopped(); - AddUntilStep("any storyboard samples playing after skip", () => allStoryboardSamples.Any(sound => sound.IsPlaying)); + waitUntilStoryboardSamplesPlay(); } [TestCase(typeof(OsuModDoubleTime), 1.5)] @@ -80,7 +81,8 @@ namespace osu.Game.Tests.Visual.Gameplay storyboardMods = new[] { testedMod }; }); - createPlayerTest(true); + createPlayerTest(); + skipIntro(); AddAssert("sample playback rate matches mod rates", () => allStoryboardSamples.All(sound => sound.ChildrenOfType().First().AggregateFrequency.Value == expectedRate)); @@ -100,7 +102,8 @@ namespace osu.Game.Tests.Visual.Gameplay storyboardMods = new[] { testedMod }; }); - createPlayerTest(true); + createPlayerTest(); + skipIntro(); ModTimeRamp gameplayMod = null; @@ -114,17 +117,20 @@ namespace osu.Game.Tests.Visual.Gameplay sound.ChildrenOfType().First().AggregateFrequency.Value == gameplayMod.SpeedChange.Value)); } - private void createPlayerTest(bool skipIntro = false) + private void createPlayerTest() { CreateTest(null); AddAssert("storyboard loaded", () => Player.Beatmap.Value.Storyboard != null); - AddUntilStep("any storyboard samples playing", () => allStoryboardSamples.Any(sound => sound.IsPlaying)); - - if (skipIntro) - AddStep("skip intro", () => InputManager.Key(Key.Space)); + waitUntilStoryboardSamplesPlay(); } + private void waitUntilStoryboardSamplesPlay() => AddUntilStep("any storyboard samples playing", () => allStoryboardSamples.Any(sound => sound.IsPlaying)); + + private void allStoryobardSamplesStopped() => AddAssert("all storyboard samples stopped immediately", () => allStoryboardSamples.All(sound => !sound.IsPlaying)); + + private void skipIntro() => AddStep("skip intro", () => InputManager.Key(Key.Space)); + private IEnumerable allStoryboardSamples => Player.ChildrenOfType(); protected override bool AllowFail => false; From 2ce4faa3564f13d334e5ed282560488257f19c22 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 3 Mar 2022 00:02:36 +0300 Subject: [PATCH 6/8] Fix typo in method name --- .../Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs index 6b74868944..909cab5e3d 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs @@ -51,7 +51,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("player paused", () => Player.Pause()); AddAssert("player is currently paused", () => Player.GameplayClockContainer.IsPaused.Value); - allStoryobardSamplesStopped(); + allStoryboardSamplesStopped(); AddStep("player resume", () => Player.Resume()); waitUntilStoryboardSamplesPlay(); @@ -63,7 +63,7 @@ namespace osu.Game.Tests.Visual.Gameplay createPlayerTest(); skipIntro(); - allStoryobardSamplesStopped(); + allStoryboardSamplesStopped(); waitUntilStoryboardSamplesPlay(); } @@ -127,7 +127,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void waitUntilStoryboardSamplesPlay() => AddUntilStep("any storyboard samples playing", () => allStoryboardSamples.Any(sound => sound.IsPlaying)); - private void allStoryobardSamplesStopped() => AddAssert("all storyboard samples stopped immediately", () => allStoryboardSamples.All(sound => !sound.IsPlaying)); + private void allStoryboardSamplesStopped() => AddAssert("all storyboard samples stopped immediately", () => allStoryboardSamples.All(sound => !sound.IsPlaying)); private void skipIntro() => AddStep("skip intro", () => InputManager.Key(Key.Space)); From 3630ab2db2da2ee6b0291bf0e3cedfd47a8f020f Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 3 Mar 2022 00:09:12 +0300 Subject: [PATCH 7/8] Remove unnecessary nullability of storyboard mods list --- osu.Game/Storyboards/Drawables/DrawableStoryboard.cs | 3 +-- osu.Game/Storyboards/Storyboard.cs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs index 840500347f..01e4dfca02 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboard.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; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -64,7 +63,7 @@ namespace osu.Game.Storyboards.Drawables public DrawableStoryboard(Storyboard storyboard, IReadOnlyList mods) { Storyboard = storyboard; - Mods = mods ?? Array.Empty(); + Mods = mods; Size = new Vector2(640, 480); diff --git a/osu.Game/Storyboards/Storyboard.cs b/osu.Game/Storyboards/Storyboard.cs index 2faed98ae0..844950336d 100644 --- a/osu.Game/Storyboards/Storyboard.cs +++ b/osu.Game/Storyboards/Storyboard.cs @@ -91,7 +91,7 @@ namespace osu.Game.Storyboards } } - public DrawableStoryboard CreateDrawable(IReadOnlyList mods = null) => + public DrawableStoryboard CreateDrawable(IReadOnlyList mods) => new DrawableStoryboard(this, mods); public Drawable CreateSpriteFromResourcePath(string path, TextureStore textureStore) From c38126ba9d708fe8250dbb76c5a8fe91cff464d3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Mar 2022 12:05:02 +0900 Subject: [PATCH 8/8] Make mods argument optional for storyboard construction --- osu.Game/Storyboards/Drawables/DrawableStoryboard.cs | 5 +++-- osu.Game/Storyboards/Storyboard.cs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs index 01e4dfca02..a0fb7b0b4a 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboard.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.Collections.Generic; using System.Linq; using System.Threading; @@ -60,10 +61,10 @@ namespace osu.Game.Storyboards.Drawables protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); - public DrawableStoryboard(Storyboard storyboard, IReadOnlyList mods) + public DrawableStoryboard(Storyboard storyboard, IReadOnlyList mods = null) { Storyboard = storyboard; - Mods = mods; + Mods = mods ?? Array.Empty(); Size = new Vector2(640, 480); diff --git a/osu.Game/Storyboards/Storyboard.cs b/osu.Game/Storyboards/Storyboard.cs index 844950336d..2faed98ae0 100644 --- a/osu.Game/Storyboards/Storyboard.cs +++ b/osu.Game/Storyboards/Storyboard.cs @@ -91,7 +91,7 @@ namespace osu.Game.Storyboards } } - public DrawableStoryboard CreateDrawable(IReadOnlyList mods) => + public DrawableStoryboard CreateDrawable(IReadOnlyList mods = null) => new DrawableStoryboard(this, mods); public Drawable CreateSpriteFromResourcePath(string path, TextureStore textureStore)