Merge pull request #11137 from peppy/fix-player-load-stuck-at-empty-screen

This commit is contained in:
Bartłomiej Dach
2020-12-11 21:22:12 +01:00
committed by GitHub

View File

@ -2,6 +2,7 @@
// 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.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations; using JetBrains.Annotations;
@ -71,8 +72,9 @@ namespace osu.Game.Screens.Play
} }
private bool readyForPush => private bool readyForPush =>
!playerConsumed
// don't push unless the player is completely loaded // don't push unless the player is completely loaded
player?.LoadState == LoadState.Ready && player?.LoadState == LoadState.Ready
// don't push if the user is hovering one of the panes, unless they are idle. // don't push if the user is hovering one of the panes, unless they are idle.
&& (IsHovered || idleTracker.IsIdle.Value) && (IsHovered || idleTracker.IsIdle.Value)
// don't push if the user is dragging a slider or otherwise. // don't push if the user is dragging a slider or otherwise.
@ -84,6 +86,11 @@ namespace osu.Game.Screens.Play
private Player player; private Player player;
/// <summary>
/// Whether the curent player instance has been consumed via <see cref="consumePlayer"/>.
/// </summary>
private bool playerConsumed;
private LogoTrackingContainer content; private LogoTrackingContainer content;
private bool hideOverlays; private bool hideOverlays;
@ -179,7 +186,10 @@ namespace osu.Game.Screens.Play
contentIn(); contentIn();
MetadataInfo.Delay(750).FadeIn(500); MetadataInfo.Delay(750).FadeIn(500);
this.Delay(1800).Schedule(pushWhenLoaded);
// after an initial delay, start the debounced load check.
// this will continue to execute even after resuming back on restart.
Scheduler.Add(new ScheduledDelegate(pushWhenLoaded, 1800, 0));
showMuteWarningIfNeeded(); showMuteWarningIfNeeded();
} }
@ -188,17 +198,18 @@ namespace osu.Game.Screens.Play
{ {
base.OnResuming(last); base.OnResuming(last);
contentIn(); // prepare for a retry.
player = null;
playerConsumed = false;
cancelLoad();
this.Delay(400).Schedule(pushWhenLoaded); contentIn();
} }
public override void OnSuspending(IScreen next) public override void OnSuspending(IScreen next)
{ {
base.OnSuspending(next); base.OnSuspending(next);
cancelLoad();
BackgroundBrightnessReduction = false; BackgroundBrightnessReduction = false;
// we're moving to player, so a period of silence is upcoming. // we're moving to player, so a period of silence is upcoming.
@ -274,6 +285,14 @@ namespace osu.Game.Screens.Play
} }
} }
private Player consumePlayer()
{
Debug.Assert(!playerConsumed);
playerConsumed = true;
return player;
}
private void prepareNewPlayer() private void prepareNewPlayer()
{ {
if (!this.IsCurrentScreen()) if (!this.IsCurrentScreen())
@ -315,8 +334,6 @@ namespace osu.Game.Screens.Play
{ {
if (!this.IsCurrentScreen()) return; if (!this.IsCurrentScreen()) return;
try
{
if (!readyForPush) if (!readyForPush)
{ {
// as the pushDebounce below has a delay, we need to keep checking and cancel a future debounce // as the pushDebounce below has a delay, we need to keep checking and cancel a future debounce
@ -325,11 +342,16 @@ namespace osu.Game.Screens.Play
return; return;
} }
// if a push has already been scheduled, no further action is required.
// this value is reset via cancelLoad() to allow a second usage of the same PlayerLoader screen.
if (scheduledPushPlayer != null) if (scheduledPushPlayer != null)
return; return;
scheduledPushPlayer = Scheduler.AddDelayed(() => scheduledPushPlayer = Scheduler.AddDelayed(() =>
{ {
// ensure that once we have reached this "point of no return", readyForPush will be false for all future checks (until a new player instance is prepared).
var consumedPlayer = consumePlayer();
contentOut(); contentOut();
TransformSequence<PlayerLoader> pushSequence = this.Delay(250); TransformSequence<PlayerLoader> pushSequence = this.Delay(250);
@ -362,18 +384,13 @@ namespace osu.Game.Screens.Play
// Note that this may change if the player we load requested a re-run. // Note that this may change if the player we load requested a re-run.
ValidForResume = false; ValidForResume = false;
if (player.LoadedBeatmapSuccessfully) if (consumedPlayer.LoadedBeatmapSuccessfully)
this.Push(player); this.Push(consumedPlayer);
else else
this.Exit(); this.Exit();
}); });
}, 500); }, 500);
} }
finally
{
Schedule(pushWhenLoaded);
}
}
private void cancelLoad() private void cancelLoad()
{ {
@ -390,7 +407,7 @@ namespace osu.Game.Screens.Play
if (isDisposing) if (isDisposing)
{ {
// if the player never got pushed, we should explicitly dispose it. // if the player never got pushed, we should explicitly dispose it.
DisposalTask = LoadTask?.ContinueWith(_ => player.Dispose()); DisposalTask = LoadTask?.ContinueWith(_ => player?.Dispose());
} }
} }