mirror of
https://github.com/ppy/osu.git
synced 2025-01-27 01:02:54 +08:00
Reverse inheritance order of SkinnableSound's pause logic
This commit is contained in:
parent
59ce9fcab9
commit
414c40d298
@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
Tracking.BindValueChanged(updateSlidingSample);
|
||||
}
|
||||
|
||||
private SkinnableSound slidingSample;
|
||||
private PausableSkinnableSound slidingSample;
|
||||
|
||||
protected override void LoadSamples()
|
||||
{
|
||||
@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
var clone = HitObject.SampleControlPoint.ApplyTo(firstSample);
|
||||
clone.Name = "sliderslide";
|
||||
|
||||
AddInternal(slidingSample = new SkinnableSound(clone)
|
||||
AddInternal(slidingSample = new PausableSkinnableSound(clone)
|
||||
{
|
||||
Looping = true
|
||||
});
|
||||
|
@ -84,7 +84,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
isSpinning.BindValueChanged(updateSpinningSample);
|
||||
}
|
||||
|
||||
private SkinnableSound spinningSample;
|
||||
private PausableSkinnableSound spinningSample;
|
||||
private const float spinning_sample_initial_frequency = 1.0f;
|
||||
private const float spinning_sample_modulated_base_frequency = 0.5f;
|
||||
|
||||
@ -102,7 +102,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
var clone = HitObject.SampleControlPoint.ApplyTo(firstSample);
|
||||
clone.Name = "spinnerspin";
|
||||
|
||||
AddInternal(spinningSample = new SkinnableSound(clone)
|
||||
AddInternal(spinningSample = new PausableSkinnableSound(clone)
|
||||
{
|
||||
Volume = { Value = 0 },
|
||||
Looping = true,
|
||||
|
@ -42,9 +42,9 @@ namespace osu.Game.Rulesets.Taiko.Audio
|
||||
}
|
||||
}
|
||||
|
||||
private SkinnableSound addSound(HitSampleInfo hitSampleInfo, double lifetimeStart, double lifetimeEnd)
|
||||
private PausableSkinnableSound addSound(HitSampleInfo hitSampleInfo, double lifetimeStart, double lifetimeEnd)
|
||||
{
|
||||
var drawable = new SkinnableSound(hitSampleInfo)
|
||||
var drawable = new PausableSkinnableSound(hitSampleInfo)
|
||||
{
|
||||
LifetimeStart = lifetimeStart,
|
||||
LifetimeEnd = lifetimeEnd
|
||||
@ -57,8 +57,8 @@ namespace osu.Game.Rulesets.Taiko.Audio
|
||||
|
||||
public class DrumSample
|
||||
{
|
||||
public SkinnableSound Centre;
|
||||
public SkinnableSound Rim;
|
||||
public PausableSkinnableSound Centre;
|
||||
public PausableSkinnableSound Rim;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
private GameplayClock gameplayClock = new GameplayClock(new FramedClock());
|
||||
|
||||
private TestSkinSourceContainer skinSource;
|
||||
private SkinnableSound skinnableSound;
|
||||
private PausableSkinnableSound skinnableSound;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp() => Schedule(() =>
|
||||
@ -39,7 +39,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
Clock = gameplayClock,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Child = skinnableSound = new SkinnableSound(new SampleInfo("normal-sliderslide"))
|
||||
Child = skinnableSound = new PausableSkinnableSound(new SampleInfo("normal-sliderslide"))
|
||||
},
|
||||
};
|
||||
});
|
||||
|
@ -52,10 +52,10 @@ namespace osu.Game.Rulesets.Mods
|
||||
|
||||
public class NightcoreBeatContainer : BeatSyncedContainer
|
||||
{
|
||||
private SkinnableSound hatSample;
|
||||
private SkinnableSound clapSample;
|
||||
private SkinnableSound kickSample;
|
||||
private SkinnableSound finishSample;
|
||||
private PausableSkinnableSound hatSample;
|
||||
private PausableSkinnableSound clapSample;
|
||||
private PausableSkinnableSound kickSample;
|
||||
private PausableSkinnableSound finishSample;
|
||||
|
||||
private int? firstBeat;
|
||||
|
||||
@ -69,10 +69,10 @@ namespace osu.Game.Rulesets.Mods
|
||||
{
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
hatSample = new SkinnableSound(new SampleInfo("nightcore-hat")),
|
||||
clapSample = new SkinnableSound(new SampleInfo("nightcore-clap")),
|
||||
kickSample = new SkinnableSound(new SampleInfo("nightcore-kick")),
|
||||
finishSample = new SkinnableSound(new SampleInfo("nightcore-finish")),
|
||||
hatSample = new PausableSkinnableSound(new SampleInfo("nightcore-hat")),
|
||||
clapSample = new PausableSkinnableSound(new SampleInfo("nightcore-clap")),
|
||||
kickSample = new PausableSkinnableSound(new SampleInfo("nightcore-kick")),
|
||||
finishSample = new PausableSkinnableSound(new SampleInfo("nightcore-finish")),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
||||
/// </summary>
|
||||
public readonly Bindable<Color4> AccentColour = new Bindable<Color4>(Color4.Gray);
|
||||
|
||||
protected SkinnableSound Samples { get; private set; }
|
||||
protected PausableSkinnableSound Samples { get; private set; }
|
||||
|
||||
public virtual IEnumerable<HitSampleInfo> GetSamples() => HitObject.Samples;
|
||||
|
||||
@ -179,7 +179,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
||||
+ $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}.");
|
||||
}
|
||||
|
||||
Samples = new SkinnableSound(samples.Select(s => HitObject.SampleControlPoint.ApplyTo(s)));
|
||||
Samples = new PausableSkinnableSound(samples.Select(s => HitObject.SampleControlPoint.ApplyTo(s)));
|
||||
AddInternal(Samples);
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ namespace osu.Game.Screens.Play
|
||||
{
|
||||
/// <summary>
|
||||
/// Allows a component to disable sample playback dynamically as required.
|
||||
/// Handled by <see cref="SkinnableSound"/>.
|
||||
/// Handled by <see cref="PausableSkinnableSound"/>.
|
||||
/// </summary>
|
||||
public interface ISamplePlaybackDisabler
|
||||
{
|
||||
|
@ -33,7 +33,7 @@ namespace osu.Game.Screens.Play
|
||||
AddButton("Retry", colours.YellowDark, () => OnRetry?.Invoke());
|
||||
AddButton("Quit", new Color4(170, 27, 39, 255), () => OnQuit?.Invoke());
|
||||
|
||||
AddInternal(pauseLoop = new UnpausableSkinnableSound(new SampleInfo("pause-loop"))
|
||||
AddInternal(pauseLoop = new SkinnableSound(new SampleInfo("pause-loop"))
|
||||
{
|
||||
Looping = true,
|
||||
Volume = { Value = 0 }
|
||||
@ -54,15 +54,5 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
pauseLoop.VolumeTo(0, TRANSITION_DURATION, Easing.OutQuad).Finally(_ => pauseLoop.Stop());
|
||||
}
|
||||
|
||||
private class UnpausableSkinnableSound : SkinnableSound
|
||||
{
|
||||
protected override bool PlayWhenPaused => true;
|
||||
|
||||
public UnpausableSkinnableSound(SampleInfo sampleInfo)
|
||||
: base(sampleInfo)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
66
osu.Game/Skinning/PausableSkinnableSound.cs
Normal file
66
osu.Game/Skinning/PausableSkinnableSound.cs
Normal file
@ -0,0 +1,66 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. 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.Audio;
|
||||
using osu.Game.Screens.Play;
|
||||
|
||||
namespace osu.Game.Skinning
|
||||
{
|
||||
public class PausableSkinnableSound : SkinnableSound
|
||||
{
|
||||
protected bool RequestedPlaying { get; private set; }
|
||||
|
||||
public PausableSkinnableSound(ISampleInfo hitSamples)
|
||||
: base(hitSamples)
|
||||
{
|
||||
}
|
||||
|
||||
public PausableSkinnableSound(IEnumerable<ISampleInfo> hitSamples)
|
||||
: base(hitSamples)
|
||||
{
|
||||
}
|
||||
|
||||
private readonly IBindable<bool> samplePlaybackDisabled = new Bindable<bool>();
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(ISamplePlaybackDisabler samplePlaybackDisabler)
|
||||
{
|
||||
// if in a gameplay context, pause sample playback when gameplay is paused.
|
||||
if (samplePlaybackDisabler != null)
|
||||
{
|
||||
samplePlaybackDisabled.BindTo(samplePlaybackDisabler.SamplePlaybackDisabled);
|
||||
samplePlaybackDisabled.BindValueChanged(disabled =>
|
||||
{
|
||||
if (RequestedPlaying)
|
||||
{
|
||||
if (disabled.NewValue)
|
||||
base.Stop();
|
||||
// it's not easy to know if a sample has finished playing (to end).
|
||||
// to keep things simple only resume playing looping samples.
|
||||
else if (Looping)
|
||||
base.Play();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override void Play()
|
||||
{
|
||||
RequestedPlaying = true;
|
||||
|
||||
if (samplePlaybackDisabled.Value)
|
||||
return;
|
||||
|
||||
base.Play();
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
RequestedPlaying = false;
|
||||
base.Stop();
|
||||
}
|
||||
}
|
||||
}
|
@ -11,7 +11,6 @@ using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics.Audio;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Screens.Play;
|
||||
|
||||
namespace osu.Game.Skinning
|
||||
{
|
||||
@ -22,8 +21,6 @@ namespace osu.Game.Skinning
|
||||
[Resolved]
|
||||
private ISampleStore samples { get; set; }
|
||||
|
||||
private bool requestedPlaying;
|
||||
|
||||
public override bool RemoveWhenNotAlive => false;
|
||||
public override bool RemoveCompletedTransforms => false;
|
||||
|
||||
@ -37,8 +34,6 @@ namespace osu.Game.Skinning
|
||||
/// </remarks>
|
||||
protected bool PlayWhenZeroVolume => Looping;
|
||||
|
||||
protected virtual bool PlayWhenPaused => false;
|
||||
|
||||
private readonly AudioContainer<DrawableSample> samplesContainer;
|
||||
|
||||
public SkinnableSound(ISampleInfo hitSamples)
|
||||
@ -52,30 +47,6 @@ namespace osu.Game.Skinning
|
||||
InternalChild = samplesContainer = new AudioContainer<DrawableSample>();
|
||||
}
|
||||
|
||||
private readonly IBindable<bool> samplePlaybackDisabled = new Bindable<bool>();
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(ISamplePlaybackDisabler samplePlaybackDisabler)
|
||||
{
|
||||
// if in a gameplay context, pause sample playback when gameplay is paused.
|
||||
if (samplePlaybackDisabler != null)
|
||||
{
|
||||
samplePlaybackDisabled.BindTo(samplePlaybackDisabler.SamplePlaybackDisabled);
|
||||
samplePlaybackDisabled.BindValueChanged(disabled =>
|
||||
{
|
||||
if (requestedPlaying)
|
||||
{
|
||||
if (disabled.NewValue && !PlayWhenPaused)
|
||||
stop();
|
||||
// it's not easy to know if a sample has finished playing (to end).
|
||||
// to keep things simple only resume playing looping samples.
|
||||
else if (Looping)
|
||||
play();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private bool looping;
|
||||
|
||||
public bool Looping
|
||||
@ -91,17 +62,8 @@ namespace osu.Game.Skinning
|
||||
}
|
||||
}
|
||||
|
||||
public void Play()
|
||||
public virtual void Play()
|
||||
{
|
||||
requestedPlaying = true;
|
||||
play();
|
||||
}
|
||||
|
||||
private void play()
|
||||
{
|
||||
if (samplePlaybackDisabled.Value && !PlayWhenPaused)
|
||||
return;
|
||||
|
||||
samplesContainer.ForEach(c =>
|
||||
{
|
||||
if (PlayWhenZeroVolume || c.AggregateVolume.Value > 0)
|
||||
@ -109,13 +71,7 @@ namespace osu.Game.Skinning
|
||||
});
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
requestedPlaying = false;
|
||||
stop();
|
||||
}
|
||||
|
||||
private void stop()
|
||||
public virtual void Stop()
|
||||
{
|
||||
samplesContainer.ForEach(c => c.Stop());
|
||||
}
|
||||
@ -150,7 +106,7 @@ namespace osu.Game.Skinning
|
||||
|
||||
// Start playback internally for the new samples if the previous ones were playing beforehand.
|
||||
if (wasPlaying)
|
||||
play();
|
||||
Play();
|
||||
}
|
||||
|
||||
#region Re-expose AudioContainer
|
||||
|
Loading…
Reference in New Issue
Block a user