diff --git a/osu.Game/Skinning/PausableSkinnableSound.cs b/osu.Game/Skinning/PausableSkinnableSound.cs index b48cf5d448..6245bcae02 100644 --- a/osu.Game/Skinning/PausableSkinnableSound.cs +++ b/osu.Game/Skinning/PausableSkinnableSound.cs @@ -18,7 +18,7 @@ namespace osu.Game.Skinning protected bool RequestedPlaying { get; private set; } - private readonly IBindable samplePlaybackDisabled = new Bindable(); + protected virtual bool AllowNonLoopingCutOff => false; public PausableSkinnableSound() { @@ -34,6 +34,8 @@ namespace osu.Game.Skinning { } + private readonly IBindable samplePlaybackDisabled = new Bindable(); + private ScheduledDelegate scheduledStart; [BackgroundDependencyLoader(true)] @@ -43,28 +45,34 @@ namespace osu.Game.Skinning if (samplePlaybackDisabler != null) { samplePlaybackDisabled.BindTo(samplePlaybackDisabler.SamplePlaybackDisabled); - samplePlaybackDisabled.BindValueChanged(SamplePlaybackDisabledChanged); + samplePlaybackDisabled.BindValueChanged(disabled => + { + if (!RequestedPlaying) return; + + // if the sample is non-looping, and non-looping cut off is not allowed, + // let the sample play out to completion (sounds better than abruptly cutting off). + if (!Looping && !AllowNonLoopingCutOff) return; + + cancelPendingStart(); + + if (disabled.NewValue) + base.Stop(); + else + { + // schedule so we don't start playing a sample which is no longer alive. + scheduledStart = Schedule(() => + { + if (RequestedPlaying) + base.Play(); + }); + } + }); } } - protected virtual void SamplePlaybackDisabledChanged(ValueChangedEvent disabled) - { - if (!RequestedPlaying) return; - - // let non-looping samples that have already been started play out to completion (sounds better than abruptly cutting off). - if (!Looping) return; - - CancelPendingStart(); - - if (disabled.NewValue) - base.Stop(); - else - ScheduleStart(); - } - public override void Play(bool restart = true) { - CancelPendingStart(); + cancelPendingStart(); RequestedPlaying = true; if (samplePlaybackDisabled.Value) @@ -75,25 +83,15 @@ namespace osu.Game.Skinning public override void Stop() { - CancelPendingStart(); + cancelPendingStart(); RequestedPlaying = false; base.Stop(); } - protected void CancelPendingStart() + private void cancelPendingStart() { scheduledStart?.Cancel(); scheduledStart = null; } - - protected void ScheduleStart() - { - // schedule so we don't start playing a sample which is no longer alive. - scheduledStart = Schedule(() => - { - if (RequestedPlaying) - base.Play(); - }); - } } } diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs index d5e1e19666..ebdf64e7ba 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs @@ -21,6 +21,8 @@ namespace osu.Game.Storyboards.Drawables public override bool RemoveWhenNotAlive => false; + protected override bool AllowNonLoopingCutOff => true; + public DrawableStoryboardSample(StoryboardSampleInfo sampleInfo) : base(sampleInfo) { @@ -31,19 +33,6 @@ namespace osu.Game.Storyboards.Drawables [Resolved] private IBindable> mods { get; set; } - protected override void SamplePlaybackDisabledChanged(ValueChangedEvent disabled) - { - if (!RequestedPlaying) return; - - if (disabled.NewValue) - Stop(); - else - { - CancelPendingStart(); - ScheduleStart(); - } - } - protected override void SkinChanged(ISkinSource skin, bool allowFallback) { base.SkinChanged(skin, allowFallback);