From 8cad09370d527dd421c2383790459f1fc258943e Mon Sep 17 00:00:00 2001 From: ocboogie Date: Wed, 12 Apr 2017 00:20:41 -0700 Subject: [PATCH 1/8] Fixed pause and fail screen overlap --- osu.Game/Screens/Play/Player.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index e2712a64e4..2a18d44248 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -273,6 +273,11 @@ namespace osu.Game.Screens.Play private void onFail() { + if (IsPaused) + { + pauseOverlay.Hide(); + IsPaused = false; + } sourceClock.Stop(); Delay(500); From 348dd7140662e164d103afeda23c621363c1e443 Mon Sep 17 00:00:00 2001 From: ocboogie Date: Wed, 12 Apr 2017 02:43:42 -0700 Subject: [PATCH 2/8] Fixed repeat keys working for resuming --- osu.Game/Screens/Play/PauseOverlay.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Play/PauseOverlay.cs b/osu.Game/Screens/Play/PauseOverlay.cs index f9706d263e..6088e2fea5 100644 --- a/osu.Game/Screens/Play/PauseOverlay.cs +++ b/osu.Game/Screens/Play/PauseOverlay.cs @@ -20,6 +20,7 @@ namespace osu.Game.Screens.Play protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { + if (args.Repeat) return false; if (args.Key == Key.Escape) { if (State == Visibility.Hidden) return false; From d250dde537ff671321c5f845da50cff64790af58 Mon Sep 17 00:00:00 2001 From: ocboogie Date: Wed, 12 Apr 2017 02:50:03 -0700 Subject: [PATCH 3/8] Fixed repeat keys working for retrying --- osu.Game/Screens/Play/FailOverlay.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Play/FailOverlay.cs b/osu.Game/Screens/Play/FailOverlay.cs index 7a32e19338..1cd34e45e7 100644 --- a/osu.Game/Screens/Play/FailOverlay.cs +++ b/osu.Game/Screens/Play/FailOverlay.cs @@ -17,6 +17,7 @@ namespace osu.Game.Screens.Play public override string Description => "you're dead, try again?"; protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { + if (args.Repeat) return false; if (args.Key == Key.Escape) { if (State == Visibility.Hidden) return false; From 6c6ef946bde3fc2cdd357d1dfb0b361af49919fe Mon Sep 17 00:00:00 2001 From: ocboogie Date: Wed, 12 Apr 2017 04:01:52 -0700 Subject: [PATCH 4/8] Some more clean up --- osu.Game/Screens/Play/FailOverlay.cs | 12 --------- osu.Game/Screens/Play/PauseOverlay.cs | 1 - osu.Game/Screens/Play/Player.cs | 36 +++++++-------------------- 3 files changed, 9 insertions(+), 40 deletions(-) diff --git a/osu.Game/Screens/Play/FailOverlay.cs b/osu.Game/Screens/Play/FailOverlay.cs index 1cd34e45e7..1c0e01201e 100644 --- a/osu.Game/Screens/Play/FailOverlay.cs +++ b/osu.Game/Screens/Play/FailOverlay.cs @@ -15,18 +15,6 @@ namespace osu.Game.Screens.Play public override string Header => "failed"; public override string Description => "you're dead, try again?"; - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) - { - if (args.Repeat) return false; - if (args.Key == Key.Escape) - { - if (State == Visibility.Hidden) return false; - OnQuit(); - return true; - } - - return base.OnKeyDown(state, args); - } [BackgroundDependencyLoader] private void load(OsuColour colours) diff --git a/osu.Game/Screens/Play/PauseOverlay.cs b/osu.Game/Screens/Play/PauseOverlay.cs index 6088e2fea5..c8439b33e0 100644 --- a/osu.Game/Screens/Play/PauseOverlay.cs +++ b/osu.Game/Screens/Play/PauseOverlay.cs @@ -23,7 +23,6 @@ namespace osu.Game.Screens.Play if (args.Repeat) return false; if (args.Key == Key.Escape) { - if (State == Visibility.Hidden) return false; OnResume(); return true; } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 2a18d44248..2ae809a7c2 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -35,7 +35,7 @@ namespace osu.Game.Screens.Play public BeatmapInfo BeatmapInfo; - public bool IsPaused { get; private set; } + public bool IsPaused => !sourceClock.IsRunning; public bool HasFailed { get; private set; } @@ -204,19 +204,13 @@ namespace osu.Game.Screens.Play public void Pause(bool force = false) { - if (canPause || force) - { - lastPauseActionTime = Time.Current; - hudOverlay.KeyCounter.IsCounting = false; - pauseOverlay.Retries = RestartCount; - pauseOverlay.Show(); - sourceClock.Stop(); - IsPaused = true; - } - else - { - IsPaused = false; - } + if (!canPause && !force) return; + + lastPauseActionTime = Time.Current; + hudOverlay.KeyCounter.IsCounting = false; + pauseOverlay.Retries = RestartCount; + pauseOverlay.Show(); + sourceClock.Stop(); } public void Resume() @@ -225,13 +219,6 @@ namespace osu.Game.Screens.Play hudOverlay.KeyCounter.IsCounting = true; pauseOverlay.Hide(); sourceClock.Start(); - IsPaused = false; - } - - public void TogglePaused() - { - IsPaused = !IsPaused; - if (IsPaused) Pause(); else Resume(); } public void Restart() @@ -273,11 +260,6 @@ namespace osu.Game.Screens.Play private void onFail() { - if (IsPaused) - { - pauseOverlay.Hide(); - IsPaused = false; - } sourceClock.Stop(); Delay(500); @@ -331,7 +313,7 @@ namespace osu.Game.Screens.Play //pause screen override logic. if (pauseOverlay?.State == Visibility.Hidden && !canPause) return true; - if (!IsPaused && sourceClock.IsRunning) // For if the user presses escape quickly when entering the map + if (!IsPaused) // For if the user presses escape quickly when entering the map { Pause(); return true; From 32b87d12b58ce23133f83fcd437e7ceca2e5d2ca Mon Sep 17 00:00:00 2001 From: ocboogie Date: Wed, 12 Apr 2017 04:54:24 -0700 Subject: [PATCH 5/8] Removed unneeded `using` --- osu.Game/Screens/Play/FailOverlay.cs | 3 --- osu.Game/Screens/Play/PauseOverlay.cs | 1 - 2 files changed, 4 deletions(-) diff --git a/osu.Game/Screens/Play/FailOverlay.cs b/osu.Game/Screens/Play/FailOverlay.cs index 1c0e01201e..3225695cb7 100644 --- a/osu.Game/Screens/Play/FailOverlay.cs +++ b/osu.Game/Screens/Play/FailOverlay.cs @@ -1,9 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Graphics.Containers; -using osu.Framework.Input; -using OpenTK.Input; using osu.Game.Graphics; using OpenTK.Graphics; using osu.Framework.Allocation; diff --git a/osu.Game/Screens/Play/PauseOverlay.cs b/osu.Game/Screens/Play/PauseOverlay.cs index c8439b33e0..3b06b1c84f 100644 --- a/osu.Game/Screens/Play/PauseOverlay.cs +++ b/osu.Game/Screens/Play/PauseOverlay.cs @@ -5,7 +5,6 @@ using System; using osu.Framework.Input; using osu.Game.Graphics; using OpenTK.Input; -using osu.Framework.Graphics.Containers; using OpenTK.Graphics; using osu.Framework.Allocation; From 94bf1d65b617a8d3c9d40078be0b51440bf14f80 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Apr 2017 11:41:08 +0900 Subject: [PATCH 6/8] Fix thread race conditions on pausing close to a fail. --- osu.Game/Screens/Play/Player.cs | 36 ++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 2ae809a7c2..1bab7cddde 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens.Play private const double pause_cooldown = 1000; private double lastPauseActionTime; - private bool canPause => Time.Current >= lastPauseActionTime + pause_cooldown; + private bool canPause => ValidForResume && !HasFailed && Time.Current >= lastPauseActionTime + pause_cooldown; private IAdjustableClock sourceClock; private IFrameBasedClock interpolatedSourceClock; @@ -206,11 +206,28 @@ namespace osu.Game.Screens.Play { if (!canPause && !force) return; - lastPauseActionTime = Time.Current; - hudOverlay.KeyCounter.IsCounting = false; - pauseOverlay.Retries = RestartCount; - pauseOverlay.Show(); sourceClock.Stop(); + + // the actual pausing is potentially happening on a different thread. + // we want to wait for the source clock to stop so we can be sure all components are in a stable state. + if (!IsPaused) + { + Schedule(() => Pause(force)); + return; + } + + // 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 last processed frame (which would change canPause). + // as the scheduler runs before children updates, let's schedule for the next frame. + Schedule(() => + { + if (!canPause) return; + + lastPauseActionTime = Time.Current; + hudOverlay.KeyCounter.IsCounting = false; + pauseOverlay.Retries = RestartCount; + pauseOverlay.Show(); + }); } public void Resume() @@ -227,11 +244,11 @@ namespace osu.Game.Screens.Play var newPlayer = new Player(); + ValidForResume = false; + LoadComponentAsync(newPlayer, delegate { newPlayer.RestartCount = RestartCount + 1; - ValidForResume = false; - if (!Push(newPlayer)) { // Error(?) @@ -247,10 +264,11 @@ namespace osu.Game.Screens.Play if (scoreProcessor.HasFailed || onCompletionEvent != null) return; + ValidForResume = false; + Delay(1000); onCompletionEvent = Schedule(delegate { - ValidForResume = false; Push(new Results { Score = scoreProcessor.CreateScore() @@ -262,8 +280,6 @@ namespace osu.Game.Screens.Play { sourceClock.Stop(); - Delay(500); - HasFailed = true; failOverlay.Retries = RestartCount; failOverlay.Show(); From 5f8baf874dd6907d612fdde8b7d6485d24678e93 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Apr 2017 18:31:23 +0900 Subject: [PATCH 7/8] Use interpolatedSourceClock's IsRunning value for consistency. --- osu.Game/Screens/Play/Player.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 1bab7cddde..7f43ae2ac3 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -35,7 +35,7 @@ namespace osu.Game.Screens.Play public BeatmapInfo BeatmapInfo; - public bool IsPaused => !sourceClock.IsRunning; + public bool IsPaused => !interpolatedSourceClock.IsRunning; public bool HasFailed { get; private set; } @@ -206,12 +206,12 @@ namespace osu.Game.Screens.Play { if (!canPause && !force) return; - sourceClock.Stop(); - // the actual pausing is potentially happening on a different thread. // we want to wait for the source clock to stop so we can be sure all components are in a stable state. if (!IsPaused) { + sourceClock.Stop(); + Schedule(() => Pause(force)); return; } From 262a2c9f0e093b416d1f0b61083ec5dae119624c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Apr 2017 19:01:15 +0900 Subject: [PATCH 8/8] Add exception for failing. --- osu.Game/Screens/Play/Player.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 7f43ae2ac3..01d5d0770a 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -324,6 +324,9 @@ namespace osu.Game.Screens.Play protected override bool OnExiting(Screen next) { + if (HasFailed || !ValidForResume) + return false; + if (pauseOverlay != null && !HitRenderer.HasReplayLoaded) { //pause screen override logic.