-
Notifications
You must be signed in to change notification settings - Fork 441
Asynchronous loading
osu-framework
puts a lot of focus on non-blocking loading, striving to never block the interface threads at any point. It is therefore recommended (and in some cases forced) that you use async patterns when loading components.
It is recommended that any larger components are preloaded ahead of time. For instance, after a user has arrived on a menu screen, loading could begin on the next screen(s) that will be displayed.
The simplest method to load a component in the background is by calling LoadComponentAsync
from inside a Drawable
. This method also exposes a callback which can be used to perform an action when loading completes, which can be useful for showing a newly loading component as soon as it is ready.
Instantly using the component:
LoadComponentAsync(new MyComponent(), Add);
Preloading for future use:
var myComponent = new MyComponent();
LoadComponentAsync(myComponent);
...
Add(myComponent); // note that this will cause a blocking load if the async load has not yet completed.
This method returns a Task
which can be blocked on with Task.Wait()
if you need custom blocking behaviour.
When a component is loaded, it will attempt to load all nested children that have ShouldBeAlive == true
. To make use of this chaining, ensure that all loading code is either in the ctor
or a private method marked with the [BackgroundDependencyLoader]
attribute. The latter is recommended as it avoids a potential overhead when constructing new instances of the component that aren't nested in an asynchronous load.
public class MainComponent : CompositeDrawable
{
[BackgroundDependencyLoader]
private void load()
{
Child = new NestedComponent();
// this could also be in the ctor if required, but generally use BDL wherever possible for maximum efficiency.
}
}
public class NestedComponent : Drawable
{
[BackgroundDependencyLoader]
private void load()
{
// long running load
}
}
The following call could then be used to load MainComponent
and NestedComponent
asynchronously, only adding MainCompoent when the nested tree is completely loaded.
LoadComponentAsync(new MainComponent(), Add);
Some classes come with pre-built asynchronous behaviours. One example is Screen
, which automatically loads a child screen that is Push
ed if it is not already in a loaded state. Overriding such asynchronous behaviour can be achieved as mentioned above, by manually blocking on a preload call:
var blocking = new BlockingScreen();
LoadComponentAsync(blocking).Wait();
screenStack.Push(blocking);
- Create your first project
- Learning framework key bindings
- Adding resource stores
- Adding custom key bindings
- Adding custom fonts