Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make quick restart even faster #30603

Merged
merged 4 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ public void TestQuickRetry()
AddUntilStep("restart completed", () => getCurrentPlayer() != null && getCurrentPlayer() != previousPlayer);
AddStep("release quick retry key", () => InputManager.ReleaseKey(Key.Tilde));

AddUntilStep("wait for player", () => getCurrentPlayer()?.LoadState == LoadState.Ready);
AddUntilStep("wait for player", () => getCurrentPlayer()?.LoadState >= LoadState.Ready);

AddUntilStep("time reached zero", () => getCurrentPlayer()?.GameplayClockContainer.CurrentTime > 0);
AddUntilStep("skip button not visible", () => !checkSkipButtonVisible());
Expand Down
101 changes: 69 additions & 32 deletions osu.Game/Screens/Play/PlayerLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Input;
Expand Down Expand Up @@ -51,6 +52,8 @@ public partial class PlayerLoader : ScreenWithBeatmapBackground

public override bool? AllowGlobalTrackControl => false;

public override float BackgroundParallaxAmount => quickRestart ? 0 : 1;

// Here because IsHovered will not update unless we do so.
public override bool HandlePositionalInput => true;

Expand Down Expand Up @@ -86,9 +89,13 @@ public partial class PlayerLoader : ScreenWithBeatmapBackground

private SkinnableSound sampleRestart = null!;

private Box? quickRestartBlackLayer;

[Cached]
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple);

private const double quick_restart_initial_delay = 500;

protected bool BackgroundBrightnessReduction
{
set
Expand Down Expand Up @@ -305,6 +312,9 @@ public override void OnSuspending(ScreenTransitionEvent e)
{
base.OnSuspending(e);

quickRestartBlackLayer?.FadeOut(500, Easing.OutQuint).Expire();
quickRestartBlackLayer = null;

BackgroundBrightnessReduction = false;

// we're moving to player, so a period of silence is upcoming.
Expand Down Expand Up @@ -348,7 +358,14 @@ protected override void LogoArriving(OsuLogo logo, bool resuming)
if (!resuming) logo.MoveTo(new Vector2(0.5f), duration, Easing.OutQuint);

logo.ScaleTo(new Vector2(0.15f), duration, Easing.OutQuint);
logo.FadeIn(350);

if (quickRestart)
{
logo.Delay(quick_restart_initial_delay)
.FadeIn(350);
}
else
logo.FadeIn(350);

Scheduler.AddDelayed(() =>
{
Expand Down Expand Up @@ -387,7 +404,7 @@ protected override void Update()

// We need to perform this check here rather than in OnHover as any number of children of VisualSettings
// may also be handling the hover events.
if (inputManager.HoveredDrawables.Contains(VisualSettings))
if (inputManager.HoveredDrawables.Contains(VisualSettings) || quickRestart)
{
// Preview user-defined background dim and blur when hovered on the visual settings panel.
ApplyToBackground(b =>
Expand Down Expand Up @@ -454,28 +471,45 @@ private void contentIn(double delayBeforeSideDisplays = 0)
{
MetadataInfo.Loading = true;

content.FadeInFromZero(500, Easing.OutQuint);

if (quickRestart)
{
// A quick restart starts by triggering a fade to black
AddInternal(quickRestartBlackLayer = new Box
{
Colour = Color4.Black,
RelativeSizeAxes = Axes.Both,
Depth = float.MaxValue
});

quickRestartBlackLayer
.Delay(50)
.FadeOut(5000, Easing.OutQuint);

prepareNewPlayer();
content.ScaleTo(1, 650, Easing.OutQuint);

content
.Delay(quick_restart_initial_delay)
.ScaleTo(1)
.FadeInFromZero(500, Easing.OutQuint);
}
else
{
content.FadeInFromZero(500, Easing.OutQuint);

content
.ScaleTo(0.7f)
.ScaleTo(1, 650, Easing.OutQuint)
.Then()
.Schedule(prepareNewPlayer);
}

using (BeginDelayedSequence(delayBeforeSideDisplays))
{
settingsScroll.FadeInFromZero(500, Easing.Out)
.MoveToX(0, 500, Easing.OutQuint);
using (BeginDelayedSequence(delayBeforeSideDisplays))
{
settingsScroll.FadeInFromZero(500, Easing.Out)
.MoveToX(0, 500, Easing.OutQuint);

disclaimers.FadeInFromZero(500, Easing.Out)
.MoveToX(0, 500, Easing.OutQuint);
disclaimers.FadeInFromZero(500, Easing.Out)
.MoveToX(0, 500, Easing.OutQuint);
}
}

AddRangeInternal(new[]
Expand Down Expand Up @@ -539,33 +573,36 @@ private void pushWhenLoaded()
highPerformanceSession ??= highPerformanceSessionManager?.BeginSession();

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();
{
// 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(0);
TransformSequence<PlayerLoader> pushSequence = this.Delay(0);

// This goes hand-in-hand with the restoration of low pass filter in contentOut().
this.TransformBindableTo(volumeAdjustment, 0, CONTENT_OUT_DURATION, Easing.OutCubic);
// This goes hand-in-hand with the restoration of low pass filter in contentOut().
this.TransformBindableTo(volumeAdjustment, 0, CONTENT_OUT_DURATION, Easing.OutCubic);

pushSequence.Schedule(() =>
{
if (!this.IsCurrentScreen()) return;
pushSequence.Schedule(() =>
{
if (!this.IsCurrentScreen()) return;

LoadTask = null;
LoadTask = null;

// By default, we want to load the player and never be returned to.
// Note that this may change if the player we load requested a re-run.
ValidForResume = false;
// By default, we want to load the player and never be returned to.
// Note that this may change if the player we load requested a re-run.
ValidForResume = false;

if (consumedPlayer.LoadedBeatmapSuccessfully)
this.Push(consumedPlayer);
else
this.Exit();
});
}, 500);
if (consumedPlayer.LoadedBeatmapSuccessfully)
this.Push(consumedPlayer);
else
this.Exit();
});
},
// When a quick restart is activated, the metadata content will display some time later if it's taking too long.
// To avoid it appearing too briefly, if it begins to fade in let's induce a standard delay.
quickRestart && content.Alpha == 0 ? 0 : 500);
bdach marked this conversation as resolved.
Show resolved Hide resolved
}

private void cancelLoad()
Expand Down
Loading