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

Tidy up Player's container loading logic

Fixes drawable ruleset being loaded before skin sources are finished, by loading them as a separate operation (to avoid children being loaded first).
This commit is contained in:
Dean Herbert 2019-08-27 18:27:21 +09:00
parent db987c6077
commit 7aeeb65ae7
4 changed files with 49 additions and 38 deletions

View File

@ -45,12 +45,11 @@ namespace osu.Game.Rulesets.Osu.Tests
private Drawable createProvider(Skin skin, Func<Drawable> creationFunction)
{
var mainProvider = new SkinProvidingContainer(skin) { RelativeSizeAxes = Axes.Both };
var mainProvider = new SkinProvidingContainer(skin);
return mainProvider
.WithChild(new SkinProvidingContainer(Ruleset.Value.CreateInstance().CreateLegacySkinProvider(mainProvider))
{
RelativeSizeAxes = Axes.Both,
Child = creationFunction()
});
}

View File

@ -44,7 +44,6 @@ namespace osu.Game.Rulesets.Osu.UI
// Todo: Remove when hitobjects are properly pooled
new SkinProvidingContainer(null)
{
RelativeSizeAxes = Axes.Both,
Child = HitObjectContainer,
},
approachCircles = new ApproachCircleProxyContainer

View File

@ -123,30 +123,53 @@ namespace osu.Game.Screens.Play
InternalChild = GameplayClockContainer = new GameplayClockContainer(working, Mods.Value, DrawableRuleset.GameplayStartTime);
SkinProvidingContainer skinProvidingContainer = new BeatmapSkinProvidingContainer(working.Skin)
{
RelativeSizeAxes = Axes.Both,
};
addUnderlayComponents(GameplayClockContainer);
addGameplayComponents(GameplayClockContainer, working);
addOverlayComponents(GameplayClockContainer, working);
GameplayClockContainer.Children = new[]
DrawableRuleset.HasReplayLoaded.BindValueChanged(e => HUDOverlay.HoldToQuit.PauseOnFocusLost = !e.NewValue && PauseOnFocusLost, true);
// bind clock into components that require it
DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused);
// Bind ScoreProcessor to ourselves
ScoreProcessor.AllJudged += onCompletion;
ScoreProcessor.Failed += onFail;
foreach (var mod in Mods.Value.OfType<IApplicableToScoreProcessor>())
mod.ApplyToScoreProcessor(ScoreProcessor);
}
private void addUnderlayComponents(Container target)
{
target.Add(DimmableStoryboard = new DimmableStoryboard(Beatmap.Value.Storyboard) { RelativeSizeAxes = Axes.Both });
}
private void addGameplayComponents(Container target, WorkingBeatmap working)
{
var beatmapSkinProvider = new BeatmapSkinProvidingContainer(working.Skin);
// the beatmapSkinProvider is used as the fallback source here to allow the ruleset-specific skin implementation
// full access to all skin sources.
var rulesetSkinProvider = new SkinProvidingContainer(ruleset.CreateLegacySkinProvider(beatmapSkinProvider));
// load the skinning hierarchy first.
// this is intentionally done in two stages to ensure things are in a loaded state before exposing the ruleset to skin sources.
target.Add(new ScalingContainer(ScalingMode.Gameplay)
.WithChild(beatmapSkinProvider
.WithChild(target = rulesetSkinProvider)));
target.AddRange(new Drawable[]
{
DrawableRuleset,
new ComboEffects(ScoreProcessor)
});
}
private void addOverlayComponents(Container target, WorkingBeatmap working)
{
target.AddRange(new[]
{
DimmableStoryboard = new DimmableStoryboard(Beatmap.Value.Storyboard) { RelativeSizeAxes = Axes.Both },
new ScalingContainer(ScalingMode.Gameplay)
{
Child = skinProvidingContainer.WithChild(
// the skinProvidingContainer is used as the fallback source here to allow the ruleset-specific skin implementation
// full access to all skin sources.
new SkinProvidingContainer(ruleset.CreateLegacySkinProvider(skinProvidingContainer))
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
DrawableRuleset,
new ComboEffects(ScoreProcessor)
}
}
)
},
breakOverlay = new BreakOverlay(working.Beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor)
{
Anchor = Anchor.Centre,
@ -205,19 +228,7 @@ namespace osu.Game.Screens.Play
},
},
failAnimation = new FailAnimation(DrawableRuleset) { OnComplete = onFailComplete, }
};
DrawableRuleset.HasReplayLoaded.BindValueChanged(e => HUDOverlay.HoldToQuit.PauseOnFocusLost = !e.NewValue && PauseOnFocusLost, true);
// bind clock into components that require it
DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused);
// Bind ScoreProcessor to ourselves
ScoreProcessor.AllJudged += onCompletion;
ScoreProcessor.Failed += onFail;
foreach (var mod in Mods.Value.OfType<IApplicableToScoreProcessor>())
mod.ApplyToScoreProcessor(ScoreProcessor);
});
}
private WorkingBeatmap loadBeatmap()

View File

@ -32,6 +32,8 @@ namespace osu.Game.Skinning
public SkinProvidingContainer(ISkin skin)
{
this.skin = skin;
RelativeSizeAxes = Axes.Both;
}
public Drawable GetDrawableComponent(string componentName)