1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 21:02:55 +08:00

Merge pull request #7692 from peppy/safe-screen-lease

Ensure OsuScreen leases are taken out synchronously
This commit is contained in:
Dean Herbert 2020-02-03 18:57:39 +09:00 committed by GitHub
commit f5a38aff08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 80 additions and 37 deletions

View File

@ -68,10 +68,10 @@ namespace osu.Game.Tests.Visual.Background
[SetUp] [SetUp]
public virtual void SetUp() => Schedule(() => public virtual void SetUp() => Schedule(() =>
{ {
Child = new OsuScreenStack(songSelect = new DummySongSelect()) var stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both };
{ Child = stack;
RelativeSizeAxes = Axes.Both
}; stack.Push(songSelect = new DummySongSelect());
}); });
/// <summary> /// <summary>

View File

@ -207,9 +207,11 @@ namespace osu.Game.Tests.Visual.Gameplay
{ {
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
OsuScreenStack stack;
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{ {
new OsuScreenStack(screen) stack = new OsuScreenStack
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
}, },
@ -224,6 +226,8 @@ namespace osu.Game.Tests.Visual.Gameplay
Origin = Anchor.TopLeft, Origin = Anchor.TopLeft,
} }
}; };
stack.Push(screen);
} }
} }

View File

@ -75,10 +75,16 @@ namespace osu.Game.Tests.Visual.Gameplay
public void ResultsWithoutPlayer() public void ResultsWithoutPlayer()
{ {
TestSoloResults screen = null; TestSoloResults screen = null;
OsuScreenStack stack;
AddStep("load results", () => Child = new OsuScreenStack(screen = createResultsScreen()) AddStep("load results", () =>
{ {
RelativeSizeAxes = Axes.Both Child = stack = new OsuScreenStack
{
RelativeSizeAxes = Axes.Both
};
stack.Push(screen = createResultsScreen());
}); });
AddUntilStep("wait for loaded", () => screen.IsLoaded); AddUntilStep("wait for loaded", () => screen.IsLoaded);
AddAssert("retry overlay not present", () => screen.RetryOverlay == null); AddAssert("retry overlay not present", () => screen.RetryOverlay == null);
@ -102,11 +108,14 @@ namespace osu.Game.Tests.Visual.Gameplay
public TestResultsContainer(IScreen screen) public TestResultsContainer(IScreen screen)
{ {
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
OsuScreenStack stack;
InternalChild = new OsuScreenStack(screen) InternalChild = stack = new OsuScreenStack
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
}; };
stack.Push(screen);
} }
} }

View File

@ -31,7 +31,7 @@ namespace osu.Game.Tests.Visual.Menus
protected IntroTestScene() protected IntroTestScene()
{ {
Drawable introStack = null; OsuScreenStack introStack = null;
Children = new Drawable[] Children = new Drawable[]
{ {
@ -57,10 +57,12 @@ namespace osu.Game.Tests.Visual.Menus
introStack?.Expire(); introStack?.Expire();
Add(introStack = new OsuScreenStack(CreateScreen()) Add(introStack = new OsuScreenStack
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
}); });
introStack.Push(CreateScreen());
}); });
} }

View File

@ -16,7 +16,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
{ {
int index = 0; int index = 0;
OsuScreenStack screenStack = new OsuScreenStack(new TestMultiplayerSubScreen(index)) { RelativeSizeAxes = Axes.Both }; OsuScreenStack screenStack = new OsuScreenStack { RelativeSizeAxes = Axes.Both };
screenStack.Push(new TestMultiplayerSubScreen(index));
Children = new Drawable[] Children = new Drawable[]
{ {

View File

@ -25,7 +25,9 @@ namespace osu.Game.Tests.Visual.UserInterface
OsuSpriteText titleText; OsuSpriteText titleText;
IScreen startScreen = new TestScreenOne(); IScreen startScreen = new TestScreenOne();
screenStack = new OsuScreenStack(startScreen) { RelativeSizeAxes = Axes.Both };
screenStack = new OsuScreenStack { RelativeSizeAxes = Axes.Both };
screenStack.Push(startScreen);
Children = new Drawable[] Children = new Drawable[]
{ {

View File

@ -17,7 +17,8 @@ namespace osu.Game.Graphics.UserInterface
stack.ScreenPushed += onPushed; stack.ScreenPushed += onPushed;
stack.ScreenExited += onExited; stack.ScreenExited += onExited;
onPushed(null, stack.CurrentScreen); if (stack.CurrentScreen != null)
onPushed(null, stack.CurrentScreen);
Current.ValueChanged += current => current.NewValue.MakeCurrent(); Current.ValueChanged += current => current.NewValue.MakeCurrent();
} }

View File

@ -96,7 +96,7 @@ namespace osu.Game.Screens.Multi
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Top = Header.HEIGHT }, Padding = new MarginPadding { Top = Header.HEIGHT },
Child = screenStack = new OsuScreenStack(loungeSubScreen = new LoungeSubScreen()) { RelativeSizeAxes = Axes.Both } Child = screenStack = new OsuScreenStack { RelativeSizeAxes = Axes.Both }
}, },
new Header(screenStack), new Header(screenStack),
createButton = new HeaderButton createButton = new HeaderButton
@ -120,6 +120,8 @@ namespace osu.Game.Screens.Multi
} }
}; };
screenStack.Push(loungeSubScreen = new LoungeSubScreen());
screenStack.ScreenPushed += screenPushed; screenStack.ScreenPushed += screenPushed;
screenStack.ScreenExited += screenExited; screenStack.ScreenExited += screenExited;
} }

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// 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.Collections.Generic; using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Internal;
using osu.Framework.Allocation; using osu.Framework.Allocation;
@ -95,15 +96,30 @@ namespace osu.Game.Screens
public Bindable<IReadOnlyList<Mod>> Mods { get; private set; } public Bindable<IReadOnlyList<Mod>> Mods { get; private set; }
private OsuScreenDependencies screenDependencies;
internal void CreateLeasedDependencies(IReadOnlyDependencyContainer dependencies) => createDependencies(dependencies);
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
{ {
var screenDependencies = new OsuScreenDependencies(DisallowExternalBeatmapRulesetChanges, parent); if (screenDependencies == null)
{
if (DisallowExternalBeatmapRulesetChanges)
throw new InvalidOperationException($"Screens that specify {nameof(DisallowExternalBeatmapRulesetChanges)} must be pushed immediately.");
createDependencies(parent);
}
return base.CreateChildDependencies(screenDependencies);
}
private void createDependencies(IReadOnlyDependencyContainer dependencies)
{
screenDependencies = new OsuScreenDependencies(DisallowExternalBeatmapRulesetChanges, dependencies);
Beatmap = screenDependencies.Beatmap; Beatmap = screenDependencies.Beatmap;
Ruleset = screenDependencies.Ruleset; Ruleset = screenDependencies.Ruleset;
Mods = screenDependencies.Mods; Mods = screenDependencies.Mods;
return base.CreateChildDependencies(screenDependencies);
} }
protected BackgroundScreen Background => backgroundStack?.CurrentScreen as BackgroundScreen; protected BackgroundScreen Background => backgroundStack?.CurrentScreen as BackgroundScreen;

View File

@ -13,22 +13,11 @@ namespace osu.Game.Screens
[Cached] [Cached]
private BackgroundScreenStack backgroundScreenStack; private BackgroundScreenStack backgroundScreenStack;
private ParallaxContainer parallaxContainer; private readonly ParallaxContainer parallaxContainer;
protected float ParallaxAmount => parallaxContainer.ParallaxAmount; protected float ParallaxAmount => parallaxContainer.ParallaxAmount;
public OsuScreenStack() public OsuScreenStack()
{
initializeStack();
}
public OsuScreenStack(IScreen baseScreen)
: base(baseScreen)
{
initializeStack();
}
private void initializeStack()
{ {
InternalChild = parallaxContainer = new ParallaxContainer InternalChild = parallaxContainer = new ParallaxContainer
{ {
@ -36,13 +25,32 @@ namespace osu.Game.Screens
Child = backgroundScreenStack = new BackgroundScreenStack { RelativeSizeAxes = Axes.Both }, Child = backgroundScreenStack = new BackgroundScreenStack { RelativeSizeAxes = Axes.Both },
}; };
ScreenPushed += onScreenChange; ScreenPushed += screenPushed;
ScreenExited += onScreenChange; ScreenExited += screenExited;
} }
private void onScreenChange(IScreen prev, IScreen next) private void screenPushed(IScreen prev, IScreen next)
{ {
parallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * ((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f; if (LoadState < LoadState.Ready)
{
// dependencies must be present to stay in a sane state.
// this is generally only ever hit by test scenes.
Schedule(() => screenPushed(prev, next));
return;
}
// create dependencies synchronously to ensure leases are in a sane state.
((OsuScreen)next).CreateLeasedDependencies((prev as OsuScreen)?.Dependencies ?? Dependencies);
setParallax(next);
} }
private void screenExited(IScreen prev, IScreen next)
{
setParallax(next);
}
private void setParallax(IScreen next) =>
parallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * ((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f;
} }
} }

View File

@ -68,10 +68,7 @@ namespace osu.Game.Screens.Select
SampleConfirm?.Play(); SampleConfirm?.Play();
LoadComponentAsync(player = new PlayerLoader(() => new Player()), l => this.Push(player = new PlayerLoader(() => new Player()));
{
if (this.IsCurrentScreen()) this.Push(player);
});
return true; return true;
} }