1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-15 10:02:59 +08:00

Rework PauseContainer to better pause

This commit is contained in:
Dean Herbert 2018-02-27 16:02:57 +09:00
parent d4f1723ae6
commit fee258f2f2
2 changed files with 39 additions and 39 deletions

View File

@ -44,14 +44,21 @@ namespace osu.Game.Screens.Play
public Action OnResume;
public Action OnPause;
public IAdjustableClock AudioClock;
public FramedClock FramedClock;
public readonly IAdjustableClock SeekableClock;
public readonly FramedClock FramedClock;
public PauseContainer()
public PauseContainer(FramedClock framedClock, IAdjustableClock seekableClock)
{
FramedClock = framedClock;
SeekableClock = seekableClock;
RelativeSizeAxes = Axes.Both;
AddInternal(content = new Container { RelativeSizeAxes = Axes.Both });
AddInternal(content = new Container
{
Clock = FramedClock,
RelativeSizeAxes = Axes.Both
});
AddInternal(pauseOverlay = new PauseOverlay
{
@ -65,47 +72,37 @@ namespace osu.Game.Screens.Play
});
}
public void Pause(bool force = false)
public void Pause(bool force = false) => Schedule(() => // Scheduled to ensure a stable position in execution order, no matter how it was called.
{
if (!CanPause && !force) return;
if (IsPaused) return;
// stop the decoupled clock (stops the audio eventually)
AudioClock.Stop();
// stop processing updatess on the offset clock (instantly freezes time for all our components)
FramedClock.ProcessSourceClockFrames = false;
// stop the seekable clock (stops the audio eventually)
SeekableClock.Stop();
IsPaused = true;
// we need to do a final check after all of our children have processed up to the paused clock time.
// this is to cover cases where, for instance, the player fails in the current processing frame.
Schedule(() =>
{
if (!CanPause) return;
OnPause?.Invoke();
pauseOverlay.Show();
lastPauseActionTime = Time.Current;
OnPause?.Invoke();
pauseOverlay.Show();
});
}
lastPauseActionTime = Time.Current;
});
public void Resume()
{
if (!IsPaused) return;
IsPaused = false;
FramedClock.ProcessSourceClockFrames = true;
IsResuming = false;
lastPauseActionTime = Time.Current;
OnResume?.Invoke();
// seek back to the time of the framed clock.
// this accounts for the audio clock potentially taking time to enter a completely stopped state.
SeekableClock.Seek(FramedClock.CurrentTime);
SeekableClock.Start();
OnResume?.Invoke();
pauseOverlay.Hide();
AudioClock.Start();
IsResuming = false;
}
private OsuGameBase game;
@ -122,6 +119,9 @@ namespace osu.Game.Screens.Play
if (!game.IsActive && CanPause)
Pause();
if (!IsPaused)
FramedClock.ProcessFrame();
base.Update();
}

View File

@ -158,16 +158,8 @@ namespace osu.Game.Screens.Play
Children = new Drawable[]
{
storyboardContainer = new Container
pauseContainer = new PauseContainer(offsetClock, decoupledClock)
{
RelativeSizeAxes = Axes.Both,
Clock = offsetClock,
Alpha = 0,
},
pauseContainer = new PauseContainer
{
AudioClock = decoupledClock,
FramedClock = offsetClock,
OnRetry = Restart,
OnQuit = Exit,
CheckCanPause = () => AllowPause && ValidForResume && !HasFailed && !RulesetContainer.HasReplayLoaded,
@ -183,7 +175,15 @@ namespace osu.Game.Screens.Play
{
RelativeSizeAxes = Axes.Both,
Clock = offsetClock,
Child = RulesetContainer,
Children = new[]
{
storyboardContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
},
RulesetContainer,
}
},
new SkipButton(firstObjectTime)
{
@ -338,7 +338,9 @@ namespace osu.Game.Screens.Play
this.Delay(750).Schedule(() =>
{
if (!pauseContainer.IsPaused)
{
decoupledClock.Start();
}
});
});
});
@ -365,9 +367,7 @@ namespace osu.Game.Screens.Play
}
if (loadedSuccessfully)
{
pauseContainer?.Pause();
}
return true;
}