1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-15 18:13:09 +08:00

Use bindable flow instead

This commit is contained in:
Dean Herbert 2020-10-27 14:10:12 +09:00
parent 6853da459d
commit 9cfb81589e
6 changed files with 46 additions and 39 deletions

View File

@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.Mods
private OsuInputManager inputManager; private OsuInputManager inputManager;
private GameplayClock gameplayClock; private IFrameStableClock gameplayClock;
private List<OsuReplayFrame> replayFrames; private List<OsuReplayFrame> replayFrames;

View File

@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.UI
public override Container FrameStableComponents { get; } = new Container { RelativeSizeAxes = Axes.Both }; public override Container FrameStableComponents { get; } = new Container { RelativeSizeAxes = Axes.Both };
public override FrameStableClock FrameStableClock => frameStabilityContainer.FrameStableClock; public override IFrameStableClock FrameStableClock => frameStabilityContainer.FrameStableClock;
private bool frameStablePlayback = true; private bool frameStablePlayback = true;
@ -404,7 +404,7 @@ namespace osu.Game.Rulesets.UI
/// <summary> /// <summary>
/// The frame-stable clock which is being used for playfield display. /// The frame-stable clock which is being used for playfield display.
/// </summary> /// </summary>
public abstract FrameStableClock FrameStableClock { get; } public abstract IFrameStableClock FrameStableClock { get; }
/// <summary>~ /// <summary>~
/// The associated ruleset. /// The associated ruleset.

View File

@ -2,7 +2,10 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Timing; using osu.Framework.Timing;
@ -29,14 +32,16 @@ namespace osu.Game.Rulesets.UI
/// </summary> /// </summary>
internal bool FrameStablePlayback = true; internal bool FrameStablePlayback = true;
public IFrameStableClock FrameStableClock => frameStableClock;
[Cached(typeof(GameplayClock))] [Cached(typeof(GameplayClock))]
public readonly FrameStableClock FrameStableClock; private readonly FrameStabilityClock frameStableClock;
public FrameStabilityContainer(double gameplayStartTime = double.MinValue) public FrameStabilityContainer(double gameplayStartTime = double.MinValue)
{ {
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
FrameStableClock = new FrameStableClock(framedClock = new FramedClock(manualClock = new ManualClock())); frameStableClock = new FrameStabilityClock(framedClock = new FramedClock(manualClock = new ManualClock()));
this.gameplayStartTime = gameplayStartTime; this.gameplayStartTime = gameplayStartTime;
} }
@ -57,8 +62,8 @@ namespace osu.Game.Rulesets.UI
{ {
if (clock != null) if (clock != null)
{ {
parentGameplayClock = FrameStableClock.ParentGameplayClock = clock; parentGameplayClock = frameStableClock.ParentGameplayClock = clock;
FrameStableClock.IsPaused.BindTo(clock.IsPaused); frameStableClock.IsPaused.BindTo(clock.IsPaused);
} }
} }
@ -91,7 +96,7 @@ namespace osu.Game.Rulesets.UI
public override bool UpdateSubTree() public override bool UpdateSubTree()
{ {
requireMoreUpdateLoops = true; requireMoreUpdateLoops = true;
validState = !FrameStableClock.IsPaused.Value; validState = !frameStableClock.IsPaused.Value;
int loops = 0; int loops = 0;
@ -194,6 +199,8 @@ namespace osu.Game.Rulesets.UI
requireMoreUpdateLoops |= manualClock.CurrentTime != parentGameplayClock.CurrentTime; requireMoreUpdateLoops |= manualClock.CurrentTime != parentGameplayClock.CurrentTime;
frameStableClock.IsCatchingUp.Value = requireMoreUpdateLoops;
// The manual clock time has changed in the above code. The framed clock now needs to be updated // The manual clock time has changed in the above code. The framed clock now needs to be updated
// to ensure that the its time is valid for our children before input is processed // to ensure that the its time is valid for our children before input is processed
framedClock.ProcessFrame(); framedClock.ProcessFrame();
@ -209,10 +216,26 @@ namespace osu.Game.Rulesets.UI
} }
else else
{ {
Clock = FrameStableClock; Clock = frameStableClock;
} }
} }
public ReplayInputHandler ReplayInputHandler { get; set; } public ReplayInputHandler ReplayInputHandler { get; set; }
private class FrameStabilityClock : GameplayClock, IFrameStableClock
{
public GameplayClock ParentGameplayClock;
public readonly Bindable<bool> IsCatchingUp = new Bindable<bool>();
public override IEnumerable<Bindable<double>> NonGameplayAdjustments => ParentGameplayClock?.NonGameplayAdjustments ?? Enumerable.Empty<Bindable<double>>();
public FrameStabilityClock(FramedClock underlyingClock)
: base(underlyingClock)
{
}
IBindable<bool> IFrameStableClock.IsCatchingUp => IsCatchingUp;
}
} }
} }

View File

@ -1,28 +1,13 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Timing; using osu.Framework.Timing;
using osu.Game.Screens.Play;
namespace osu.Game.Rulesets.UI namespace osu.Game.Rulesets.UI
{ {
public class FrameStableClock : GameplayClock public interface IFrameStableClock : IFrameBasedClock
{ {
public GameplayClock ParentGameplayClock; IBindable<bool> IsCatchingUp { get; }
public override IEnumerable<Bindable<double>> NonGameplayAdjustments => ParentGameplayClock?.NonGameplayAdjustments ?? Enumerable.Empty<Bindable<double>>();
public FrameStableClock(FramedClock underlyingClock)
: base(underlyingClock)
{
}
public override bool ShouldDisableSamplePlayback =>
// handle the case where playback is catching up to real-time.
base.ShouldDisableSamplePlayback || (ParentGameplayClock != null && Math.Abs(CurrentTime - ParentGameplayClock.CurrentTime) > 200);
} }
} }

View File

@ -61,11 +61,6 @@ namespace osu.Game.Screens.Play
public bool IsRunning => underlyingClock.IsRunning; public bool IsRunning => underlyingClock.IsRunning;
/// <summary>
/// Whether nested samples supporting the <see cref="ISamplePlaybackDisabler"/> interface should be paused.
/// </summary>
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).

View File

@ -238,7 +238,13 @@ namespace osu.Game.Screens.Play
skipOverlay.Hide(); skipOverlay.Hide();
} }
DrawableRuleset.IsPaused.BindValueChanged(_ => updateGameplayState()); DrawableRuleset.IsPaused.BindValueChanged(paused =>
{
updateGameplayState();
updateSampleDisabledState();
});
DrawableRuleset.FrameStableClock.IsCatchingUp.BindValueChanged(_ => updateSampleDisabledState());
DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updateGameplayState()); DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updateGameplayState());
@ -367,13 +373,6 @@ namespace osu.Game.Screens.Play
} }
}; };
protected override void Update()
{
base.Update();
samplePlaybackDisabled.Value = DrawableRuleset.FrameStableClock.ShouldDisableSamplePlayback;
}
private void onBreakTimeChanged(ValueChangedEvent<bool> isBreakTime) private void onBreakTimeChanged(ValueChangedEvent<bool> isBreakTime)
{ {
updateGameplayState(); updateGameplayState();
@ -388,6 +387,11 @@ namespace osu.Game.Screens.Play
LocalUserPlaying.Value = inGameplay; LocalUserPlaying.Value = inGameplay;
} }
private void updateSampleDisabledState()
{
samplePlaybackDisabled.Value = DrawableRuleset.FrameStableClock.IsCatchingUp.Value || GameplayClockContainer.GameplayClock.IsPaused.Value;
}
private void updatePauseOnFocusLostState() => private void updatePauseOnFocusLostState() =>
HUDOverlay.HoldToQuit.PauseOnFocusLost = PauseOnFocusLost HUDOverlay.HoldToQuit.PauseOnFocusLost = PauseOnFocusLost
&& !DrawableRuleset.HasReplayLoaded.Value && !DrawableRuleset.HasReplayLoaded.Value