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

ScreenStack likely removes screens one frame too early #6518

Open
smoogipoo opened this issue Jan 31, 2025 · 1 comment
Open

ScreenStack likely removes screens one frame too early #6518

smoogipoo opened this issue Jan 31, 2025 · 1 comment

Comments

@smoogipoo
Copy link
Contributor

ScreenStack implements its own children life updates:

protected override bool UpdateChildrenLife()
{
if (!base.UpdateChildrenLife()) return false;
// In order to provide custom suspend/resume logic, screens always have RemoveWhenNotAlive set to false.
// We need to manually handle removal here (in the opposite order to how the screens were pushed to ensure bindable sanity).
if (exited.FirstOrDefault()?.IsAlive == false)
{
foreach (var s in exited)
{
RemoveInternal(s, false);
DisposeChildAsync(s);
}
exited.Clear();
}
return true;
}

When screens are exited they are .Expire()d, calculating their expiry time as LatestTransformEndTime:

if (source == null)
{
// This is the first screen that exited
toExit.AsDrawable().Expire();
}

Which means that the intended usage of screens is something like:

void OnExit()
{
    this.FadeOut(1000);
    // Expecting the screen to die after 1000ms.
}

The problem is that UpdateChildrenLife occurs prior to children being updated, which may cause unintended effects if the transforms aren't updated for the final time. It's likely fine for something like a FadeOut() because the final frame will already be at a low alpha value, but consider the following situation:

void OnExit()
{
    this.TransformBindableTo(audioVolumeBindable, 0, 1000);
}

In this case, the effect is not fine as it leaves the sample with >0 volume in the final frame.

This expiry process probably needs to be re-considered a bit, and this may even be an issue outside of screens too because the base UpdateChildrenLife() implementation works much the same way.

@peppy
Copy link
Member

peppy commented Feb 3, 2025

If/when this is fixed, we should revisit adding a global sound fade on OsuScreen (as proposed here). We aren't doing this for now because there's a small chance it will never fully perform the fade.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants