Merge pull request #1412 from peppy/startup-load-improvements

Improve startup load times by sequentially loading components
This commit is contained in:
Dan Balasescu
2017-10-24 12:10:13 +09:00
committed by GitHub
4 changed files with 49 additions and 45 deletions

View File

@ -12,15 +12,12 @@ using osu.Desktop.Overlays;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Game; using osu.Game;
using osu.Game.Screens.Menu;
using OpenTK.Input; using OpenTK.Input;
namespace osu.Desktop namespace osu.Desktop
{ {
internal class OsuGameDesktop : OsuGame internal class OsuGameDesktop : OsuGame
{ {
private VersionManager versionManager;
public OsuGameDesktop(string[] args = null) public OsuGameDesktop(string[] args = null)
: base(args) : base(args)
{ {
@ -82,16 +79,11 @@ namespace osu.Desktop
{ {
base.LoadComplete(); base.LoadComplete();
LoadComponentAsync(versionManager = new VersionManager { Depth = int.MinValue }); LoadComponentAsync(new VersionManager { Depth = int.MinValue }, v =>
ScreenChanged += s =>
{ {
if (s is Intro && s.ChildScreen == null) Add(v);
{ v.State = Visibility.Visible;
Add(versionManager); });
versionManager.State = Visibility.Visible;
}
};
} }
public override void SetHost(GameHost host) public override void SetHost(GameHost host)

View File

@ -157,40 +157,49 @@ namespace osu.Game
BeatmapManager.PostNotification = n => notificationOverlay?.Post(n); BeatmapManager.PostNotification = n => notificationOverlay?.Post(n);
BeatmapManager.GetStableStorage = GetStorageForStableInstall; BeatmapManager.GetStableStorage = GetStorageForStableInstall;
AddRange(new Drawable[] { AddRange(new Drawable[]
{
new VolumeControlReceptor new VolumeControlReceptor
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
ActionRequested = action => volume.Adjust(action) ActionRequested = action => volume.Adjust(action)
}, },
mainContent = new Container mainContent = new Container { RelativeSizeAxes = Axes.Both },
{ overlayContent = new Container { RelativeSizeAxes = Axes.Both, Depth = float.MinValue },
RelativeSizeAxes = Axes.Both,
},
volume = new VolumeControl(),
overlayContent = new Container { RelativeSizeAxes = Axes.Both },
new OnScreenDisplay(),
}); });
LoadComponentAsync(screenStack = new Loader(), d => loadComponentSingleFile(screenStack = new Loader(), d =>
{ {
screenStack.ModePushed += screenAdded; screenStack.ModePushed += screenAdded;
screenStack.Exited += screenRemoved; screenStack.Exited += screenRemoved;
mainContent.Add(screenStack); mainContent.Add(screenStack);
}); });
loadComponentSingleFile(Toolbar = new Toolbar
{
Depth = -5,
OnHome = delegate
{
hideAllOverlays();
intro?.ChildScreen?.MakeCurrent();
},
}, overlayContent.Add);
loadComponentSingleFile(volume = new VolumeControl(), AddInternal);
loadComponentSingleFile(new OnScreenDisplay(), AddInternal);
//overlay elements //overlay elements
LoadComponentAsync(direct = new DirectOverlay { Depth = -1 }, mainContent.Add); loadComponentSingleFile(direct = new DirectOverlay { Depth = -1 }, mainContent.Add);
LoadComponentAsync(social = new SocialOverlay { Depth = -1 }, mainContent.Add); loadComponentSingleFile(social = new SocialOverlay { Depth = -1 }, mainContent.Add);
LoadComponentAsync(chat = new ChatOverlay { Depth = -1 }, mainContent.Add); loadComponentSingleFile(chat = new ChatOverlay { Depth = -1 }, mainContent.Add);
LoadComponentAsync(settings = new MainSettings loadComponentSingleFile(settings = new MainSettings
{ {
GetToolbarHeight = () => ToolbarOffset, GetToolbarHeight = () => ToolbarOffset,
Depth = -1 Depth = -1
}, overlayContent.Add); }, overlayContent.Add);
LoadComponentAsync(userProfile = new UserProfileOverlay { Depth = -2 }, mainContent.Add); loadComponentSingleFile(userProfile = new UserProfileOverlay { Depth = -2 }, mainContent.Add);
LoadComponentAsync(beatmapSetOverlay = new BeatmapSetOverlay { Depth = -3 }, mainContent.Add); loadComponentSingleFile(beatmapSetOverlay = new BeatmapSetOverlay { Depth = -3 }, mainContent.Add);
LoadComponentAsync(musicController = new MusicController loadComponentSingleFile(musicController = new MusicController
{ {
Depth = -4, Depth = -4,
Position = new Vector2(0, Toolbar.HEIGHT), Position = new Vector2(0, Toolbar.HEIGHT),
@ -198,16 +207,16 @@ namespace osu.Game
Origin = Anchor.TopRight, Origin = Anchor.TopRight,
}, overlayContent.Add); }, overlayContent.Add);
LoadComponentAsync(notificationOverlay = new NotificationOverlay loadComponentSingleFile(notificationOverlay = new NotificationOverlay
{ {
Depth = -4, Depth = -4,
Anchor = Anchor.TopRight, Anchor = Anchor.TopRight,
Origin = Anchor.TopRight, Origin = Anchor.TopRight,
}, overlayContent.Add); }, overlayContent.Add);
LoadComponentAsync(dialogOverlay = new DialogOverlay loadComponentSingleFile(dialogOverlay = new DialogOverlay
{ {
Depth = -5, Depth = -6,
}, overlayContent.Add); }, overlayContent.Add);
Logger.NewEntry += entry => Logger.NewEntry += entry =>
@ -246,16 +255,6 @@ namespace osu.Game
}; };
} }
LoadComponentAsync(Toolbar = new Toolbar
{
Depth = -4,
OnHome = delegate
{
hideAllOverlays();
intro?.ChildScreen?.MakeCurrent();
},
}, overlayContent.Add);
settings.StateChanged += delegate settings.StateChanged += delegate
{ {
switch (settings.State) switch (settings.State)
@ -272,6 +271,17 @@ namespace osu.Game
Cursor.State = Visibility.Hidden; Cursor.State = Visibility.Hidden;
} }
private Task asyncLoadStream;
private void loadComponentSingleFile<T>(T d, Action<T> add)
where T : Drawable
{
// schedule is here to ensure that all component loads are done after LoadComplete is run (and thus all dependencies are cached).
// with some better organisation of LoadComplete to do construction and dependency caching in one step, followed by calls to loadComponentSingleFile,
// we could avoid the need for scheduling altogether.
Schedule(() => { asyncLoadStream = asyncLoadStream?.ContinueWith(t => LoadComponentAsync(d, add).Wait()) ?? LoadComponentAsync(d, add); });
}
public bool OnPressed(GlobalAction action) public bool OnPressed(GlobalAction action)
{ {
if (intro == null) return false; if (intro == null) return false;

View File

@ -1,6 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Primitives;
@ -11,11 +12,12 @@ namespace osu.Game.Overlays.Toolbar
internal class ToolbarUserArea : Container internal class ToolbarUserArea : Container
{ {
public LoginOverlay LoginOverlay; public LoginOverlay LoginOverlay;
private readonly ToolbarUserButton button; private ToolbarUserButton button;
public override RectangleF BoundingBox => button.BoundingBox; public override RectangleF BoundingBox => button.BoundingBox;
public ToolbarUserArea() [BackgroundDependencyLoader]
private void load()
{ {
RelativeSizeAxes = Axes.Y; RelativeSizeAxes = Axes.Y;
AutoSizeAxes = Axes.X; AutoSizeAxes = Axes.X;
@ -36,4 +38,4 @@ namespace osu.Game.Overlays.Toolbar
}; };
} }
} }
} }