mirror of
https://github.com/ppy/osu.git
synced 2025-01-29 05:52:56 +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);
|
Tracking.BindValueChanged(updateSlidingSample);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SkinnableSound slidingSample;
|
private PausableSkinnableSound slidingSample;
|
||||||
|
|
||||||
protected override void LoadSamples()
|
protected override void LoadSamples()
|
||||||
{
|
{
|
||||||
@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
var clone = HitObject.SampleControlPoint.ApplyTo(firstSample);
|
var clone = HitObject.SampleControlPoint.ApplyTo(firstSample);
|
||||||
clone.Name = "sliderslide";
|
clone.Name = "sliderslide";
|
||||||
|
|
||||||
AddInternal(slidingSample = new SkinnableSound(clone)
|
AddInternal(slidingSample = new PausableSkinnableSound(clone)
|
||||||
{
|
{
|
||||||
Looping = true
|
Looping = true
|
||||||
});
|
});
|
||||||
|
@ -84,7 +84,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
isSpinning.BindValueChanged(updateSpinningSample);
|
isSpinning.BindValueChanged(updateSpinningSample);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SkinnableSound spinningSample;
|
private PausableSkinnableSound spinningSample;
|
||||||
private const float spinning_sample_initial_frequency = 1.0f;
|
private const float spinning_sample_initial_frequency = 1.0f;
|
||||||
private const float spinning_sample_modulated_base_frequency = 0.5f;
|
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);
|
var clone = HitObject.SampleControlPoint.ApplyTo(firstSample);
|
||||||
clone.Name = "spinnerspin";
|
clone.Name = "spinnerspin";
|
||||||
|
|
||||||
AddInternal(spinningSample = new SkinnableSound(clone)
|
AddInternal(spinningSample = new PausableSkinnableSound(clone)
|
||||||
{
|
{
|
||||||
Volume = { Value = 0 },
|
Volume = { Value = 0 },
|
||||||
Looping = true,
|
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,
|
LifetimeStart = lifetimeStart,
|
||||||
LifetimeEnd = lifetimeEnd
|
LifetimeEnd = lifetimeEnd
|
||||||
@ -57,8 +57,8 @@ namespace osu.Game.Rulesets.Taiko.Audio
|
|||||||
|
|
||||||
public class DrumSample
|
public class DrumSample
|
||||||
{
|
{
|
||||||
public SkinnableSound Centre;
|
public PausableSkinnableSound Centre;
|
||||||
public SkinnableSound Rim;
|
public PausableSkinnableSound Rim;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
private GameplayClock gameplayClock = new GameplayClock(new FramedClock());
|
private GameplayClock gameplayClock = new GameplayClock(new FramedClock());
|
||||||
|
|
||||||
private TestSkinSourceContainer skinSource;
|
private TestSkinSourceContainer skinSource;
|
||||||
private SkinnableSound skinnableSound;
|
private PausableSkinnableSound skinnableSound;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUp() => Schedule(() =>
|
||||||
@ -39,7 +39,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
Clock = gameplayClock,
|
Clock = gameplayClock,
|
||||||
RelativeSizeAxes = Axes.Both,
|
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
|
public class NightcoreBeatContainer : BeatSyncedContainer
|
||||||
{
|
{
|
||||||
private SkinnableSound hatSample;
|
private PausableSkinnableSound hatSample;
|
||||||
private SkinnableSound clapSample;
|
private PausableSkinnableSound clapSample;
|
||||||
private SkinnableSound kickSample;
|
private PausableSkinnableSound kickSample;
|
||||||
private SkinnableSound finishSample;
|
private PausableSkinnableSound finishSample;
|
||||||
|
|
||||||
private int? firstBeat;
|
private int? firstBeat;
|
||||||
|
|
||||||
@ -69,10 +69,10 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
{
|
{
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
hatSample = new SkinnableSound(new SampleInfo("nightcore-hat")),
|
hatSample = new PausableSkinnableSound(new SampleInfo("nightcore-hat")),
|
||||||
clapSample = new SkinnableSound(new SampleInfo("nightcore-clap")),
|
clapSample = new PausableSkinnableSound(new SampleInfo("nightcore-clap")),
|
||||||
kickSample = new SkinnableSound(new SampleInfo("nightcore-kick")),
|
kickSample = new PausableSkinnableSound(new SampleInfo("nightcore-kick")),
|
||||||
finishSample = new SkinnableSound(new SampleInfo("nightcore-finish")),
|
finishSample = new PausableSkinnableSound(new SampleInfo("nightcore-finish")),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly Bindable<Color4> AccentColour = new Bindable<Color4>(Color4.Gray);
|
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;
|
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}.");
|
+ $" 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);
|
AddInternal(Samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Allows a component to disable sample playback dynamically as required.
|
/// Allows a component to disable sample playback dynamically as required.
|
||||||
/// Handled by <see cref="SkinnableSound"/>.
|
/// Handled by <see cref="PausableSkinnableSound"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ISamplePlaybackDisabler
|
public interface ISamplePlaybackDisabler
|
||||||
{
|
{
|
||||||
|
@ -33,7 +33,7 @@ namespace osu.Game.Screens.Play
|
|||||||
AddButton("Retry", colours.YellowDark, () => OnRetry?.Invoke());
|
AddButton("Retry", colours.YellowDark, () => OnRetry?.Invoke());
|
||||||
AddButton("Quit", new Color4(170, 27, 39, 255), () => OnQuit?.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,
|
Looping = true,
|
||||||
Volume = { Value = 0 }
|
Volume = { Value = 0 }
|
||||||
@ -54,15 +54,5 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
pauseLoop.VolumeTo(0, TRANSITION_DURATION, Easing.OutQuad).Finally(_ => pauseLoop.Stop());
|
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.Audio;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Screens.Play;
|
|
||||||
|
|
||||||
namespace osu.Game.Skinning
|
namespace osu.Game.Skinning
|
||||||
{
|
{
|
||||||
@ -22,8 +21,6 @@ namespace osu.Game.Skinning
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private ISampleStore samples { get; set; }
|
private ISampleStore samples { get; set; }
|
||||||
|
|
||||||
private bool requestedPlaying;
|
|
||||||
|
|
||||||
public override bool RemoveWhenNotAlive => false;
|
public override bool RemoveWhenNotAlive => false;
|
||||||
public override bool RemoveCompletedTransforms => false;
|
public override bool RemoveCompletedTransforms => false;
|
||||||
|
|
||||||
@ -37,8 +34,6 @@ namespace osu.Game.Skinning
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
protected bool PlayWhenZeroVolume => Looping;
|
protected bool PlayWhenZeroVolume => Looping;
|
||||||
|
|
||||||
protected virtual bool PlayWhenPaused => false;
|
|
||||||
|
|
||||||
private readonly AudioContainer<DrawableSample> samplesContainer;
|
private readonly AudioContainer<DrawableSample> samplesContainer;
|
||||||
|
|
||||||
public SkinnableSound(ISampleInfo hitSamples)
|
public SkinnableSound(ISampleInfo hitSamples)
|
||||||
@ -52,30 +47,6 @@ namespace osu.Game.Skinning
|
|||||||
InternalChild = samplesContainer = new AudioContainer<DrawableSample>();
|
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;
|
private bool looping;
|
||||||
|
|
||||||
public 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 =>
|
samplesContainer.ForEach(c =>
|
||||||
{
|
{
|
||||||
if (PlayWhenZeroVolume || c.AggregateVolume.Value > 0)
|
if (PlayWhenZeroVolume || c.AggregateVolume.Value > 0)
|
||||||
@ -109,13 +71,7 @@ namespace osu.Game.Skinning
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Stop()
|
public virtual void Stop()
|
||||||
{
|
|
||||||
requestedPlaying = false;
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void stop()
|
|
||||||
{
|
{
|
||||||
samplesContainer.ForEach(c => c.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.
|
// Start playback internally for the new samples if the previous ones were playing beforehand.
|
||||||
if (wasPlaying)
|
if (wasPlaying)
|
||||||
play();
|
Play();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Re-expose AudioContainer
|
#region Re-expose AudioContainer
|
||||||
|
Loading…
Reference in New Issue
Block a user