From c490dba7b3e0e22202ab861e0132a5779d818f0f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 13 Jun 2020 18:18:46 +0900 Subject: [PATCH 01/13] Fix crash on local score display --- osu.Game/Scoring/ScoreStore.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Scoring/ScoreStore.cs b/osu.Game/Scoring/ScoreStore.cs index 9627481f4d..f5c5cd5dad 100644 --- a/osu.Game/Scoring/ScoreStore.cs +++ b/osu.Game/Scoring/ScoreStore.cs @@ -18,6 +18,8 @@ namespace osu.Game.Scoring protected override IQueryable AddIncludesForConsumption(IQueryable query) => base.AddIncludesForConsumption(query) .Include(s => s.Beatmap) + .Include(s => s.Beatmap).ThenInclude(b => b.Metadata) + .Include(s => s.Beatmap).ThenInclude(b => b.BeatmapSet).ThenInclude(s => s.Metadata) .Include(s => s.Ruleset); } } From 201bfda3382931077cc8acc26082ce740004f123 Mon Sep 17 00:00:00 2001 From: Ronnie Moir <7267697+H2n9@users.noreply.github.com> Date: Sat, 13 Jun 2020 15:16:27 +0100 Subject: [PATCH 02/13] Give ModTimeRamp an adjust pitch setting. Implement in ModWindDown and ModWindUp --- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 16 +++++++++++++++- osu.Game/Rulesets/Mods/ModWindDown.cs | 7 +++++++ osu.Game/Rulesets/Mods/ModWindUp.cs | 7 +++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index c1f3e357a1..a38aa2bac6 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -26,6 +26,9 @@ namespace osu.Game.Rulesets.Mods [SettingSource("Final rate", "The final speed to ramp to")] public abstract BindableNumber FinalRate { get; } + [SettingSource("Adjust Pitch", "Should pitch be adjusted with speed")] + public abstract BindableBool AdjustPitch { get; } + public override string SettingDescription => $"{InitialRate.Value:N2}x to {FinalRate.Value:N2}x"; private double finalRateTime; @@ -44,12 +47,15 @@ namespace osu.Game.Rulesets.Mods { // for preview purpose at song select. eventually we'll want to be able to update every frame. FinalRate.BindValueChanged(val => applyAdjustment(1), true); + + AdjustPitch.BindValueChanged(updatePitchAdjustment, false); } public void ApplyToTrack(Track track) { this.track = track; - track.AddAdjustment(AdjustableProperty.Frequency, SpeedChange); + + track.AddAdjustment(AdjustPitch.Value ? AdjustableProperty.Frequency : AdjustableProperty.Tempo, SpeedChange); FinalRate.TriggerChange(); } @@ -75,5 +81,13 @@ namespace osu.Game.Rulesets.Mods /// The amount of adjustment to apply (from 0..1). private void applyAdjustment(double amount) => SpeedChange.Value = InitialRate.Value + (FinalRate.Value - InitialRate.Value) * Math.Clamp(amount, 0, 1); + + private void updatePitchAdjustment(ValueChangedEvent value) + { + // remove existing old adjustment + track.RemoveAdjustment(value.OldValue ? AdjustableProperty.Frequency : AdjustableProperty.Tempo, SpeedChange); + + track.AddAdjustment(value.NewValue ? AdjustableProperty.Frequency : AdjustableProperty.Tempo, SpeedChange); + } } } diff --git a/osu.Game/Rulesets/Mods/ModWindDown.cs b/osu.Game/Rulesets/Mods/ModWindDown.cs index 5e634ac434..e46b4eff2e 100644 --- a/osu.Game/Rulesets/Mods/ModWindDown.cs +++ b/osu.Game/Rulesets/Mods/ModWindDown.cs @@ -37,6 +37,13 @@ namespace osu.Game.Rulesets.Mods Precision = 0.01, }; + [SettingSource("Adjust Pitch", "Should pitch be adjusted with speed")] + public override BindableBool AdjustPitch { get; } = new BindableBool + { + Default = true, + Value = true + }; + public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModWindUp)).ToArray(); } } diff --git a/osu.Game/Rulesets/Mods/ModWindUp.cs b/osu.Game/Rulesets/Mods/ModWindUp.cs index 74c6fc22d3..02203a474d 100644 --- a/osu.Game/Rulesets/Mods/ModWindUp.cs +++ b/osu.Game/Rulesets/Mods/ModWindUp.cs @@ -37,6 +37,13 @@ namespace osu.Game.Rulesets.Mods Precision = 0.01, }; + [SettingSource("Adjust Pitch", "Should pitch be adjusted with speed")] + public override BindableBool AdjustPitch { get; } = new BindableBool + { + Default = true, + Value = true + }; + public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModWindDown)).ToArray(); } } From 77eb428184473b09e0cb370adaf11e45e0b9ed9e Mon Sep 17 00:00:00 2001 From: Ronnie Moir <7267697+H2n9@users.noreply.github.com> Date: Sat, 13 Jun 2020 16:30:21 +0100 Subject: [PATCH 03/13] Use consistent setting casing --- osu.Game/Rulesets/Mods/ModWindDown.cs | 2 +- osu.Game/Rulesets/Mods/ModWindUp.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModWindDown.cs b/osu.Game/Rulesets/Mods/ModWindDown.cs index e46b4eff2e..679b50057b 100644 --- a/osu.Game/Rulesets/Mods/ModWindDown.cs +++ b/osu.Game/Rulesets/Mods/ModWindDown.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Mods Precision = 0.01, }; - [SettingSource("Adjust Pitch", "Should pitch be adjusted with speed")] + [SettingSource("Adjust pitch", "Should pitch be adjusted with speed")] public override BindableBool AdjustPitch { get; } = new BindableBool { Default = true, diff --git a/osu.Game/Rulesets/Mods/ModWindUp.cs b/osu.Game/Rulesets/Mods/ModWindUp.cs index 02203a474d..b733bf423e 100644 --- a/osu.Game/Rulesets/Mods/ModWindUp.cs +++ b/osu.Game/Rulesets/Mods/ModWindUp.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Mods Precision = 0.01, }; - [SettingSource("Adjust Pitch", "Should pitch be adjusted with speed")] + [SettingSource("Adjust pitch", "Should pitch be adjusted with speed")] public override BindableBool AdjustPitch { get; } = new BindableBool { Default = true, From dc5bb12fa8e9f6f47c14c57b8242b24f24aa37c3 Mon Sep 17 00:00:00 2001 From: Ronnie Moir <7267697+H2n9@users.noreply.github.com> Date: Sat, 13 Jun 2020 16:32:43 +0100 Subject: [PATCH 04/13] Use local helper for selecting adjusted property --- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index a38aa2bac6..9f30f340fd 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Mods [SettingSource("Final rate", "The final speed to ramp to")] public abstract BindableNumber FinalRate { get; } - [SettingSource("Adjust Pitch", "Should pitch be adjusted with speed")] + [SettingSource("Adjust pitch", "Should pitch be adjusted with speed")] public abstract BindableBool AdjustPitch { get; } public override string SettingDescription => $"{InitialRate.Value:N2}x to {FinalRate.Value:N2}x"; @@ -55,9 +55,8 @@ namespace osu.Game.Rulesets.Mods { this.track = track; - track.AddAdjustment(AdjustPitch.Value ? AdjustableProperty.Frequency : AdjustableProperty.Tempo, SpeedChange); - FinalRate.TriggerChange(); + AdjustPitch.TriggerChange(); } public virtual void ApplyToBeatmap(IBeatmap beatmap) @@ -85,9 +84,12 @@ namespace osu.Game.Rulesets.Mods private void updatePitchAdjustment(ValueChangedEvent value) { // remove existing old adjustment - track.RemoveAdjustment(value.OldValue ? AdjustableProperty.Frequency : AdjustableProperty.Tempo, SpeedChange); + track.RemoveAdjustment(adjustmentForPitchSetting(value.OldValue), SpeedChange); - track.AddAdjustment(value.NewValue ? AdjustableProperty.Frequency : AdjustableProperty.Tempo, SpeedChange); + track.AddAdjustment(adjustmentForPitchSetting(value.NewValue), SpeedChange); } + + private AdjustableProperty adjustmentForPitchSetting(bool value) + => value ? AdjustableProperty.Frequency : AdjustableProperty.Tempo; } } From 7b95c55afb17429a8eb1b253c62767c11f3792c9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 14 Jun 2020 11:33:59 +0900 Subject: [PATCH 05/13] Fix HardwareCorrectionOffsetClock breaking ElapsedTime readings --- osu.Game/Screens/Play/GameplayClockContainer.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index 2f85d6ad1e..fe1d22e987 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -251,8 +251,9 @@ namespace osu.Game.Screens.Play private class HardwareCorrectionOffsetClock : FramedOffsetClock { - // we always want to apply the same real-time offset, so it should be adjusted by the playback rate to achieve this. - public override double CurrentTime => SourceTime + Offset * Rate; + // we always want to apply the same real-time offset, so it should be adjusted by the difference in playback rate (from realtime) to achieve this. + // base implementation already adds offset at 1.0 rate, so we only add the difference from that here. + public override double CurrentTime => base.CurrentTime + Offset * (1 - Rate); public HardwareCorrectionOffsetClock(IClock source, bool processSource = true) : base(source, processSource) From 1164a1048330211410a9f050176bf868c56a023d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 14 Jun 2020 11:34:07 +0900 Subject: [PATCH 06/13] Add test coverage --- .../TestSceneGameplayClockContainer.cs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs diff --git a/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs b/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs new file mode 100644 index 0000000000..a97566ba7b --- /dev/null +++ b/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs @@ -0,0 +1,25 @@ +// 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 NUnit.Framework; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu; +using osu.Game.Screens.Play; +using osu.Game.Tests.Visual; + +namespace osu.Game.Tests.Gameplay +{ + public class TestSceneGameplayClockContainer : OsuTestScene + { + [Test] + public void TestStartThenElapsedTime() + { + GameplayClockContainer gcc = null; + + AddStep("create container", () => Add(gcc = new GameplayClockContainer(CreateWorkingBeatmap(new OsuRuleset().RulesetInfo), Array.Empty(), 0))); + AddStep("start track", () => gcc.Start()); + AddUntilStep("elapsed greater than zero", () => gcc.GameplayClock.ElapsedFrameTime > 0); + } + } +} From abe07b742ebb16190fe0a4601f1fbbc8094748c7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 14 Jun 2020 13:20:58 +0900 Subject: [PATCH 07/13] Fix drag scroll in editor timeline no longer working correctly --- osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs | 2 -- .../Edit/Compose/Components/ComposeBlueprintContainer.cs | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index d07cffff0c..cc417bbb10 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -44,8 +44,6 @@ namespace osu.Game.Screens.Edit.Compose.Components private readonly BindableList selectedHitObjects = new BindableList(); - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; - [Resolved(canBeNull: true)] private IPositionSnapProvider snapProvider { get; set; } diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index 0b5d8262fd..e1f311f1b8 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -11,6 +11,7 @@ using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; +using osuTK; namespace osu.Game.Screens.Edit.Compose.Components { @@ -26,6 +27,8 @@ namespace osu.Game.Screens.Edit.Compose.Components private readonly Container placementBlueprintContainer; + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; + private InputManager inputManager; private readonly IEnumerable drawableHitObjects; From 0d53d0ffc8f361576a60ebda3ae1e5dece2c6144 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 15 Jun 2020 00:46:20 +0900 Subject: [PATCH 08/13] Fix back-to-front math --- osu.Game/Screens/Play/GameplayClockContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index fe1d22e987..0653373c91 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -253,7 +253,7 @@ namespace osu.Game.Screens.Play { // we always want to apply the same real-time offset, so it should be adjusted by the difference in playback rate (from realtime) to achieve this. // base implementation already adds offset at 1.0 rate, so we only add the difference from that here. - public override double CurrentTime => base.CurrentTime + Offset * (1 - Rate); + public override double CurrentTime => base.CurrentTime + Offset * (Rate - 1); public HardwareCorrectionOffsetClock(IClock source, bool processSource = true) : base(source, processSource) From 9907b4763bb76963eee9d652640559f07e5fce1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 14 Jun 2020 18:39:41 +0200 Subject: [PATCH 09/13] Remove redundant default argument value --- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index 9f30f340fd..09c50ce115 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Mods // for preview purpose at song select. eventually we'll want to be able to update every frame. FinalRate.BindValueChanged(val => applyAdjustment(1), true); - AdjustPitch.BindValueChanged(updatePitchAdjustment, false); + AdjustPitch.BindValueChanged(updatePitchAdjustment); } public void ApplyToTrack(Track track) From 5f0a345eebd0410364a79b69aa0465490b48712a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 14 Jun 2020 18:48:49 +0200 Subject: [PATCH 10/13] Unify method naming --- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index 09c50ce115..edca3edf46 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -46,9 +46,8 @@ namespace osu.Game.Rulesets.Mods protected ModTimeRamp() { // for preview purpose at song select. eventually we'll want to be able to update every frame. - FinalRate.BindValueChanged(val => applyAdjustment(1), true); - - AdjustPitch.BindValueChanged(updatePitchAdjustment); + FinalRate.BindValueChanged(val => applyRateAdjustment(1), true); + AdjustPitch.BindValueChanged(applyPitchAdjustment); } public void ApplyToTrack(Track track) @@ -71,17 +70,17 @@ namespace osu.Game.Rulesets.Mods public virtual void Update(Playfield playfield) { - applyAdjustment((track.CurrentTime - beginRampTime) / finalRateTime); + applyRateAdjustment((track.CurrentTime - beginRampTime) / finalRateTime); } /// /// Adjust the rate along the specified ramp /// /// The amount of adjustment to apply (from 0..1). - private void applyAdjustment(double amount) => + private void applyRateAdjustment(double amount) => SpeedChange.Value = InitialRate.Value + (FinalRate.Value - InitialRate.Value) * Math.Clamp(amount, 0, 1); - private void updatePitchAdjustment(ValueChangedEvent value) + private void applyPitchAdjustment(ValueChangedEvent value) { // remove existing old adjustment track.RemoveAdjustment(adjustmentForPitchSetting(value.OldValue), SpeedChange); From e6ddd0380e2ee3b12aacd5a2fdf009ede4605672 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 14 Jun 2020 18:50:07 +0200 Subject: [PATCH 11/13] Rename bool arguments for readability --- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index edca3edf46..df059eef7d 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -80,15 +80,15 @@ namespace osu.Game.Rulesets.Mods private void applyRateAdjustment(double amount) => SpeedChange.Value = InitialRate.Value + (FinalRate.Value - InitialRate.Value) * Math.Clamp(amount, 0, 1); - private void applyPitchAdjustment(ValueChangedEvent value) + private void applyPitchAdjustment(ValueChangedEvent adjustPitchSetting) { // remove existing old adjustment - track.RemoveAdjustment(adjustmentForPitchSetting(value.OldValue), SpeedChange); + track.RemoveAdjustment(adjustmentForPitchSetting(adjustPitchSetting.OldValue), SpeedChange); - track.AddAdjustment(adjustmentForPitchSetting(value.NewValue), SpeedChange); + track.AddAdjustment(adjustmentForPitchSetting(adjustPitchSetting.NewValue), SpeedChange); } - private AdjustableProperty adjustmentForPitchSetting(bool value) - => value ? AdjustableProperty.Frequency : AdjustableProperty.Tempo; + private AdjustableProperty adjustmentForPitchSetting(bool adjustPitchSettingValue) + => adjustPitchSettingValue ? AdjustableProperty.Frequency : AdjustableProperty.Tempo; } } From 978636b90c5f1f1ff943cbe4027543c595e52201 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 15 Jun 2020 09:38:33 +0900 Subject: [PATCH 12/13] Fix storyboard sample playback failing when expected to play at 0ms --- osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs index f3f8308964..8292b02068 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs @@ -51,7 +51,7 @@ namespace osu.Game.Storyboards.Drawables LifetimeStart = sampleInfo.StartTime; LifetimeEnd = double.MaxValue; } - else if (Time.Current - Time.Elapsed < sampleInfo.StartTime) + else if (Time.Current - Time.Elapsed <= sampleInfo.StartTime) { // We've passed the start time of the sample. We only play the sample if we're within an allowable range // from the sample's start, to reduce layering if we've been fast-forwarded far into the future From fdf7c56ba28db7165d1651dcdfb2e69520866e35 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 15 Jun 2020 11:18:12 +0900 Subject: [PATCH 13/13] Add test coverage --- .../Gameplay/TestSceneStoryboardSamples.cs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index 84506739ab..2c85c4809b 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.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.IO; using System.Threading.Tasks; @@ -10,7 +11,12 @@ using osu.Framework.Audio.Sample; using osu.Framework.IO.Stores; using osu.Framework.Testing; using osu.Game.Audio; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu; +using osu.Game.Screens.Play; using osu.Game.Skinning; +using osu.Game.Storyboards; +using osu.Game.Storyboards.Drawables; using osu.Game.Tests.Resources; using osu.Game.Tests.Visual; @@ -43,6 +49,27 @@ namespace osu.Game.Tests.Gameplay AddAssert("sample is non-null", () => channel != null); } + [Test] + public void TestSamplePlaybackAtZero() + { + GameplayClockContainer gameplayContainer = null; + DrawableStoryboardSample sample = null; + + AddStep("create container", () => + { + Add(gameplayContainer = new GameplayClockContainer(CreateWorkingBeatmap(new OsuRuleset().RulesetInfo), Array.Empty(), 0)); + + gameplayContainer.Add(sample = new DrawableStoryboardSample(new StoryboardSampleInfo(string.Empty, 0, 1)) + { + Clock = gameplayContainer.GameplayClock + }); + }); + + AddStep("start time", () => gameplayContainer.Start()); + + AddUntilStep("sample playback succeeded", () => sample.LifetimeEnd < double.MaxValue); + } + private class TestSkin : LegacySkin { public TestSkin(string resourceName, AudioManager audioManager)