Skip to content

Fix osu! logo suddenly disappearing during rapid exit #24424

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

Merged
merged 1 commit into from
Jul 31, 2023

Conversation

bdach
Copy link
Collaborator

@bdach bdach commented Jul 30, 2023

master:

2023-07-30.19-06-14.mp4

this PR:

2023-07-30.19-06-45.mp4

That particular part regressed in #24208. tl;dr: MainMenu wasn't returning the proxy to game on exit. Note that reproduction requires that any screen under MainMenu is navigated to; exiting from MainMenu itself will look fine.

You might ask why this isn't a problem if you exit slowly, but only shows up when exiting quickly; I have no idea after several hours of staring at ScreenStack. I got about as far as determining that during a slow exit, main menu will only be expired, but during a fast exit, it will be expired and then removed from hierarchy entirely. I don't know why.

I also don't know why this rotation doesn't play out all of the time. The kiai fountain PR didn't break that so I'm cutting my losses there. There's probably something that should be fixed in ScreenStack or in the weird logo arriving-suspending-exiting management flow but I'm attempting to be pragmatic here. If reviewers think that this PR is too much of a shortcut, then this can be closed I guess. Help debugging these complex systems would certainly be appreciated because I give up right now.

Comment on lines +206 to +207
[CanBeNull]
private Drawable proxiedLogo;
Copy link
Collaborator Author

@bdach bdach Jul 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Storing this is required because if you exit very fast, you can hit LogoExiting() without a prior LogoArriving(), thus dying at

Unhandled exception. System.InvalidOperationException: No usage to return
   at osu.Game.Screens.Menu.OsuLogo.ReturnProxy() in /home/dachb/Documents/opensource/osu/osu.Game/Screens/Menu/OsuLogo.cs:line 461
   at osu.Game.Screens.Menu.MainMenu.LogoExiting(OsuLogo logo) in /home/dachb/Documents/opensource/osu/osu.Game/Screens/Menu/MainMenu.cs:line 271
   at osu.Game.Screens.OsuScreen.<onExitingLogo>b__80_0() in /home/dachb/Documents/opensource/osu/osu.Game/Screens/OsuScreen.cs:line 265
   at osu.Game.Screens.Menu.OsuLogo.<>c__DisplayClass39_0.<AppendAnimatingAction>g__runnableAction|0() in /home/dachb/Documents/opensource/osu/osu.Game/Screens/Menu/OsuLogo.cs:line 256
   at osu.Game.Screens.Menu.OsuLogo.AppendAnimatingAction(Action action, Boolean waitForPrevious) in /home/dachb/Documents/opensource/osu/osu.Game/Screens/Menu/OsuLogo.cs:line 261
   at osu.Game.Screens.OsuScreen.onExitingLogo() in /home/dachb/Documents/opensource/osu/osu.Game/Screens/OsuScreen.cs:line 265
   at osu.Game.Screens.OsuScreen.OnExiting(ScreenExitEvent e) in /home/dachb/Documents/opensource/osu/osu.Game/Screens/OsuScreen.cs:line 230
   at osu.Game.Screens.Menu.MainMenu.OnExiting(ScreenExitEvent e) in /home/dachb/Documents/opensource/osu/osu.Game/Screens/Menu/MainMenu.cs:line 334
   at osu.Framework.Screens.ScreenStack.exitFrom(IScreen source, Boolean shouldFireExitEvent, Boolean shouldFireResumeEvent, IScreen destination)
   at osu.Framework.Screens.ScreenStack.Exit(IScreen source)
   at osu.Framework.Screens.ScreenExtensions.Exit(IScreen screen)
   at osu.Game.Screens.Menu.MainMenu.<OnExiting>b__62_0() in /home/dachb/Documents/opensource/osu/osu.Game/Screens/Menu/MainMenu.cs:line 318

Alternative would be making ReturnProxy() safely re-entrant I guess.

The reason why it is possible to receive exit without arrival is that resume-arrival gets appended to queue of actions potentially queued by previous screen, which exit disregards in favour of performing actions immediately:

private void applyArrivingDefaults(bool isResuming)
{
logo?.AppendAnimatingAction(() =>
{
if (this.IsCurrentScreen()) LogoArriving(logo, isResuming);
}, true);
}
private void onExitingLogo()
{
logo?.AppendAnimatingAction(() => LogoExiting(logo), false);
}

@peppy peppy merged commit 0e59cdc into ppy:master Jul 31, 2023
@bdach bdach deleted the exit-logo-hide branch July 31, 2023 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants