mirror of
https://github.com/ppy/osu.git
synced 2025-02-21 13:42:55 +08:00
Merge pull request #10505 from peppy/skin-disabler-refactor
Move ISampleDisabler implementation to Player and FrameStabilityContainer
This commit is contained in:
commit
93dfbd5d9e
@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
AddStep("get variables", () =>
|
AddStep("get variables", () =>
|
||||||
{
|
{
|
||||||
gameplayClock = Player.ChildrenOfType<FrameStabilityContainer>().First().GameplayClock;
|
gameplayClock = Player.ChildrenOfType<FrameStabilityContainer>().First();
|
||||||
slider = Player.ChildrenOfType<DrawableSlider>().OrderBy(s => s.HitObject.StartTime).First();
|
slider = Player.ChildrenOfType<DrawableSlider>().OrderBy(s => s.HitObject.StartTime).First();
|
||||||
samples = slider.ChildrenOfType<DrawableSample>().ToArray();
|
samples = slider.ChildrenOfType<DrawableSample>().ToArray();
|
||||||
});
|
});
|
||||||
|
@ -13,7 +13,6 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Graphics.OpenGL.Textures;
|
using osu.Framework.Graphics.OpenGL.Textures;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Framework.Timing;
|
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
@ -22,27 +21,24 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
public class TestSceneSkinnableSound : OsuTestScene
|
public class TestSceneSkinnableSound : OsuTestScene
|
||||||
{
|
{
|
||||||
[Cached(typeof(ISamplePlaybackDisabler))]
|
|
||||||
private GameplayClock gameplayClock = new GameplayClock(new FramedClock());
|
|
||||||
|
|
||||||
private TestSkinSourceContainer skinSource;
|
private TestSkinSourceContainer skinSource;
|
||||||
private PausableSkinnableSound skinnableSound;
|
private PausableSkinnableSound skinnableSound;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUpSteps()
|
||||||
|
{
|
||||||
|
AddStep("setup hierarchy", () =>
|
||||||
{
|
{
|
||||||
gameplayClock.IsPaused.Value = false;
|
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
skinSource = new TestSkinSourceContainer
|
skinSource = new TestSkinSourceContainer
|
||||||
{
|
{
|
||||||
Clock = gameplayClock,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Child = skinnableSound = new PausableSkinnableSound(new SampleInfo("normal-sliderslide"))
|
Child = skinnableSound = new PausableSkinnableSound(new SampleInfo("normal-sliderslide"))
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestStoppedSoundDoesntResumeAfterPause()
|
public void TestStoppedSoundDoesntResumeAfterPause()
|
||||||
@ -62,8 +58,9 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
AddUntilStep("wait for sample to stop playing", () => !sample.Playing);
|
AddUntilStep("wait for sample to stop playing", () => !sample.Playing);
|
||||||
|
|
||||||
AddStep("pause gameplay clock", () => gameplayClock.IsPaused.Value = true);
|
AddStep("disable sample playback", () => skinSource.SamplePlaybackDisabled.Value = true);
|
||||||
AddStep("resume gameplay clock", () => gameplayClock.IsPaused.Value = false);
|
|
||||||
|
AddStep("enable sample playback", () => skinSource.SamplePlaybackDisabled.Value = false);
|
||||||
|
|
||||||
AddWaitStep("wait a bit", 5);
|
AddWaitStep("wait a bit", 5);
|
||||||
AddAssert("sample not playing", () => !sample.Playing);
|
AddAssert("sample not playing", () => !sample.Playing);
|
||||||
@ -82,8 +79,11 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
AddUntilStep("wait for sample to start playing", () => sample.Playing);
|
AddUntilStep("wait for sample to start playing", () => sample.Playing);
|
||||||
|
|
||||||
AddStep("pause gameplay clock", () => gameplayClock.IsPaused.Value = true);
|
AddStep("disable sample playback", () => skinSource.SamplePlaybackDisabled.Value = true);
|
||||||
AddUntilStep("wait for sample to stop playing", () => !sample.Playing);
|
AddUntilStep("wait for sample to stop playing", () => !sample.Playing);
|
||||||
|
|
||||||
|
AddStep("enable sample playback", () => skinSource.SamplePlaybackDisabled.Value = false);
|
||||||
|
AddUntilStep("wait for sample to start playing", () => sample.Playing);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -98,10 +98,11 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
AddAssert("sample playing", () => sample.Playing);
|
AddAssert("sample playing", () => sample.Playing);
|
||||||
|
|
||||||
AddStep("pause gameplay clock", () => gameplayClock.IsPaused.Value = true);
|
AddStep("disable sample playback", () => skinSource.SamplePlaybackDisabled.Value = true);
|
||||||
AddUntilStep("wait for sample to stop playing", () => !sample.Playing);
|
|
||||||
|
|
||||||
AddStep("resume gameplay clock", () => gameplayClock.IsPaused.Value = false);
|
AddUntilStep("sample not playing", () => !sample.Playing);
|
||||||
|
|
||||||
|
AddStep("enable sample playback", () => skinSource.SamplePlaybackDisabled.Value = false);
|
||||||
|
|
||||||
AddAssert("sample not playing", () => !sample.Playing);
|
AddAssert("sample not playing", () => !sample.Playing);
|
||||||
AddAssert("sample not playing", () => !sample.Playing);
|
AddAssert("sample not playing", () => !sample.Playing);
|
||||||
@ -120,7 +121,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
AddAssert("sample playing", () => sample.Playing);
|
AddAssert("sample playing", () => sample.Playing);
|
||||||
|
|
||||||
AddStep("pause gameplay clock", () => gameplayClock.IsPaused.Value = true);
|
AddStep("disable sample playback", () => skinSource.SamplePlaybackDisabled.Value = true);
|
||||||
AddUntilStep("wait for sample to stop playing", () => !sample.Playing);
|
AddUntilStep("wait for sample to stop playing", () => !sample.Playing);
|
||||||
|
|
||||||
AddStep("trigger skin change", () => skinSource.TriggerSourceChanged());
|
AddStep("trigger skin change", () => skinSource.TriggerSourceChanged());
|
||||||
@ -133,20 +134,25 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
});
|
});
|
||||||
|
|
||||||
AddAssert("new sample stopped", () => !sample.Playing);
|
AddAssert("new sample stopped", () => !sample.Playing);
|
||||||
AddStep("resume gameplay clock", () => gameplayClock.IsPaused.Value = false);
|
AddStep("enable sample playback", () => skinSource.SamplePlaybackDisabled.Value = false);
|
||||||
|
|
||||||
AddWaitStep("wait a bit", 5);
|
AddWaitStep("wait a bit", 5);
|
||||||
AddAssert("new sample not played", () => !sample.Playing);
|
AddAssert("new sample not played", () => !sample.Playing);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cached(typeof(ISkinSource))]
|
[Cached(typeof(ISkinSource))]
|
||||||
private class TestSkinSourceContainer : Container, ISkinSource
|
[Cached(typeof(ISamplePlaybackDisabler))]
|
||||||
|
private class TestSkinSourceContainer : Container, ISkinSource, ISamplePlaybackDisabler
|
||||||
{
|
{
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private ISkinSource source { get; set; }
|
private ISkinSource source { get; set; }
|
||||||
|
|
||||||
public event Action SourceChanged;
|
public event Action SourceChanged;
|
||||||
|
|
||||||
|
public Bindable<bool> SamplePlaybackDisabled { get; } = new Bindable<bool>();
|
||||||
|
|
||||||
|
IBindable<bool> ISamplePlaybackDisabler.SamplePlaybackDisabled => SamplePlaybackDisabled;
|
||||||
|
|
||||||
public Drawable GetDrawableComponent(ISkinComponent component) => source?.GetDrawableComponent(component);
|
public Drawable GetDrawableComponent(ISkinComponent component) => source?.GetDrawableComponent(component);
|
||||||
public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => source?.GetTexture(componentName, wrapModeS, wrapModeT);
|
public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => source?.GetTexture(componentName, wrapModeS, wrapModeT);
|
||||||
public SampleChannel GetSample(ISampleInfo sampleInfo) => source?.GetSample(sampleInfo);
|
public SampleChannel GetSample(ISampleInfo sampleInfo) => source?.GetSample(sampleInfo);
|
||||||
|
@ -18,8 +18,11 @@ namespace osu.Game.Rulesets.UI
|
|||||||
/// A container which consumes a parent gameplay clock and standardises frame counts for children.
|
/// A container which consumes a parent gameplay clock and standardises frame counts for children.
|
||||||
/// Will ensure a minimum of 50 frames per clock second is maintained, regardless of any system lag or seeks.
|
/// Will ensure a minimum of 50 frames per clock second is maintained, regardless of any system lag or seeks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class FrameStabilityContainer : Container, IHasReplayHandler
|
[Cached(typeof(ISamplePlaybackDisabler))]
|
||||||
|
public class FrameStabilityContainer : Container, IHasReplayHandler, ISamplePlaybackDisabler
|
||||||
{
|
{
|
||||||
|
private readonly Bindable<bool> samplePlaybackDisabled = new Bindable<bool>();
|
||||||
|
|
||||||
private readonly double gameplayStartTime;
|
private readonly double gameplayStartTime;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -35,7 +38,6 @@ namespace osu.Game.Rulesets.UI
|
|||||||
public GameplayClock GameplayClock => stabilityGameplayClock;
|
public GameplayClock GameplayClock => stabilityGameplayClock;
|
||||||
|
|
||||||
[Cached(typeof(GameplayClock))]
|
[Cached(typeof(GameplayClock))]
|
||||||
[Cached(typeof(ISamplePlaybackDisabler))]
|
|
||||||
private readonly StabilityGameplayClock stabilityGameplayClock;
|
private readonly StabilityGameplayClock stabilityGameplayClock;
|
||||||
|
|
||||||
public FrameStabilityContainer(double gameplayStartTime = double.MinValue)
|
public FrameStabilityContainer(double gameplayStartTime = double.MinValue)
|
||||||
@ -102,6 +104,8 @@ namespace osu.Game.Rulesets.UI
|
|||||||
requireMoreUpdateLoops = true;
|
requireMoreUpdateLoops = true;
|
||||||
validState = !GameplayClock.IsPaused.Value;
|
validState = !GameplayClock.IsPaused.Value;
|
||||||
|
|
||||||
|
samplePlaybackDisabled.Value = stabilityGameplayClock.ShouldDisableSamplePlayback;
|
||||||
|
|
||||||
int loops = 0;
|
int loops = 0;
|
||||||
|
|
||||||
while (validState && requireMoreUpdateLoops && loops++ < MaxCatchUpFrames)
|
while (validState && requireMoreUpdateLoops && loops++ < MaxCatchUpFrames)
|
||||||
@ -224,6 +228,8 @@ namespace osu.Game.Rulesets.UI
|
|||||||
|
|
||||||
public ReplayInputHandler ReplayInputHandler { get; set; }
|
public ReplayInputHandler ReplayInputHandler { get; set; }
|
||||||
|
|
||||||
|
IBindable<bool> ISamplePlaybackDisabler.SamplePlaybackDisabled => samplePlaybackDisabled;
|
||||||
|
|
||||||
private class StabilityGameplayClock : GameplayClock
|
private class StabilityGameplayClock : GameplayClock
|
||||||
{
|
{
|
||||||
public GameplayClock ParentGameplayClock;
|
public GameplayClock ParentGameplayClock;
|
||||||
@ -237,7 +243,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool ShouldDisableSamplePlayback =>
|
public override bool ShouldDisableSamplePlayback =>
|
||||||
// handle the case where playback is catching up to real-time.
|
// handle the case where playback is catching up to real-time.
|
||||||
base.ShouldDisableSamplePlayback
|
base.ShouldDisableSamplePlayback
|
||||||
|| ParentSampleDisabler?.SamplePlaybackDisabled.Value == true
|
|| ParentSampleDisabler?.SamplePlaybackDisabled.Value == true
|
||||||
|
@ -17,7 +17,7 @@ namespace osu.Game.Screens.Play
|
|||||||
/// <see cref="IFrameBasedClock"/>, as this should only be done once to ensure accuracy.
|
/// <see cref="IFrameBasedClock"/>, as this should only be done once to ensure accuracy.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GameplayClock : IFrameBasedClock, ISamplePlaybackDisabler
|
public class GameplayClock : IFrameBasedClock
|
||||||
{
|
{
|
||||||
private readonly IFrameBasedClock underlyingClock;
|
private readonly IFrameBasedClock underlyingClock;
|
||||||
|
|
||||||
@ -28,8 +28,6 @@ namespace osu.Game.Screens.Play
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual IEnumerable<Bindable<double>> NonGameplayAdjustments => Enumerable.Empty<Bindable<double>>();
|
public virtual IEnumerable<Bindable<double>> NonGameplayAdjustments => Enumerable.Empty<Bindable<double>>();
|
||||||
|
|
||||||
private readonly Bindable<bool> samplePlaybackDisabled = new Bindable<bool>();
|
|
||||||
|
|
||||||
public GameplayClock(IFrameBasedClock underlyingClock)
|
public GameplayClock(IFrameBasedClock underlyingClock)
|
||||||
{
|
{
|
||||||
this.underlyingClock = underlyingClock;
|
this.underlyingClock = underlyingClock;
|
||||||
@ -66,13 +64,11 @@ namespace osu.Game.Screens.Play
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether nested samples supporting the <see cref="ISamplePlaybackDisabler"/> interface should be paused.
|
/// Whether nested samples supporting the <see cref="ISamplePlaybackDisabler"/> interface should be paused.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual bool ShouldDisableSamplePlayback => IsPaused.Value;
|
public virtual bool ShouldDisableSamplePlayback => IsPaused.Value;
|
||||||
|
|
||||||
public void ProcessFrame()
|
public void ProcessFrame()
|
||||||
{
|
{
|
||||||
// intentionally not updating the underlying clock (handled externally).
|
// intentionally not updating the underlying clock (handled externally).
|
||||||
|
|
||||||
samplePlaybackDisabled.Value = ShouldDisableSamplePlayback;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public double ElapsedFrameTime => underlyingClock.ElapsedFrameTime;
|
public double ElapsedFrameTime => underlyingClock.ElapsedFrameTime;
|
||||||
@ -82,7 +78,5 @@ namespace osu.Game.Screens.Play
|
|||||||
public FrameTimeInfo TimeInfo => underlyingClock.TimeInfo;
|
public FrameTimeInfo TimeInfo => underlyingClock.TimeInfo;
|
||||||
|
|
||||||
public IClock Source => underlyingClock;
|
public IClock Source => underlyingClock;
|
||||||
|
|
||||||
IBindable<bool> ISamplePlaybackDisabler.SamplePlaybackDisabled => samplePlaybackDisabled;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,6 @@ namespace osu.Game.Screens.Play
|
|||||||
public GameplayClock GameplayClock => localGameplayClock;
|
public GameplayClock GameplayClock => localGameplayClock;
|
||||||
|
|
||||||
[Cached(typeof(GameplayClock))]
|
[Cached(typeof(GameplayClock))]
|
||||||
[Cached(typeof(ISamplePlaybackDisabler))]
|
|
||||||
private readonly LocalGameplayClock localGameplayClock;
|
private readonly LocalGameplayClock localGameplayClock;
|
||||||
|
|
||||||
private Bindable<double> userAudioOffset;
|
private Bindable<double> userAudioOffset;
|
||||||
|
@ -35,7 +35,8 @@ using osu.Game.Users;
|
|||||||
namespace osu.Game.Screens.Play
|
namespace osu.Game.Screens.Play
|
||||||
{
|
{
|
||||||
[Cached]
|
[Cached]
|
||||||
public class Player : ScreenWithBeatmapBackground
|
[Cached(typeof(ISamplePlaybackDisabler))]
|
||||||
|
public class Player : ScreenWithBeatmapBackground, ISamplePlaybackDisabler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The delay upon completion of the beatmap before displaying the results screen.
|
/// The delay upon completion of the beatmap before displaying the results screen.
|
||||||
@ -55,6 +56,8 @@ namespace osu.Game.Screens.Play
|
|||||||
// We are managing our own adjustments (see OnEntering/OnExiting).
|
// We are managing our own adjustments (see OnEntering/OnExiting).
|
||||||
public override bool AllowRateAdjustments => false;
|
public override bool AllowRateAdjustments => false;
|
||||||
|
|
||||||
|
private readonly Bindable<bool> samplePlaybackDisabled = new Bindable<bool>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether gameplay should pause when the game window focus is lost.
|
/// Whether gameplay should pause when the game window focus is lost.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -229,7 +232,11 @@ namespace osu.Game.Screens.Play
|
|||||||
skipOverlay.Hide();
|
skipOverlay.Hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawableRuleset.IsPaused.BindValueChanged(_ => updateGameplayState());
|
DrawableRuleset.IsPaused.BindValueChanged(paused =>
|
||||||
|
{
|
||||||
|
updateGameplayState();
|
||||||
|
samplePlaybackDisabled.Value = paused.NewValue;
|
||||||
|
});
|
||||||
DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updateGameplayState());
|
DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updateGameplayState());
|
||||||
|
|
||||||
DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true);
|
DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true);
|
||||||
@ -752,5 +759,7 @@ namespace osu.Game.Screens.Play
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
IBindable<bool> ISamplePlaybackDisabler.SamplePlaybackDisabled => samplePlaybackDisabled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user