feat: adding loaded future to the component (#1466)

* feat: adding loaded future to the component

* fix: flame flare example game

* docs

* Update doc/flame/components.md

Co-authored-by: Lukas Klingsbo <me@lukas.fyi>

Co-authored-by: Lukas Klingsbo <me@lukas.fyi>
This commit is contained in:
Erick
2022-03-18 14:45:21 -03:00
committed by GitHub
parent 4ddd90aafc
commit 6434829b45
4 changed files with 47 additions and 7 deletions

View File

@ -36,6 +36,11 @@ throughout the component's lifetime. This method will only run if the parent is
If the parent is not mounted yet, then this method will wait in a queue (this will have no effect
on the rest of the game engine).
A component lifecycle state can be checked by a series of getters:
- `isLoaded`: Returns a bool with the current loaded state
- `loaded`: Returns a future that will complete once the component has finished loading
- `isMounted`: Returns a bool with the current mounted state
- `mounted`: Returns a future that will complete once the component has finished mounting
### Priority

View File

@ -54,6 +54,7 @@ class Component {
ComponentSet? _children;
Completer<void>? _mountCompleter;
Completer<void>? _loadCompleter;
@protected
_LifecycleManager get lifecycle {
@ -208,6 +209,17 @@ class Component {
/// the lifetime of the [Component] object. Do not call this method manually.
Future<void>? onLoad() => null;
/// A future that will complete once this component has finished loading.
Future<void> get loaded {
if (isLoaded) {
return Future.value();
}
_loadCompleter ??= Completer<void>();
return _loadCompleter!.future;
}
/// Called when the component is added to its parent.
///
/// This method only runs when the component is fully loaded, i.e. after
@ -420,6 +432,7 @@ class Component {
} else {
return onLoadFuture.then((_) {
_state = LifecycleState.loaded;
_loadCompleter?.complete();
});
}
return null;

View File

@ -93,6 +93,30 @@ void main() {
},
);
flameGame.test('component loaded completes', (game) async {
final component = _MyComponent();
await game.add(component);
final loaded = component.loaded;
await game.ready();
return expectLater(loaded, completes);
});
flameGame.test(
'component loaded completes even after the '
'component is already loaded',
(game) async {
final component = _MyComponent();
await game.add(component);
await game.ready();
final loaded = component.loaded;
return expectLater(loaded, completes);
},
);
// Obsolete scenario, when we used to have a separate "prepare" stage
flameGame.test('parent prepares the component', (game) async {
final parent = _MyComponent('parent');

View File

@ -19,8 +19,6 @@ class MyGame extends FlameGame with TapDetector, DoubleTapDetector {
late final MinionComponent minionComponent;
bool loaded = false;
@override
Future<void> onLoad() async {
add(BGComponent());