diff --git a/.github/.cspell/dart_dictionary.txt b/.github/.cspell/dart_dictionary.txt index 66c0dcc8210..3a0eef43893 100644 --- a/.github/.cspell/dart_dictionary.txt +++ b/.github/.cspell/dart_dictionary.txt @@ -4,3 +4,4 @@ dartdoc # documentation tool for dart dartdocs # plural of dartdoc endtemplate # Use @endtemplate to close a @template block in dartdoc pubspec # dependency and configuration file of every Dart project +unawaited # dart:async helper to mark a Future as intentionally not awaited diff --git a/doc/bridge_packages/flame_behaviors/getting_started.md b/doc/bridge_packages/flame_behaviors/getting_started.md index c7db80385fd..61c8b41ed93 100644 --- a/doc/bridge_packages/flame_behaviors/getting_started.md +++ b/doc/bridge_packages/flame_behaviors/getting_started.md @@ -94,7 +94,7 @@ For instance a `TimerComponent` can implement a time-based behavioral activity: class MyBehavior extends Behavior { @override Future onLoad() async { - await add(TimerComponent(period: 5, repeat: true, onTick: _onTick)); + add(TimerComponent(period: 5, repeat: true, onTick: _onTick)); } void _onTick() { diff --git a/doc/bridge_packages/flame_bloc/bloc.md b/doc/bridge_packages/flame_bloc/bloc.md index da1075df905..403e5f5baac 100644 --- a/doc/bridge_packages/flame_bloc/bloc.md +++ b/doc/bridge_packages/flame_bloc/bloc.md @@ -22,7 +22,7 @@ We can do that by using `FlameBlocProvider` component: class MyGame extends FlameGame { @override Future onLoad() async { - await add( + add( FlameBlocProvider( create: () => PlayerInventoryBloc(), children: [ @@ -44,7 +44,7 @@ fashion: class MyGame extends FlameGame { @override Future onLoad() async { - await add( + add( FlameMultiBlocProvider( providers: [ FlameBlocProvider( @@ -72,7 +72,7 @@ By using `FlameBlocListener` component: class Player extends PositionComponent { @override Future onLoad() async { - await add( + add( FlameBlocListener( listener: (state) { updateGear(state); diff --git a/doc/bridge_packages/flame_spine/flame_spine.md b/doc/bridge_packages/flame_spine/flame_spine.md index 58943a6c8c1..87c13dc5fd8 100644 --- a/doc/bridge_packages/flame_spine/flame_spine.md +++ b/doc/bridge_packages/flame_spine/flame_spine.md @@ -40,7 +40,7 @@ class FlameSpineExample extends FlameGame { // Set the "walk" animation on track 0 in looping mode spineboy.animationState.setAnimationByName(0, 'walk', true); - await add(spineboy); + add(spineboy); } @override diff --git a/doc/flame/components/components.md b/doc/flame/components/components.md index f02935f0a4c..28a28bca599 100644 --- a/doc/flame/components/components.md +++ b/doc/flame/components/components.md @@ -212,6 +212,19 @@ class MyGame extends FlameGame { The two approaches can be combined freely: the children specified within the constructor will be added first, and then any additional child components after. +The `add()`, `addAll()`, and `addToParent()` methods are synchronous: they return immediately +without waiting for the child to load or mount. This makes them safe to call from anywhere, +including inside `update()` or a loop that spawns many components, without having to `await` them +or wrap them in `unawaited`. If you need to wait until a child has reached a given lifecycle stage, +await its `loaded`, `mounted`, or `removed` future instead (see the lifecycle getters under +[Component lifecycle](#component-lifecycle)): + +```dart +world.add(coin); +await coin.mounted; +// The coin is now guaranteed to be mounted. +``` + Note that the children added via either method are only guaranteed to be available eventually: after they are loaded and mounted. We can only assure that they will appear in the children list in the same order as they were scheduled for addition. diff --git a/doc/flame/examples/lib/anchor.dart b/doc/flame/examples/lib/anchor.dart index 48d3d63aeb1..eec4b18ce62 100644 --- a/doc/flame/examples/lib/anchor.dart +++ b/doc/flame/examples/lib/anchor.dart @@ -25,12 +25,12 @@ class AnchorGame extends FlameGame { paint: BasicPalette.blue.paint(), ); - await _redComponent.addAll([ + _redComponent.addAll([ _blueComponent, CircleComponent(radius: 2, anchor: Anchor.center), ]); - await addAll([ + addAll([ _redComponent, _parentAnchorText, _childAnchorText, diff --git a/doc/flame/examples/lib/time_scale.dart b/doc/flame/examples/lib/time_scale.dart index 7183e1d9a3a..e0ba9b59cc2 100644 --- a/doc/flame/examples/lib/time_scale.dart +++ b/doc/flame/examples/lib/time_scale.dart @@ -10,7 +10,7 @@ class TimeScaleGame extends FlameGame with HasTimeScale { @override Future onLoad() async { - await add( + add( EmberPlayer( position: size / 2, size: size / 4, diff --git a/doc/flame/game.md b/doc/flame/game.md index 9a3de14ace2..5020bfe83bb 100644 --- a/doc/flame/game.md +++ b/doc/flame/game.md @@ -38,8 +38,8 @@ class MyCrate extends SpriteComponent { class MyWorld extends World { @override - Future onLoad() async { - await add(MyCrate()); + void onLoad() { + add(MyCrate()); } } @@ -236,8 +236,8 @@ application. This is a common scenario when building games: there is a single fu Adding this mixin provides performance advantages in certain scenarios. In particular, a component's `onLoad` method is guaranteed to start when that component is added to its parent, even if the -parent is not yet mounted itself. Consequently, `await`-ing on `parent.add(component)` is guaranteed -to always finish loading the component. +parent is not yet mounted itself. Consequently, awaiting `component.loaded` after +`parent.add(component)` is guaranteed to finish loading the component. Using this mixin is simple: diff --git a/doc/tutorials/platformer/app/lib/overlays/hud.dart b/doc/tutorials/platformer/app/lib/overlays/hud.dart index c658e6e8323..e2c1cc9d0f6 100644 --- a/doc/tutorials/platformer/app/lib/overlays/hud.dart +++ b/doc/tutorials/platformer/app/lib/overlays/hud.dart @@ -44,7 +44,7 @@ class Hud extends PositionComponent with HasGameReference { for (var i = 1; i <= game.health; i++) { final positionX = 40 * i; - await add( + add( HeartHealthComponent( heartNumber: i, position: Vector2(positionX.toDouble(), 20), diff --git a/doc/tutorials/platformer/step_6.md b/doc/tutorials/platformer/step_6.md index 0441f53c660..533f2cee05b 100644 --- a/doc/tutorials/platformer/step_6.md +++ b/doc/tutorials/platformer/step_6.md @@ -128,7 +128,7 @@ class Hud extends PositionComponent with HasGameReference { for (var i = 1; i <= game.health; i++) { final positionX = 40 * i; - await add( + add( HeartHealthComponent( heartNumber: i, position: Vector2(positionX.toDouble(), 20), diff --git a/examples/games/crystal_ball/lib/src/game/components/camera_target.dart b/examples/games/crystal_ball/lib/src/game/components/camera_target.dart index e2b6b26314f..22eac0b4acc 100644 --- a/examples/games/crystal_ball/lib/src/game/components/camera_target.dart +++ b/examples/games/crystal_ball/lib/src/game/components/camera_target.dart @@ -14,7 +14,7 @@ class CameraTarget extends PositionComponent @override Future onLoad() async { - await add(moveEffect); + add(moveEffect); } void go({ diff --git a/examples/games/crystal_ball/lib/src/game/components/input_handler.dart b/examples/games/crystal_ball/lib/src/game/components/input_handler.dart index bf74df733e8..fc3358436e3 100644 --- a/examples/games/crystal_ball/lib/src/game/components/input_handler.dart +++ b/examples/games/crystal_ball/lib/src/game/components/input_handler.dart @@ -14,7 +14,7 @@ class InputHandler extends PositionComponent @override Future onLoad() async { - await add( + add( KeyboardListenerComponent( keyDown: { LogicalKeyboardKey.arrowLeft: (_) => onLeftStart(), diff --git a/examples/lib/stories/animations/benchmark_example.dart b/examples/lib/stories/animations/benchmark_example.dart index a6421f8d367..85dc2014129 100644 --- a/examples/lib/stories/animations/benchmark_example.dart +++ b/examples/lib/stories/animations/benchmark_example.dart @@ -20,7 +20,7 @@ starts to drop in FPS, this is without any sprite batching and such. @override Future onLoad() async { - await camera.viewport.addAll([ + camera.viewport.addAll([ FpsTextComponent( position: size - Vector2(10, 50), anchor: Anchor.bottomRight, diff --git a/examples/lib/stories/bridge_libraries/flame_forge2d/blob_example.dart b/examples/lib/stories/bridge_libraries/flame_forge2d/blob_example.dart index 6e5f177b78b..0553de08906 100644 --- a/examples/lib/stories/bridge_libraries/flame_forge2d/blob_example.dart +++ b/examples/lib/stories/bridge_libraries/flame_forge2d/blob_example.dart @@ -29,10 +29,12 @@ class BlobWorld extends Forge2DWorld ..dampingRatio = 1.0 ..collideConnected = false; - await addAll([ + final blobParts = [ for (var i = 0; i < 20; i++) BlobPart(i, jointDef, blobRadius, blobCenter), - ]); + ]; + addAll(blobParts); + await Future.wait(blobParts.map((part) => part.loaded)); createJoint(ConstantVolumeJoint(physicsWorld, jointDef)); } diff --git a/examples/lib/stories/bridge_libraries/flame_forge2d/joints/rope_joint.dart b/examples/lib/stories/bridge_libraries/flame_forge2d/joints/rope_joint.dart index ab79b2a0b08..7bfbd2b4c1b 100644 --- a/examples/lib/stories/bridge_libraries/flame_forge2d/joints/rope_joint.dart +++ b/examples/lib/stories/bridge_libraries/flame_forge2d/joints/rope_joint.dart @@ -36,7 +36,8 @@ class RopeJointWorld extends Forge2DWorld width: handleWidth, height: 3, ); - await add(box); + add(box); + await box.loaded; createPrismaticJoint(box.body, anchor); return box.body; @@ -49,7 +50,8 @@ class RopeJointWorld extends Forge2DWorld for (var i = 0; i < length; i++) { final newPosition = prevBody.worldCenter + Vector2(0, 1); final ball = Ball(newPosition, radius: 0.5, color: Colors.white); - await add(ball); + add(ball); + await ball.loaded; createRopeJoint(ball.body, prevBody); prevBody = ball.body; diff --git a/examples/lib/stories/bridge_libraries/flame_forge2d/joints/weld_joint.dart b/examples/lib/stories/bridge_libraries/flame_forge2d/joints/weld_joint.dart index 50001153224..0ff1d58558f 100644 --- a/examples/lib/stories/bridge_libraries/flame_forge2d/joints/weld_joint.dart +++ b/examples/lib/stories/bridge_libraries/flame_forge2d/joints/weld_joint.dart @@ -40,7 +40,8 @@ class WeldJointWorld extends Forge2DWorld color: Colors.white, ); - await addAll([leftPillar, rightPillar]); + addAll([leftPillar, rightPillar]); + await Future.wait([leftPillar.loaded, rightPillar.loaded]); createBridge(leftPillar, rightPillar); } @@ -71,7 +72,8 @@ class WeldJointWorld extends Forge2DWorld width: sectionWidth, height: 1, ); - await add(section); + add(section); + await section.loaded; if (prevSection != null) { createWeldJoint( diff --git a/examples/lib/stories/bridge_libraries/flame_jenny/components/dialogue_box.dart b/examples/lib/stories/bridge_libraries/flame_jenny/components/dialogue_box.dart index 4820ce8d05a..24fe2286675 100644 --- a/examples/lib/stories/bridge_libraries/flame_jenny/components/dialogue_box.dart +++ b/examples/lib/stories/bridge_libraries/flame_jenny/components/dialogue_box.dart @@ -16,7 +16,7 @@ class DialogueBoxComponent extends SpriteComponent with HasGameReference { 'dialogue_box.png', srcSize: spriteSize, ); - await addAll([buttonRow, textBox]); + addAll([buttonRow, textBox]); return super.onLoad(); } diff --git a/examples/lib/stories/bridge_libraries/flame_spine/basic_spine_example.dart b/examples/lib/stories/bridge_libraries/flame_spine/basic_spine_example.dart index c296b4918c7..a214b5e0c3e 100644 --- a/examples/lib/stories/bridge_libraries/flame_spine/basic_spine_example.dart +++ b/examples/lib/stories/bridge_libraries/flame_spine/basic_spine_example.dart @@ -41,7 +41,7 @@ class FlameSpineExample extends FlameGame with TapCallbacks { // Set the "walk" animation on track 0 in looping mode spineboy.animationState.setAnimation(0, 'walk', true); - await add(spineboy); + add(spineboy); } @override diff --git a/examples/lib/stories/bridge_libraries/flame_spine/shared_data_spine_example.dart b/examples/lib/stories/bridge_libraries/flame_spine/shared_data_spine_example.dart index 1b5a4be7112..dd7c53d3fc9 100644 --- a/examples/lib/stories/bridge_libraries/flame_spine/shared_data_spine_example.dart +++ b/examples/lib/stories/bridge_libraries/flame_spine/shared_data_spine_example.dart @@ -45,7 +45,7 @@ class SharedDataSpineExample extends FlameGame with TapCallbacks { spineboy.animationState.setAnimation(0, 'walk', true); spineboys.add(spineboy); } - await addAll(spineboys); + addAll(spineboys); } @override diff --git a/examples/lib/stories/camera_and_viewport/camera_component_example.dart b/examples/lib/stories/camera_and_viewport/camera_component_example.dart index 1c60d66d223..a6cfbf5c2f7 100644 --- a/examples/lib/stories/camera_and_viewport/camera_component_example.dart +++ b/examples/lib/stories/camera_and_viewport/camera_component_example.dart @@ -171,7 +171,8 @@ class AntWorld extends World { Future onLoad() async { final random = Random(); curve = DragonCurve(); - await add(curve); + add(curve); + await curve.loaded; bgRect = curve.boundingRect().inflate(100); const baseColor = HSVColor.fromAHSV(1, 38.5, 0.63, 0.68); diff --git a/examples/lib/stories/camera_and_viewport/camera_component_properties_example.dart b/examples/lib/stories/camera_and_viewport/camera_component_properties_example.dart index 2c39bb9dbcb..545b082660a 100644 --- a/examples/lib/stories/camera_and_viewport/camera_component_properties_example.dart +++ b/examples/lib/stories/camera_and_viewport/camera_component_properties_example.dart @@ -46,7 +46,7 @@ class CameraComponentPropertiesExample extends FlameGame { ..strokeWidth = 0.25 ..color = const Color(0xaaffff00), ); - await world.add(_cullRect); + world.add(_cullRect); camera.mounted.then((_) { updateSize(canvasSize); }); diff --git a/examples/lib/stories/collision_detection/multiple_worlds_example.dart b/examples/lib/stories/collision_detection/multiple_worlds_example.dart index a6bd6e512a9..37a2f08c1f1 100644 --- a/examples/lib/stories/collision_detection/multiple_worlds_example.dart +++ b/examples/lib/stories/collision_detection/multiple_worlds_example.dart @@ -24,7 +24,7 @@ class MultipleWorldsExample extends FlameGame { final world2 = CollisionDetectionWorld(); final camera1 = CameraComponent(world: world1); final camera2 = CameraComponent(world: world2); - await addAll([world1, world2, camera1, camera2]); + addAll([world1, world2, camera1, camera2]); final ember1 = CollidableEmber(position: Vector2(75, 75)); final ember2 = CollidableEmber(position: Vector2(-75, 75)); final ember3 = CollidableEmber(position: Vector2(75, -75)); diff --git a/examples/lib/stories/components/component_pool_example.dart b/examples/lib/stories/components/component_pool_example.dart index 129d080e84f..1b86e1bb897 100644 --- a/examples/lib/stories/components/component_pool_example.dart +++ b/examples/lib/stories/components/component_pool_example.dart @@ -56,7 +56,7 @@ class _BallWorld extends World with TapCallbacks { // Add a stats display to show pool information statsDisplay = _StatsDisplay(pool: ballPool); - await add(statsDisplay); + add(statsDisplay); } @override diff --git a/examples/lib/stories/components/keys_example.dart b/examples/lib/stories/components/keys_example.dart index 84f15f7d7c6..984809c29df 100644 --- a/examples/lib/stories/components/keys_example.dart +++ b/examples/lib/stories/components/keys_example.dart @@ -77,7 +77,7 @@ class KeysExampleGame extends FlameGame { final mage = await loadSprite('mage.png'); final ranger = await loadSprite('ranger.png'); - await addAll([ + addAll([ SelectableClass( key: ComponentKey.named('knight'), sprite: knight, diff --git a/examples/lib/stories/components/time_scale_example.dart b/examples/lib/stories/components/time_scale_example.dart index 567ffcbd957..b3f2b3edb59 100644 --- a/examples/lib/stories/components/time_scale_example.dart +++ b/examples/lib/stories/components/time_scale_example.dart @@ -47,7 +47,7 @@ class TimeScaleExample extends FlameGame ); gameSpeedText.position = Vector2(size.x * 0.5, size.y * 0.8); - await world.addAll([ + world.addAll([ _Chopper( position: Vector2(-100, -10), size: Vector2.all(64), @@ -96,8 +96,8 @@ class _Chopper extends SpriteAnimationComponent @override Future onLoad() async { - await add(CircleHitbox()); - await add(_timer); + add(CircleHitbox()); + add(_timer); return super.onLoad(); } diff --git a/examples/lib/stories/system/step_engine_example.dart b/examples/lib/stories/system/step_engine_example.dart index a2d1bc7f433..a6ba4211a82 100644 --- a/examples/lib/stories/system/step_engine_example.dart +++ b/examples/lib/stories/system/step_engine_example.dart @@ -55,7 +55,7 @@ class StepEngineExample extends FlameGame hudComponents: [_controlsText], ); - await addAll([world, cameraComponent]); + addAll([world, cameraComponent]); } @override diff --git a/packages/flame/benchmark/collision_detection_benchmark.dart b/packages/flame/benchmark/collision_detection_benchmark.dart index 9e5be280460..109b88cc7e1 100644 --- a/packages/flame/benchmark/collision_detection_benchmark.dart +++ b/packages/flame/benchmark/collision_detection_benchmark.dart @@ -40,7 +40,7 @@ class FlatCollisionBenchmark extends AsyncBenchmarkBase { ), ); - await _game.addAll(_blocks); + _game.addAll(_blocks); await _game.ready(); } @@ -96,7 +96,7 @@ class NestedCollisionBenchmark extends AsyncBenchmarkBase { components.add(parent); } - await _game.addAll(components); + _game.addAll(components); await _game.ready(); } diff --git a/packages/flame/benchmark/component_churn_benchmark.dart b/packages/flame/benchmark/component_churn_benchmark.dart index 3d71659a5ab..163ea89eddd 100644 --- a/packages/flame/benchmark/component_churn_benchmark.dart +++ b/packages/flame/benchmark/component_churn_benchmark.dart @@ -48,13 +48,13 @@ class ComponentChurnBenchmark extends AsyncBenchmarkBase { Future setup() async { _game = FlameGame(); await mountGame(_game); - await _game.world.addAll( + _game.world.addAll( List.generate(staticPopulation, (_) => Component()), ); for (var i = 0; i < _liveBatches; i++) { final batch = _newBatch(); _batches.addLast(batch); - await _game.world.addAll(batch); + _game.world.addAll(batch); } await _game.ready(); } @@ -65,7 +65,7 @@ class ComponentChurnBenchmark extends AsyncBenchmarkBase { _game.world.removeAll(_batches.removeFirst()); final batch = _newBatch(); _batches.addLast(batch); - await _game.world.addAll(batch); + _game.world.addAll(batch); _game.update(_dt); } } @@ -97,7 +97,7 @@ class MassAddRemoveBenchmark extends AsyncBenchmarkBase { Future run() async { for (var i = 0; i < _amountCycles; i++) { final components = List.generate(_amountComponents, (_) => Component()); - await _game.world.addAll(components); + _game.world.addAll(components); _game.update(_dt); _game.world.removeAll(components); _game.update(_dt); diff --git a/packages/flame/benchmark/priority_change_benchmark.dart b/packages/flame/benchmark/priority_change_benchmark.dart index 8e79199cdae..a2fb68538ad 100644 --- a/packages/flame/benchmark/priority_change_benchmark.dart +++ b/packages/flame/benchmark/priority_change_benchmark.dart @@ -47,7 +47,7 @@ class SiblingPriorityChangeBenchmark extends AsyncBenchmarkBase { ), ), ); - await _game.world.addAll(parents); + _game.world.addAll(parents); await _game.ready(); _children = [ for (final parent in parents) parent.children.toList(growable: false), @@ -98,7 +98,7 @@ class YSortPriorityBenchmark extends AsyncBenchmarkBase { final random = Random(_randomSeed); _game = FlameGame(); await mountGame(_game); - await _game.world.addAll( + _game.world.addAll( List.generate(_amountChildren, (i) => Component(priority: i)), ); await _game.ready(); diff --git a/packages/flame/benchmark/render_components_benchmark.dart b/packages/flame/benchmark/render_components_benchmark.dart index 66a9b0fe08f..dae58aedd52 100644 --- a/packages/flame/benchmark/render_components_benchmark.dart +++ b/packages/flame/benchmark/render_components_benchmark.dart @@ -33,7 +33,7 @@ class RenderComponentsBenchmark extends AsyncBenchmarkBase { _game = FlameGame(); await mountGame(_game, size: Vector2.all(100.0)); - await _game.addAll( + _game.addAll( List.generate( _amountComponents, (_) => _BenchmarkComponent(random: random, level: 1), @@ -63,7 +63,7 @@ class _BenchmarkComponent extends PositionComponent { @override Future onLoad() async { if (random.nextDouble() <= level) { - await addAll( + addAll( List.generate( random.nextInt(2) + 1, (_) { diff --git a/packages/flame/benchmark/type_query_benchmark.dart b/packages/flame/benchmark/type_query_benchmark.dart index b235dc18bc3..1fd3f134f95 100644 --- a/packages/flame/benchmark/type_query_benchmark.dart +++ b/packages/flame/benchmark/type_query_benchmark.dart @@ -47,7 +47,7 @@ class TypeQueryChurnBenchmark extends AsyncBenchmarkBase { await mountGame(_game); _game.world.children.register<_MarkedComponent>(); _game.world.children.register<_PlainComponent>(); - await _game.world.addAll( + _game.world.addAll( List.generate( _amountStatic, (i) => @@ -57,7 +57,7 @@ class TypeQueryChurnBenchmark extends AsyncBenchmarkBase { for (var i = 0; i < _liveBatches; i++) { final batch = _newBatch(); _batches.addLast(batch); - await _game.world.addAll(batch); + _game.world.addAll(batch); } await _game.ready(); } @@ -69,7 +69,7 @@ class TypeQueryChurnBenchmark extends AsyncBenchmarkBase { _game.world.removeAll(_batches.removeFirst()); final batch = _newBatch(); _batches.addLast(batch); - await _game.world.addAll(batch); + _game.world.addAll(batch); for (final marked in _game.world.children.query<_MarkedComponent>()) { visited += marked.marker; } diff --git a/packages/flame/benchmark/update_components_benchmark.dart b/packages/flame/benchmark/update_components_benchmark.dart index 83a5c749dd9..39602747d28 100644 --- a/packages/flame/benchmark/update_components_benchmark.dart +++ b/packages/flame/benchmark/update_components_benchmark.dart @@ -34,7 +34,7 @@ class UpdateComponentsBenchmark extends AsyncBenchmarkBase { // without this, onLoad never runs and the child components are never // created, making the benchmark measure a tree 11x smaller than intended. await mountGame(_game); - await _game.addAll( + _game.addAll( List.generate(_amountComponents, _BenchmarkComponent.new), ); @@ -76,7 +76,7 @@ class _BenchmarkComponent extends PositionComponent { @override Future onLoad() async { for (var i = 0; i < _amountChildren; i++) { - await add(PositionComponent(position: Vector2(i * 2, 0))); + add(PositionComponent(position: Vector2(i * 2, 0))); } } diff --git a/packages/flame/lib/src/components/core/component.dart b/packages/flame/lib/src/components/core/component.dart index c8198d496d5..63d6bfa63ee 100644 --- a/packages/flame/lib/src/components/core/component.dart +++ b/packages/flame/lib/src/components/core/component.dart @@ -647,12 +647,18 @@ class Component { /// The cost of this flexibility is that the component won't be added right /// away. Instead, it will be placed into a queue, and then added later, after /// it has finished loading, but no sooner than on the next game tick. - /// You can await [FlameGame.lifecycleEventsProcessed] like so: + /// + /// This method is synchronous: it returns immediately without waiting for the + /// component to load or mount. This makes it safe to call from anywhere, + /// including inside [update] or a loop that spawns many components, without + /// having to `await` it or wrap it in `unawaited`. If you need to wait for a + /// particular lifecycle stage, await the child's [loaded], [mounted], or + /// [removed] future instead: /// /// ```dart /// world.add(coin); - /// await game.lifecycleEventsProcessed; - /// // The coin is now guaranteed to be added. + /// await coin.mounted; + /// // The coin is now guaranteed to be mounted. /// ``` /// /// When multiple children are scheduled to be added to the same parent, we @@ -666,32 +672,19 @@ class Component { /// its mounting will be delayed until such time when the parent becomes /// mounted. /// - /// This method returns a future that completes when the component is done - /// loading, and mounting if the parent is currently mounted. However, this - /// future will not guarantee that the component will become "fully mounted": - /// it still needs to be added to the parent's children list, and that - /// operation will only be done on the next game tick. - /// /// A component can only be added to one parent at a time. It is an error to /// try to add it to multiple parents, or even to the same parent multiple /// times. If you need to change the parent of a component, use the /// [parent] setter. - FutureOr add(Component component) => _addChild(component); + void add(Component component) => _addChild(component); /// Adds this component as a child of [parent] (see [add] for details). - FutureOr addToParent(Component parent) => parent._addChild(this); + void addToParent(Component parent) => parent._addChild(this); /// A convenience method to [add] multiple children at once. - Future addAll(Iterable components) async { - List>? futures; + void addAll(Iterable components) { for (final component in components) { - final future = add(component); - if (future is Future) { - (futures ??= []).add(future); - } - } - if (futures != null) { - await Future.wait(futures); + add(component); } } @@ -1010,7 +1003,10 @@ class Component { _setLoadingBit(); final onLoadFuture = onLoad(); if (onLoadFuture is Future) { - return onLoadFuture.then((dynamic _) => _finishLoading()); + return onLoadFuture.then( + (dynamic _) => _finishLoading(), + onError: _failLoading, + ); } else { _finishLoading(); } @@ -1023,6 +1019,22 @@ class Component { _loadCompleter = null; } + /// Surfaces an error thrown by [onLoad]. + /// + /// Since [add] is synchronous and no longer returns the loading future, + /// a load error is reported through the [loaded] future, so it can be caught + /// with `await component.loaded`. If nothing is awaiting [loaded], the error + /// is rethrown instead of being silently swallowed. + void _failLoading(Object error, StackTrace stackTrace) { + final completer = _loadCompleter; + if (completer != null) { + _loadCompleter = null; + completer.completeError(error, stackTrace); + } else { + Error.throwWithStackTrace(error, stackTrace); + } + } + /// Mount the component that is already loaded and has a mounted parent. void _mount() { assert(_parent != null && _parent!.isMounted); diff --git a/packages/flame/lib/src/components/core/component_tree_root.dart b/packages/flame/lib/src/components/core/component_tree_root.dart index f5b0b44e913..aa11d316dd6 100644 --- a/packages/flame/lib/src/components/core/component_tree_root.dart +++ b/packages/flame/lib/src/components/core/component_tree_root.dart @@ -119,9 +119,10 @@ class ComponentTreeRoot extends Component { /// (by adding, moving or removing a component) and you want to make sure /// you react to the changed state, not the current one. /// Remember, methods like [Component.add] don't act immediately and instead - /// enqueue their action. This action also cannot be awaited - /// with something like `await world.add(something)` since that future - /// completes _before_ the lifecycle events are processed. + /// enqueue their action. They are synchronous and return nothing, so the + /// action cannot be awaited directly. To wait for a specific component, await + /// its [Component.loaded], [Component.mounted] or [Component.removed] future; + /// to wait for the whole queue to drain, await this future. /// /// Example usage: /// diff --git a/packages/flame/lib/src/components/router/route.dart b/packages/flame/lib/src/components/router/route.dart index 76beebde07d..dbbd91d21d3 100644 --- a/packages/flame/lib/src/components/router/route.dart +++ b/packages/flame/lib/src/components/router/route.dart @@ -144,7 +144,7 @@ class Route extends PositionComponent Future _addLoadingPage() async { (_loadingPage ??= _loadingBuilder!()).addToParent(this); await _loadingPage!.loaded; - await add(_page!); + add(_page!); await _page!.loaded; _loadingPage!.removeFromParent(); } diff --git a/packages/flame/test/camera/camera_component_test.dart b/packages/flame/test/camera/camera_component_test.dart index 5e71d0c48fe..9201f899834 100644 --- a/packages/flame/test/camera/camera_component_test.dart +++ b/packages/flame/test/camera/camera_component_test.dart @@ -484,7 +484,7 @@ void main() { final world = World(children: [player]); final camera = CameraComponent(); - await game.addAll([camera, world]); + game.addAll([camera, world]); await game.ready(); expect(camera.canSee(player), false); @@ -497,11 +497,11 @@ void main() { final world = World(children: [player]); final camera = CameraComponent(world: world); - await game.addAll([camera]); + game.addAll([camera]); await game.ready(); expect(camera.canSee(player), false); - await game.add(world); + game.add(world); await game.ready(); expect(camera.canSee(player), true); }); @@ -511,11 +511,11 @@ void main() { final world = World(); final camera = CameraComponent(world: world); - await game.addAll([camera, world]); + game.addAll([camera, world]); await game.ready(); expect(camera.canSee(player), false); - await world.add(player); + world.add(player); await game.ready(); expect(camera.canSee(player), true); }); @@ -526,7 +526,7 @@ void main() { final world2 = World(); final camera = CameraComponent(world: world2); - await game.addAll([camera, world1, world2]); + game.addAll([camera, world1, world2]); await game.ready(); // can see when player world is not known. @@ -547,7 +547,7 @@ void main() { world: world, ); - await game.addAll([camera, world]); + game.addAll([camera, world]); await game.ready(); camera.moveBy(size / 2); diff --git a/packages/flame/test/camera/viewports/fixed_resolution_viewport_test.dart b/packages/flame/test/camera/viewports/fixed_resolution_viewport_test.dart index 5a62b9f88ac..ad7315b3738 100644 --- a/packages/flame/test/camera/viewports/fixed_resolution_viewport_test.dart +++ b/packages/flame/test/camera/viewports/fixed_resolution_viewport_test.dart @@ -28,7 +28,7 @@ void main() { game.camera.viewport = viewport; final child = _OnParentResizeTesterComponent(); - await child.addToParent(viewport); + child.addToParent(viewport); await game.ready(); diff --git a/packages/flame/test/collisions/collision_detection_test.dart b/packages/flame/test/collisions/collision_detection_test.dart index 9de494659ac..7650c3b1476 100644 --- a/packages/flame/test/collisions/collision_detection_test.dart +++ b/packages/flame/test/collisions/collision_detection_test.dart @@ -2458,8 +2458,8 @@ void main() { ); final hitboxA = CircleHitbox(); final hitboxB = CircleHitbox(); - await componentA.add(hitboxA); - await componentB.add(hitboxB); + componentA.add(hitboxA); + componentB.add(hitboxB); await game.ensureAddAll([componentA, componentB]); // componentA: center=(10,10), scaledRadius=10 // componentB: center=(20,5), scaledRadius=5 @@ -2488,8 +2488,8 @@ void main() { ); final hitboxA = CircleHitbox(); final hitboxB = CircleHitbox(); - await componentA.add(hitboxA); - await componentB.add(hitboxB); + componentA.add(hitboxA); + componentB.add(hitboxB); await game.ensureAddAll([componentA, componentB]); // componentA: center=(5,5), radius=5 // componentB: center=(20,5), radius=5 @@ -2521,8 +2521,8 @@ void main() { angle: pi / 2, ); final hitboxA = RectangleHitbox(); - await child.add(hitboxA); - await parent.add(child); + child.add(hitboxA); + parent.add(child); // Block from (-2,3) to (2,7) straddles the right edge at x=0. final blockComp = PositionComponent( @@ -2530,7 +2530,7 @@ void main() { size: Vector2.all(4), ); final hitboxB = RectangleHitbox(); - await blockComp.add(hitboxB); + blockComp.add(hitboxB); await game.ensureAddAll([parent, blockComp]); game.update(0); @@ -2561,8 +2561,8 @@ void main() { Vector2(10, 10), Vector2(0, 10), ]); - await child.add(hitbox); - await parent.add(child); + child.add(hitbox); + parent.add(child); // Block from (21,5) to (25,9) straddles the left edge. final blockComp = PositionComponent( @@ -2570,7 +2570,7 @@ void main() { size: Vector2.all(4), ); final hitboxB = RectangleHitbox(); - await blockComp.add(hitboxB); + blockComp.add(hitboxB); await game.ensureAddAll([parent, blockComp]); game.update(0); @@ -2601,9 +2601,9 @@ void main() { size: Vector2.all(10), ); final hitbox = RectangleHitbox(); - await child.add(hitbox); - await midParent.add(child); - await grandparent.add(midParent); + child.add(hitbox); + midParent.add(child); + grandparent.add(midParent); // Block from (-12,8) to (-8,12) straddles the left edge at x=-10. final blockComp = PositionComponent( @@ -2611,7 +2611,7 @@ void main() { size: Vector2.all(4), ); final hitboxB = RectangleHitbox(); - await blockComp.add(hitboxB); + blockComp.add(hitboxB); await game.ensureAddAll([grandparent, blockComp]); game.update(0); diff --git a/packages/flame/test/collisions/collision_passthrough_test.dart b/packages/flame/test/collisions/collision_passthrough_test.dart index 5c74bfa7789..91dbf3a9a61 100644 --- a/packages/flame/test/collisions/collision_passthrough_test.dart +++ b/packages/flame/test/collisions/collision_passthrough_test.dart @@ -49,7 +49,7 @@ void main() { final component = PositionComponent(children: [hitbox]); final testBlock = TestBlock(Vector2.zero(), Vector2.all(10)); - await game.addAll([component, testBlock]); + game.addAll([component, testBlock]); await game.ready(); expect(hitbox.passthroughParent, isNull); diff --git a/packages/flame/test/collisions/screen_hibox_test.dart b/packages/flame/test/collisions/screen_hibox_test.dart index 1804bfaf968..7008effad3c 100644 --- a/packages/flame/test/collisions/screen_hibox_test.dart +++ b/packages/flame/test/collisions/screen_hibox_test.dart @@ -17,7 +17,7 @@ void main() { Vector2.all(10), )..anchor = Anchor.center; final screenHitbox = ScreenHitbox(); - await game.world.addAll([screenHitbox, testBlock]); + game.world.addAll([screenHitbox, testBlock]); await game.ready(); game.update(0); @@ -44,7 +44,7 @@ void main() { Vector2.all(10), )..anchor = Anchor.center; final screenHitbox = ScreenHitbox(); - await game.world.addAll([screenHitbox, testBlock]); + game.world.addAll([screenHitbox, testBlock]); await game.ready(); game.update(0); @@ -70,7 +70,7 @@ void main() { Vector2.all(10), )..anchor = Anchor.center; final screenHitbox = ScreenHitbox(); - await game.world.addAll([screenHitbox, testBlock]); + game.world.addAll([screenHitbox, testBlock]); await game.ready(); game.update(0); @@ -99,7 +99,7 @@ void main() { Vector2.all(10), )..anchor = Anchor.center; final screenHitbox = ScreenHitbox(); - await game.world.addAll([screenHitbox, testBlock]); + game.world.addAll([screenHitbox, testBlock]); await game.ready(); game.update(0); @@ -128,7 +128,7 @@ void main() { Vector2.all(2), )..anchor = Anchor.center; final screenHitbox = ScreenHitbox(); - await game.world.addAll([screenHitbox, testBlock]); + game.world.addAll([screenHitbox, testBlock]); await game.ready(); game.update(0); diff --git a/packages/flame/test/components/advanced_button_component_test.dart b/packages/flame/test/components/advanced_button_component_test.dart index 6196dcc03e2..1112cd4a759 100644 --- a/packages/flame/test/components/advanced_button_component_test.dart +++ b/packages/flame/test/components/advanced_button_component_test.dart @@ -10,7 +10,7 @@ void main() { testGolden( 'label renders correctly', (game, tester) async { - await game.add( + game.add( AdvancedButtonComponent( defaultSkin: RectangleComponent(size: Vector2(40, 20)), defaultLabel: RectangleComponent( diff --git a/packages/flame/test/components/clip_component_test.dart b/packages/flame/test/components/clip_component_test.dart index 6225db7b8c3..3d370ea395a 100644 --- a/packages/flame/test/components/clip_component_test.dart +++ b/packages/flame/test/components/clip_component_test.dart @@ -18,7 +18,7 @@ void main() { testGolden( 'renders correctly', (game, tester) async { - await game.add( + game.add( ClipComponent.rectangle( size: Vector2(100, 100), children: [_Rectangle()], @@ -33,7 +33,7 @@ void main() { testGolden( 'renders correctly', (game, tester) async { - await game.add( + game.add( ClipComponent.circle( size: Vector2(100, 100), children: [_Rectangle()], @@ -48,7 +48,7 @@ void main() { testGolden( 'renders correctly', (game, tester) async { - await game.add( + game.add( ClipComponent.polygon( points: [ Vector2(1, 0), diff --git a/packages/flame/test/components/component_pool_test.dart b/packages/flame/test/components/component_pool_test.dart index c0f24db7471..4b1ea20cb2f 100644 --- a/packages/flame/test/components/component_pool_test.dart +++ b/packages/flame/test/components/component_pool_test.dart @@ -71,7 +71,7 @@ void main() { final original = pool.acquire(); original.position.setValues(10, 20); - await game.add(original); + game.add(original); await game.ready(); original.removeFromParent(); @@ -96,7 +96,7 @@ void main() { ); final component = pool.acquire(); - await game.add(component); + game.add(component); await game.ready(); expect(component.isMounted, true); @@ -121,7 +121,7 @@ void main() { // First cycle: acquire → mount → remove final comp = pool.acquire(); - await game.add(comp); + game.add(comp); await game.ready(); comp.removeFromParent(); game.update(0); @@ -138,7 +138,7 @@ void main() { expect(pool.availableCount, 0); // Mount it again - await game.add(recycled); + game.add(recycled); await game.ready(); // Still in use (mounted, not yet removed) @@ -164,7 +164,7 @@ void main() { for (var i = 0; i < 3; i++) { final component = pool.acquire(); component.position.setValues(100, 200); - await game.add(component); + game.add(component); await game.ready(); expect(component.isMounted, true); @@ -194,9 +194,9 @@ void main() { final component2 = pool.acquire(); final component3 = pool.acquire(); - await game.add(component1); - await game.add(component2); - await game.add(component3); + game.add(component1); + game.add(component2); + game.add(component3); await game.ready(); component1.removeFromParent(); @@ -236,9 +236,9 @@ void main() { final comp2 = pool.acquire(); final comp3 = pool.acquire(); - await game.add(comp1); - await game.add(comp2); - await game.add(comp3); + game.add(comp1); + game.add(comp2); + game.add(comp3); await game.ready(); comp1.removeFromParent(); @@ -276,7 +276,7 @@ void main() { ); final component = pool.acquire(); - await game.add(component); + game.add(component); await game.ready(); pool.clear(); diff --git a/packages/flame/test/components/component_test.dart b/packages/flame/test/components/component_test.dart index 619aeee3ea2..e1466d38931 100644 --- a/packages/flame/test/components/component_test.dart +++ b/packages/flame/test/components/component_test.dart @@ -16,7 +16,7 @@ void main() { group('Lifecycle', () { testWithFlameGame('correct order', (game) async { final component = _LifecycleComponent(); - await game.world.add(component); + game.world.add(component); await game.ready(); expect( @@ -28,7 +28,7 @@ void main() { testWithFlameGame('component mounted completes', (game) async { final component = _LifecycleComponent(); final mounted = component.mounted; - await game.world.add(component); + game.world.add(component); await game.ready(); await expectLater(mounted, completes); @@ -40,7 +40,7 @@ void main() { (game) async { final component = _LifecycleComponent(); final removed = component.removed; - await game.world.add(component); + game.world.add(component); await game.ready(); game.world.remove(component); @@ -54,7 +54,7 @@ void main() { 'component removed completes when set after game is ready', (game) async { final component = _LifecycleComponent(); - await game.world.add(component); + game.world.add(component); await game.ready(); final removed = component.removed; @@ -159,7 +159,7 @@ void main() { testWithFlameGame('component loaded completes', (game) async { final component = _LifecycleComponent(); - await game.world.add(component); + game.world.add(component); final loaded = component.loaded; await game.ready(); @@ -343,7 +343,7 @@ void main() { (game) async { final parent = _LifecycleComponent('parent'); final child = _LifecycleComponent('child')..addToParent(parent); - await game.world.add(parent); + game.world.add(parent); await game.ready(); expect(parent.isMounted, true); @@ -360,7 +360,7 @@ void main() { expect(parent.parent, isNull); expect(child.parent, isNotNull); - await game.world.add(parent); + game.world.add(parent); await game.ready(); expect(parent.isMounted, true); @@ -378,7 +378,7 @@ void main() { final child = _LifecycleComponent('child')..addToParent(parent); final grandChild = _LifecycleComponent('grandchild') ..addToParent(child); - await game.world.add(parent); + game.world.add(parent); await game.ready(); expect(parent.isMounted, true); @@ -422,7 +422,8 @@ void main() { expect(game.isMounted, true); expect(child.isLoaded, false); expect(child.isMounted, false); - await game.world.add(child); + game.world.add(child); + await child.loaded; expect(child.isLoaded, true); await tester.pump(); expect(child.isMounted, true); @@ -453,7 +454,7 @@ void main() { testWithFlameGame('waits for unprocessed events', (game) async { await game.ready(); final component = _LifecycleComponent(); - await game.world.add(component); + game.world.add(component); expect(game.hasLifecycleEvents, isTrue); Future.delayed(Duration.zero).then((_) => game.update(0)); @@ -476,8 +477,8 @@ void main() { await game.ready(); final component = _SlowComponent('heavy', 0.1); final child = _SlowComponent('child', 0.1); - await component.add(child); - await game.world.add(component); + component.add(child); + game.world.add(component); expect(game.world.children, isNot(contains(component))); game.lifecycleEventsProcessed.then( @@ -497,8 +498,8 @@ void main() { await game.ready(); final component = _SlowComponent('heavy', 0.1); final child = _SlowComponent('child', 0.1); - await component.add(child); - await parent1.add(component); + component.add(child); + parent1.add(component); expect(game.lifecycleEventsProcessed, completes); @@ -519,7 +520,7 @@ void main() { testWithFlameGame('Can wait for lifecycleEventsProcessed', (game) async { await game.ready(); final component = Component(); - await game.world.add(component); + game.world.add(component); expect(game.hasLifecycleEvents, isTrue); Future.delayed(Duration.zero).then((_) => game.update(0)); @@ -559,7 +560,7 @@ void main() { (game) async { final child = Component(); final parent = Component(); - await parent.add(child); + parent.add(child); expect(child.isLoaded, false); expect(child.isMounted, false); @@ -747,9 +748,9 @@ void main() { final wrapper = Component(); await game.ensureAdd(wrapper); - final future = wrapper.add(child); + wrapper.add(child); expect(wrapper.contains(child), false); - await future; + await child.loaded; expect(wrapper.contains(child), false); await game.ready(); expect(wrapper.contains(child), true); @@ -760,12 +761,12 @@ void main() { final parent = Component(); final child = Component(); - await game.add(parent); + game.add(parent); await game.ready(); // Remove the parent and add the child in the same tick. parent.removeFromParent(); - await parent.add(child); + parent.add(child); // Timeout is added because processLifecycleEvents of ComponentTreeRoot // gets blocked in such cases. @@ -778,7 +779,7 @@ void main() { expect(game.hasLifecycleEvents, isFalse); // Adding the parent again should eventually mount the child as well. - await game.add(parent); + game.add(parent); await game.ready(); expect(child.isMounted, true); }); @@ -801,7 +802,7 @@ void main() { await game.ensureAdd(parent); expect(parent.isMounted, true); - await parent.add(child); + parent.add(child); game.update(0); // children are only added on the next tick expect(parent.contains(child), true); @@ -1046,7 +1047,7 @@ void main() { game.pauseEngine(); final component = Component(); - await game.world.add(component); + game.world.add(component); game.world.remove(component); game.resumeEngine(); @@ -1096,7 +1097,7 @@ void main() { (game) async { final parent = _RemoveAllChildrenComponent(); final child = _LifecycleComponent('child')..addToParent(parent); - await game.world.add(parent); + game.world.add(parent); await game.ready(); parent.removeFromParent(); game.update(0); @@ -1114,7 +1115,7 @@ void main() { (game) async { final parent = Component(); final child = _LifecycleComponent('child')..addToParent(parent); - await game.world.add(parent); + game.world.add(parent); await game.ready(); parent.removeFromParent(); game.update(0); @@ -1351,7 +1352,7 @@ void main() { 'adding', (game) async { final component = Component()..add(Component()..add(Component())); - await game.world.add(component); + game.world.add(component); await game.ready(); expect(game.hasLifecycleEvents, false); @@ -2030,7 +2031,7 @@ class _PrepareGame extends FlameGame { @override Future onLoad() async { - await add(prepareParent = _ParentOnPrepareComponent()); + add(prepareParent = _ParentOnPrepareComponent()); } } @@ -2047,7 +2048,7 @@ class _OnPrepareComponent extends Component { class _ParentOnPrepareComponent extends _OnPrepareComponent { @override Future onLoad() async { - await add(_OnPrepareComponent()); + add(_OnPrepareComponent()); } } diff --git a/packages/flame/test/components/joystick_component_test.dart b/packages/flame/test/components/joystick_component_test.dart index a3a2e878f18..7a48e5ae0d8 100644 --- a/packages/flame/test/components/joystick_component_test.dart +++ b/packages/flame/test/components/joystick_component_test.dart @@ -82,7 +82,7 @@ void main() { size: 20, margin: const EdgeInsets.only(left: 20, top: 20), ); - await game.add(joystick); + game.add(joystick); await game.ready(); expect(joystick.knob!.position, closeToVector(Vector2(10, 10))); final dragDispatcher = game.firstChild()!; @@ -129,7 +129,7 @@ void main() { size: 20, margin: const EdgeInsets.only(left: 20, top: 20), ); - await game.add(joystick); + game.add(joystick); await game.ready(); final dragDispatcher = game.firstChild()!; diff --git a/packages/flame/test/components/mixins/has_decorator_test.dart b/packages/flame/test/components/mixins/has_decorator_test.dart index c8513d98367..c110f7f29af 100644 --- a/packages/flame/test/components/mixins/has_decorator_test.dart +++ b/packages/flame/test/components/mixins/has_decorator_test.dart @@ -10,13 +10,13 @@ void main() { testGolden( 'Component rendering with and without a Decorator', (game, tester) async { - await game.add( + game.add( _DecoratedComponent( position: Vector2.all(25), size: Vector2.all(40), ), ); - await game.add( + game.add( _DecoratedComponent( position: Vector2(75, 25), size: Vector2.all(40), diff --git a/packages/flame/test/components/mixins/has_time_scale_test.dart b/packages/flame/test/components/mixins/has_time_scale_test.dart index 44e2596b061..2a52aa0ae78 100644 --- a/packages/flame/test/components/mixins/has_time_scale_test.dart +++ b/packages/flame/test/components/mixins/has_time_scale_test.dart @@ -10,7 +10,7 @@ void main() { _GameWithTimeScale.new, (game) async { final component = _MovingComponent(); - await game.add(component); + game.add(component); await game.ready(); const stepTime = 10.0; var distance = 0.0; @@ -44,8 +44,8 @@ void main() { (game) async { final component1 = _ComponentWithTimeScale(); final component2 = _MovingComponent(); - await component1.add(component2); - await game.add(component1); + component1.add(component2); + game.add(component1); await game.ready(); const stepTime = 10.0; var distance = 0.0; @@ -91,7 +91,7 @@ void main() { _GameWithTimeScale.new, (game) async { final component = _MovingComponent(); - await game.add(component); + game.add(component); await game.ready(); const stepTime = 10.0; var distance = 0.0; @@ -124,7 +124,7 @@ void main() { _GameWithTimeScale.new, (game) async { final component = _MovingComponent(); - await game.add(component); + game.add(component); await game.ready(); const stepTime = 10.0; var distance = 0.0; diff --git a/packages/flame/test/components/spawn_component_test.dart b/packages/flame/test/components/spawn_component_test.dart index 17baadc704e..79c12c88722 100644 --- a/packages/flame/test/components/spawn_component_test.dart +++ b/packages/flame/test/components/spawn_component_test.dart @@ -528,15 +528,16 @@ void main() { 'Throws assertion when target is set without area', (game) async { final target = Component(); + final spawn = SpawnComponent( + factory: (_) => PositionComponent(), + period: 1, + target: target, + ); - expectLater( - game.ensureAdd( - SpawnComponent( - factory: (_) => PositionComponent(), - period: 1, - target: target, - ), - ), + game.add(spawn); + + await expectLater( + spawn.loaded, throwsA(isA()), ); }, diff --git a/packages/flame/test/effects/color_effect_test.dart b/packages/flame/test/effects/color_effect_test.dart index 1ddbadbf2a2..3af9deaedef 100644 --- a/packages/flame/test/effects/color_effect_test.dart +++ b/packages/flame/test/effects/color_effect_test.dart @@ -12,7 +12,7 @@ void main() { final component = _PaintComponent(); await game.ensureAdd(component); const color = Colors.red; - await component.add( + component.add( ColorEffect(color, EffectController(duration: 1)), ); game.update(0); @@ -49,7 +49,7 @@ void main() { color, EffectController(duration: 1), ); - await component.add(effect); + component.add(effect); game.update(0.5); expect( @@ -79,7 +79,7 @@ void main() { color, EffectController(duration: 1), ); - await component.add(effect); + component.add(effect); game.update(0.5); expect( diff --git a/packages/flame/test/effects/glow_effect.dart b/packages/flame/test/effects/glow_effect.dart index 422b4060a89..d2c471ad08c 100644 --- a/packages/flame/test/effects/glow_effect.dart +++ b/packages/flame/test/effects/glow_effect.dart @@ -8,7 +8,7 @@ void main() { testWithFlameGame('can apply to component having HasPaint', (game) async { final component = _PaintComponent(); await game.ensureAdd(component); - await component.add( + component.add( GlowEffect(1, EffectController(duration: 1)), ); diff --git a/packages/flame/test/effects/hue_effect_test.dart b/packages/flame/test/effects/hue_effect_test.dart index 6f8ef4cbc1f..8c769d19f67 100644 --- a/packages/flame/test/effects/hue_effect_test.dart +++ b/packages/flame/test/effects/hue_effect_test.dart @@ -10,7 +10,7 @@ void main() { testWithFlameGame('can apply to component having HasPaint', (game) async { final component = _PaintComponent(); await game.ensureAdd(component); - await component.add( + component.add( HueEffect.by(pi, EffectController(duration: 1)), ); @@ -35,7 +35,7 @@ void main() { final component = _PaintComponent(); await game.ensureAdd(component); final effect = HueEffect.by(pi, EffectController(duration: 1)); - await component.add(effect); + component.add(effect); game.update(0.5); expect(component.paint.colorFilter, isNotNull); @@ -53,7 +53,7 @@ void main() { testWithFlameGame('animates hue to target angle', (game) async { final component = _PaintComponent(); await game.ensureAdd(component); - await component.add( + component.add( HueEffect.to(pi, EffectController(duration: 1)), ); @@ -71,7 +71,7 @@ void main() { final component = _PaintComponent(); component.hue = pi / 4; await game.ensureAdd(component); - await component.add( + component.add( HueEffect.to(pi, EffectController(duration: 1)), ); @@ -85,7 +85,7 @@ void main() { testWithFlameGame('applies color filter', (game) async { final component = _PaintComponent(); await game.ensureAdd(component); - await component.add( + component.add( HueEffect.to(pi / 2, EffectController(duration: 1)), ); diff --git a/packages/flame/test/effects/move_along_path_effect_test.dart b/packages/flame/test/effects/move_along_path_effect_test.dart index 04e4399d053..d36b6a0c17b 100644 --- a/packages/flame/test/effects/move_along_path_effect_test.dart +++ b/packages/flame/test/effects/move_along_path_effect_test.dart @@ -163,7 +163,7 @@ void main() { final world = World()..addToParent(game); final camera = CameraComponent(world: world)..addToParent(game); await game.ready(); - await camera.viewport.add( + camera.viewport.add( MoveAlongPathEffect( Path()..lineTo(10, 10), EffectController(duration: 1), diff --git a/packages/flame/test/effects/opacity_effect_test.dart b/packages/flame/test/effects/opacity_effect_test.dart index d809a2e952c..299a708fd58 100644 --- a/packages/flame/test/effects/opacity_effect_test.dart +++ b/packages/flame/test/effects/opacity_effect_test.dart @@ -29,7 +29,7 @@ void main() { await game.ensureAdd(component); component.setOpacity(0.2); - await component.add( + component.add( OpacityEffect.by(0.4, EffectController(duration: 1)), ); game.update(0); @@ -51,7 +51,7 @@ void main() { await game.ensureAdd(component); component.setOpacity(0.2); - await component.add( + component.add( OpacityEffect.to(0.4, EffectController(duration: 1)), ); game.update(0); @@ -118,10 +118,10 @@ void main() { component.setOpacity(0.0); await game.ensureAdd(component); - await component.add( + component.add( OpacityEffect.by(0.5, EffectController(duration: 10)), ); - await component.add( + component.add( OpacityEffect.by( 0.5, EffectController( @@ -160,7 +160,7 @@ void main() { // Repeat the test 3 times for (var i = 0; i < 3; ++i) { - await component.add( + component.add( OpacityEffect.fadeOut(EffectController(duration: 3)), ); @@ -183,7 +183,7 @@ void main() { final component = _PaintComponent(); await game.ensureAdd(component); - await component.add( + component.add( OpacityEffect.fadeOut( EffectController( duration: 3, @@ -207,7 +207,7 @@ void main() { ); await game.ensureAdd(component); - await component.add( + component.add( OpacityEffect.fadeOut( EffectController(duration: 1), target: component.opacityProviderOf('bluePaint'), @@ -237,7 +237,7 @@ void main() { ); await game.ensureAdd(component); - await component.add( + component.add( OpacityEffect.fadeOut(EffectController(duration: 1)), ); @@ -277,7 +277,7 @@ void main() { ); await game.ensureAdd(component); - await component.add( + component.add( OpacityEffect.to( targetOpacity, EffectController(duration: 1), @@ -328,7 +328,7 @@ void main() { ); await game.ensureAdd(component); - await component.add( + component.add( OpacityEffect.fadeIn( EffectController(duration: 1), target: component.opacityProviderOfList( @@ -368,7 +368,7 @@ void main() { infinite: true, ), ); - await component.add(effect); + component.add(effect); var totalTime = 0.0; while (totalTime < 999.9) { diff --git a/packages/flame/test/effects/scale_effect_test.dart b/packages/flame/test/effects/scale_effect_test.dart index e8f19837620..d0a9fcc84de 100644 --- a/packages/flame/test/effects/scale_effect_test.dart +++ b/packages/flame/test/effects/scale_effect_test.dart @@ -12,7 +12,7 @@ void main() { final component = PositionComponent(); await game.ensureAdd(component); - await component.add( + component.add( ScaleEffect.by(Vector2.all(2.0), EffectController(duration: 1)), ); game.update(0); @@ -34,7 +34,7 @@ void main() { await game.ensureAdd(component); component.scale = Vector2.all(1.0); - await component.add( + component.add( ScaleEffect.to(Vector2.all(3.0), EffectController(duration: 1)), ); game.update(0); @@ -59,7 +59,7 @@ void main() { Vector2.all(2.0), EffectController(duration: 1), ); - await component.add(effect..removeOnFinish = false); + component.add(effect..removeOnFinish = false); var expectedScale = 1.0; for (var i = 0; i < 5; i++) { // After each reset the object will be scaled up twice @@ -79,7 +79,7 @@ void main() { Vector2.all(1.0), EffectController(duration: 1), ); - await component.add(effect..removeOnFinish = false); + component.add(effect..removeOnFinish = false); for (var i = 0; i < 5; i++) { component.scale = Vector2.all(1 + 4.0 * i); // After each reset the object will be scaled to the value of @@ -94,7 +94,7 @@ void main() { final component = PositionComponent()..flipVertically(); await game.ensureAdd(component); - await component.add( + component.add( ScaleEffect.by(Vector2.all(5), EffectController(duration: 10)), ); component.add( @@ -138,7 +138,7 @@ void main() { infinite: true, ), ); - await component.add(effect); + component.add(effect); var totalTime = 0.0; while (totalTime < 999.9) { diff --git a/packages/flame/test/effects/size_effect_test.dart b/packages/flame/test/effects/size_effect_test.dart index 0d8d72bd8a6..1ff567ef793 100644 --- a/packages/flame/test/effects/size_effect_test.dart +++ b/packages/flame/test/effects/size_effect_test.dart @@ -12,7 +12,7 @@ void main() { await game.ensureAdd(component); component.size = Vector2.all(1.0); - await component.add( + component.add( SizeEffect.by(Vector2.all(1.0), EffectController(duration: 1)), ); game.update(0); @@ -34,7 +34,7 @@ void main() { await game.ensureAdd(component); component.size = Vector2.all(1.0); - await component.add( + component.add( SizeEffect.to(Vector2.all(3.0), EffectController(duration: 1)), ); game.update(0); @@ -59,7 +59,7 @@ void main() { Vector2.all(1.0), EffectController(duration: 1), ); - await component.add(effect..removeOnFinish = false); + component.add(effect..removeOnFinish = false); final expectedSize = Vector2.zero(); for (var i = 0; i < 5; i++) { // After each reset the object will be sized up by Vector2(1, 1) @@ -94,10 +94,10 @@ void main() { final component = _ResizableComponent(); await game.ensureAdd(component); - await component.add( + component.add( SizeEffect.by(Vector2.all(5), EffectController(duration: 10)), ); - await component.add( + component.add( SizeEffect.by( Vector2.all(0.5), EffectController( @@ -133,7 +133,7 @@ void main() { infinite: true, ), ); - await component.add(effect); + component.add(effect); var totalTime = 0.0; var tolerance = toleranceFloat32(0); diff --git a/packages/flame/test/events/component_mixins/double_tap_callbacks_test.dart b/packages/flame/test/events/component_mixins/double_tap_callbacks_test.dart index 8f662eeaf9e..a84da823e97 100644 --- a/packages/flame/test/events/component_mixins/double_tap_callbacks_test.dart +++ b/packages/flame/test/events/component_mixins/double_tap_callbacks_test.dart @@ -152,7 +152,7 @@ void main() { 'DoubleTapDispatcher is added to game when the callback is mounted', (game) async { final component = _DoubleTapCallbacksComponent(); - await game.add(component); + game.add(component); await game.ready(); expect(game.firstChild(), isNotNull); diff --git a/packages/flame/test/events/component_mixins/drag_callbacks_test.dart b/packages/flame/test/events/component_mixins/drag_callbacks_test.dart index d52b1985605..2e8ab9298ee 100644 --- a/packages/flame/test/events/component_mixins/drag_callbacks_test.dart +++ b/packages/flame/test/events/component_mixins/drag_callbacks_test.dart @@ -12,7 +12,7 @@ void main() { testWithFlameGame( 'make sure DragCallback components can be added to a FlameGame', (game) async { - await game.add(DragCallbacksComponent()); + game.add(DragCallbacksComponent()); await game.ready(); expect(game.children.toList()[2], isA()); }, @@ -391,7 +391,7 @@ void main() { game.camera.viewfinder.zoom = 2; final deltas = []; - await game.world.add( + game.world.add( DragWithCallbacksComponent( position: Vector2.all(-5), size: Vector2.all(10), @@ -428,7 +428,7 @@ void main() { game.camera.viewfinder.zoom = 1 / 2; final deltas = []; - await game.world.add( + game.world.add( DragWithCallbacksComponent( position: Vector2.all(-5), size: Vector2.all(10), diff --git a/packages/flame/test/events/component_mixins/scale_callbacks_test.dart b/packages/flame/test/events/component_mixins/scale_callbacks_test.dart index 19cb593734c..c937cc6b365 100644 --- a/packages/flame/test/events/component_mixins/scale_callbacks_test.dart +++ b/packages/flame/test/events/component_mixins/scale_callbacks_test.dart @@ -12,7 +12,7 @@ void main() { testWithFlameGame( 'make sure ScaleCallback components can be added to a FlameGame', (game) async { - await game.add(ScaleCallbacksComponent()); + game.add(ScaleCallbacksComponent()); await game.ready(); expect(game.children.toList()[2], isA()); }, @@ -358,7 +358,7 @@ void main() { game.camera.viewfinder.zoom = 3; - await game.world.add( + game.world.add( ScaleWithCallbacksComponent( position: Vector2.all(-5), size: Vector2.all(10), @@ -395,7 +395,7 @@ void main() { game.camera.viewfinder.zoom = 3; - await game.world.add( + game.world.add( ScaleWithCallbacksComponent( position: Vector2.all(-5), size: Vector2.all(10), diff --git a/packages/flame/test/events/component_mixins/scale_drag_callbacks_test.dart b/packages/flame/test/events/component_mixins/scale_drag_callbacks_test.dart index 0058860593e..6b2f9a26e88 100644 --- a/packages/flame/test/events/component_mixins/scale_drag_callbacks_test.dart +++ b/packages/flame/test/events/component_mixins/scale_drag_callbacks_test.dart @@ -13,7 +13,7 @@ void main() { '''make sure adding a component with both scale and drag mixins adds a MultiDragScaleDispatcher''', (game) async { - await game.add(ScaleDragCallbacksComponent()); + game.add(ScaleDragCallbacksComponent()); await game.ready(); expect(game.children.toList()[2], isA()); }, @@ -481,7 +481,7 @@ void main() { game.camera.viewfinder.zoom = 3; - await game.world.add( + game.world.add( ScaleDragWithCallbacksComponent( position: Vector2.all(-5), size: Vector2.all(10), @@ -518,7 +518,7 @@ void main() { game.camera.viewfinder.zoom = 3; - await game.world.add( + game.world.add( ScaleDragWithCallbacksComponent( position: Vector2.all(-5), size: Vector2.all(10), @@ -562,7 +562,7 @@ void main() { game.camera.viewfinder.zoom = 2; final deltas = []; - await game.world.add( + game.world.add( ScaleDragWithCallbacksComponent( position: Vector2.all(-5), size: Vector2.all(10), @@ -593,7 +593,7 @@ void main() { game.camera.viewfinder.zoom = 1 / 2; final deltas = []; - await game.world.add( + game.world.add( ScaleDragWithCallbacksComponent( position: Vector2.all(-5), size: Vector2.all(10), @@ -649,7 +649,7 @@ void main() { position: Vector2.all(-5), size: Vector2.all(10), ); - await game.world.add(component); + game.world.add(component); await tester.pumpWidget(GameWidget(game: game)); await tester.pump(); await tester.pump(); @@ -685,12 +685,12 @@ void main() { final game = makeFixedResolutionGame(); final scaleComponent = ScaleWithCallbacksComponent(); - await game.world.add(scaleComponent); + game.world.add(scaleComponent); await tester.pumpWidget(GameWidget(game: game)); await tester.pump(Durations.short1); final dragComponent = DragWithCallbacksComponent(); - await game.world.add(dragComponent); + game.world.add(dragComponent); await tester.pump(); await tester.pump(); @@ -708,13 +708,13 @@ void main() { size: Vector2.all(10), ); - await game.world.add(dragComponent); + game.world.add(dragComponent); await tester.pumpWidget(GameWidget(game: game)); await tester.pump(); Future injectScale() async { final scaleComponent = ScaleWithCallbacksComponent(); - await game.world.add(scaleComponent); + game.world.add(scaleComponent); await tester.pump(); expect(dragComponent.isDragged, true); } @@ -740,13 +740,13 @@ void main() { size: Vector2.all(10), ); - await game.world.add(scaleComponent); + game.world.add(scaleComponent); await tester.pumpWidget(GameWidget(game: game)); await tester.pump(); Future injectDrag() async { final dragComponent = DragWithCallbacksComponent(); - await game.world.add(dragComponent); + game.world.add(dragComponent); await tester.pump(); expect(scaleComponent.isScaling, true); } diff --git a/packages/flame/test/events/component_mixins/secondary_tap_callbacks_test.dart b/packages/flame/test/events/component_mixins/secondary_tap_callbacks_test.dart index eb3e91c89bf..b753324dfe2 100644 --- a/packages/flame/test/events/component_mixins/secondary_tap_callbacks_test.dart +++ b/packages/flame/test/events/component_mixins/secondary_tap_callbacks_test.dart @@ -189,7 +189,7 @@ void main() { 'NonPrimaryTapDispatcher is added to game when the callback is mounted', (game) async { final component = _SecondaryTapCallbacksComponent(); - await game.add(component); + game.add(component); await game.ready(); expect(game.firstChild(), isNotNull); diff --git a/packages/flame/test/events/component_mixins/tertiary_tap_callbacks_test.dart b/packages/flame/test/events/component_mixins/tertiary_tap_callbacks_test.dart index 06acfee08d2..db96bff9158 100644 --- a/packages/flame/test/events/component_mixins/tertiary_tap_callbacks_test.dart +++ b/packages/flame/test/events/component_mixins/tertiary_tap_callbacks_test.dart @@ -182,7 +182,7 @@ void main() { 'NonPrimaryTapDispatcher is added to game when the callback is mounted', (game) async { final component = _TertiaryTapCallbacksComponent(); - await game.add(component); + game.add(component); await game.ready(); expect(game.firstChild(), isNotNull); @@ -193,7 +193,7 @@ void main() { 'NonPrimaryTapDispatcher persists after component is removed', (game) async { final component = _TertiaryTapCallbacksComponent(); - await game.add(component); + game.add(component); await game.ready(); expect(game.firstChild(), isNotNull); diff --git a/packages/flame/test/game/flame_game_test.dart b/packages/flame/test/game/flame_game_test.dart index 00121a3ae85..6e7c7767988 100644 --- a/packages/flame/test/game/flame_game_test.dart +++ b/packages/flame/test/game/flame_game_test.dart @@ -105,7 +105,7 @@ void main() { renderBox.attach(PipelineOwner()); final component = _MyComponent(); - await game.add(component); + game.add(component); renderBox.gameLoopCallback(1.0); expect(component.isUpdateCalled, isTrue); diff --git a/packages/flame/test/game/mixins/single_game_instance_test.dart b/packages/flame/test/game/mixins/single_game_instance_test.dart index 39f7a337bd1..aeec45d78eb 100644 --- a/packages/flame/test/game/mixins/single_game_instance_test.dart +++ b/packages/flame/test/game/mixins/single_game_instance_test.dart @@ -33,12 +33,12 @@ void main() { (game) async { final parent = Component(); final child = _DelayedComponent(); - final future = child.addToParent(parent); + child.addToParent(parent); expect(parent.isMounted, false); expect(parent.isLoaded, false); expect(child.isMounted, false); expect(child.isLoaded, false); // not yet.. - await future; + await child.loaded; expect(parent.isMounted, false); expect(child.isLoaded, true); expect(child.isMounted, false); diff --git a/packages/flame_behavior_tree/example/lib/main.dart b/packages/flame_behavior_tree/example/lib/main.dart index c03310606f2..f4b39cd0809 100644 --- a/packages/flame_behavior_tree/example/lib/main.dart +++ b/packages/flame_behavior_tree/example/lib/main.dart @@ -65,8 +65,8 @@ class GameWorld extends World with HasGameReference { position: Vector2(gameWidth * 0.76, gameHeight * 0.9), ); - await house.add(door); - await addAll([house, agent]); + house.add(door); + addAll([house, agent]); } } @@ -126,7 +126,7 @@ class Agent extends PositionComponent with HasBehaviorTree { @override Future onLoad() async { - await add(CircleComponent(radius: 3, anchor: Anchor.center)); + add(CircleComponent(radius: 3, anchor: Anchor.center)); _setupBehaviorTree(); super.onLoad(); } diff --git a/packages/flame_behavior_tree/test/has_behavior_tree_test.dart b/packages/flame_behavior_tree/test/has_behavior_tree_test.dart index 702a585d8ea..e7930790cf5 100644 --- a/packages/flame_behavior_tree/test/has_behavior_tree_test.dart +++ b/packages/flame_behavior_tree/test/has_behavior_tree_test.dart @@ -55,7 +55,7 @@ void main() { children: [alwaysSuccess, alwaysFailure, alwaysRunning], ); - expect(() async => await game.add(component), returnsNormally); + expect(() async => game.add(component), returnsNormally); await game.ready(); expect(() => game.update(10), returnsNormally); @@ -75,7 +75,7 @@ void main() { ) ..tickInterval = 1; - await game.add(component); + game.add(component); await game.ready(); const dt = 1 / 60; @@ -130,7 +130,7 @@ void main() { final task = _TestTask(); component.treeRoot = Sequence(children: [task]); - await game.add(component); + game.add(component); await game.ready(); game.update(0.1); @@ -153,7 +153,7 @@ void main() { final outerSequence = Sequence(children: [innerSequence]); component.treeRoot = outerSequence; - await game.add(component); + game.add(component); await game.ready(); game.update(0.1); @@ -174,7 +174,7 @@ void main() { final incrementTask = _IncrementTask(); component.treeRoot = Sequence(children: [incrementTask]); - await game.add(component); + game.add(component); await game.ready(); game.update(0.1); @@ -201,7 +201,7 @@ void main() { component.treeRoot = Sequence(children: [task1, task2, task3]); - await game.add(component); + game.add(component); await game.ready(); game.update(0.1); @@ -219,7 +219,7 @@ void main() { final task = _TestTask(); component.treeRoot = Sequence(children: [task]); - await game.add(component); + game.add(component); await game.ready(); expect(() => game.update(0.1), returnsNormally); @@ -237,7 +237,7 @@ void main() { final rootNode = Sequence(children: []); component.treeRoot = rootNode; - await game.add(component); + game.add(component); await game.ready(); // Root node should have access to blackboard @@ -257,7 +257,7 @@ void main() { final task = _TestTask(); component.treeRoot = Sequence(children: [task]); - await game.add(component); + game.add(component); await game.ready(); game.update(0.1); diff --git a/packages/flame_behaviors/example/lib/behaviors/spawning_behavior.dart b/packages/flame_behaviors/example/lib/behaviors/spawning_behavior.dart index 3f9008f22e9..b1a3ba0bb19 100644 --- a/packages/flame_behaviors/example/lib/behaviors/spawning_behavior.dart +++ b/packages/flame_behaviors/example/lib/behaviors/spawning_behavior.dart @@ -11,10 +11,10 @@ class SpawningBehavior extends TappableBehavior { @override Future onLoad() async { - await parent.add(nextRandomEntity(parent.size / 2)); + parent.add(nextRandomEntity(parent.size / 2)); for (var i = 0; i < 5; i++) { - await parent.add(nextRandomEntity(parent.size / 2)); + parent.add(nextRandomEntity(parent.size / 2)); } } diff --git a/packages/flame_behaviors/example/lib/main.dart b/packages/flame_behaviors/example/lib/main.dart index d6dc00eaea4..fa1e33e9bec 100644 --- a/packages/flame_behaviors/example/lib/main.dart +++ b/packages/flame_behaviors/example/lib/main.dart @@ -7,11 +7,11 @@ import 'package:flutter/material.dart'; class ExampleGame extends FlameGame with EntityMixin, HasCollisionDetection { @override Future onLoad() async { - await add(FpsTextComponent(position: Vector2.zero())); - await add(ScreenHitbox()); + add(FpsTextComponent(position: Vector2.zero())); + add(ScreenHitbox()); // Game-specific behaviors - await add(SpawningBehavior()); + add(SpawningBehavior()); return super.onLoad(); } diff --git a/packages/flame_behaviors/lib/src/behaviors/behavior.dart b/packages/flame_behaviors/lib/src/behaviors/behavior.dart index 0ec0f96f59f..9dc7dac45a5 100644 --- a/packages/flame_behaviors/lib/src/behaviors/behavior.dart +++ b/packages/flame_behaviors/lib/src/behaviors/behavior.dart @@ -1,5 +1,3 @@ -import 'dart:async'; - import 'package:flame/components.dart'; import 'package:flame_behaviors/flame_behaviors.dart'; @@ -16,10 +14,10 @@ abstract class Behavior extends Component Behavior({super.children, super.priority, super.key}); @override - FutureOr add(Component component) { + void add(Component component) { assert(component is! EntityMixin, 'Behaviors cannot have entities.'); assert(component is! Behavior, 'Behaviors cannot have behaviors.'); - return super.add(component); + super.add(component); } @override diff --git a/packages/flame_behaviors/test/src/behaviors/propagating_collision_behavior_test.dart b/packages/flame_behaviors/test/src/behaviors/propagating_collision_behavior_test.dart index 8c69ca2b1c9..65d5426bbde 100644 --- a/packages/flame_behaviors/test/src/behaviors/propagating_collision_behavior_test.dart +++ b/packages/flame_behaviors/test/src/behaviors/propagating_collision_behavior_test.dart @@ -163,7 +163,7 @@ void main() { ); await expectLater(() async { - await entity.add(propagatingCollisionBehavior); + entity.add(propagatingCollisionBehavior); game.update(0); }, failsAssert('parent must be a PositionComponent')); }, diff --git a/packages/flame_behaviors/test/src/entity_test.dart b/packages/flame_behaviors/test/src/entity_test.dart index 62e3015f8c3..27c3f344502 100644 --- a/packages/flame_behaviors/test/src/entity_test.dart +++ b/packages/flame_behaviors/test/src/entity_test.dart @@ -32,7 +32,7 @@ void main() { setUp: (game, tester) async { final behavior = _TestBehavior(); final entity = _TestEntity(); - await entity.add(behavior); + entity.add(behavior); await game.ensureAdd(entity); }, verify: (game, tester) async { diff --git a/packages/flame_bloc/example/lib/src/game/game.dart b/packages/flame_bloc/example/lib/src/game/game.dart index e70535919db..0e904a899a7 100644 --- a/packages/flame_bloc/example/lib/src/game/game.dart +++ b/packages/flame_bloc/example/lib/src/game/game.dart @@ -40,7 +40,7 @@ class SpaceShooterGame extends FlameGame @override Future onLoad() async { - await add( + add( FlameMultiBlocProvider( providers: [ FlameBlocProvider.value( diff --git a/packages/flame_bloc/lib/src/flame_multi_bloc_provider.dart b/packages/flame_bloc/lib/src/flame_multi_bloc_provider.dart index ba06151df2e..8f9f377a5bd 100644 --- a/packages/flame_bloc/lib/src/flame_multi_bloc_provider.dart +++ b/packages/flame_bloc/lib/src/flame_multi_bloc_provider.dart @@ -22,28 +22,28 @@ class FlameMultiBlocProvider extends Component { final List? _initialChildren; FlameBlocProvider? _lastProvider; - Future _addProviders() async { + void _addProviders() { final list = [..._providers]; var current = list.removeAt(0); while (list.isNotEmpty) { final provider = list.removeAt(0); - await current.add(provider); + current.add(provider); current = provider; } - await add(_providers.first); + add(_providers.first); _lastProvider = current; _initialChildren?.forEach(add); } @override - Future add(Component component) async { + void add(Component component) { if (_lastProvider == null) { - await super.add(component); + super.add(component); } - await _lastProvider?.add(component); + _lastProvider?.add(component); } @override diff --git a/packages/flame_bloc/test/src/flame_bloc_listenable_test.dart b/packages/flame_bloc/test/src/flame_bloc_listenable_test.dart index 544ca6bdf41..e7a47f331b0 100644 --- a/packages/flame_bloc/test/src/flame_bloc_listenable_test.dart +++ b/packages/flame_bloc/test/src/flame_bloc_listenable_test.dart @@ -73,7 +73,8 @@ void main() { await game.ensureAdd(provider); final component = _PlayerListener(); - expect(() => provider.ensureAdd(component), throwsAssertionError); + provider.add(component); + await expectLater(game.ready(), throwsAssertionError); }, ); diff --git a/packages/flame_bloc/test/src/flame_bloc_reader_test.dart b/packages/flame_bloc/test/src/flame_bloc_reader_test.dart index 117a5fe4ce9..fcf062de498 100644 --- a/packages/flame_bloc/test/src/flame_bloc_reader_test.dart +++ b/packages/flame_bloc/test/src/flame_bloc_reader_test.dart @@ -22,7 +22,8 @@ void main() { await game.ensureAdd(provider); final component = _PlayerReader(); - expect(() => provider.ensureAdd(component), throwsAssertionError); + provider.add(component); + await expectLater(component.loaded, throwsAssertionError); }, ); }); diff --git a/packages/flame_console/test/src/commands_test.dart b/packages/flame_console/test/src/commands_test.dart index 547526b5230..5df8462898b 100644 --- a/packages/flame_console/test/src/commands_test.dart +++ b/packages/flame_console/test/src/commands_test.dart @@ -23,7 +23,7 @@ void main() { 'listAllChildren crawls on all children', FlameGame.new, (game) async { - await game.world.add( + game.world.add( RectangleComponent( children: [ PositionComponent(), @@ -47,7 +47,7 @@ void main() { 'match children with the given types', FlameGame.new, (game) async { - await game.world.addAll([ + game.world.addAll([ RectangleComponent( children: [ PositionComponent(), @@ -76,7 +76,7 @@ void main() { 'match children with the given types and limit', FlameGame.new, (game) async { - await game.world.addAll([ + game.world.addAll([ RectangleComponent( children: [ PositionComponent(), @@ -106,7 +106,7 @@ void main() { FlameGame.new, (game) async { late Component target; - await game.world.addAll([ + game.world.addAll([ target = RectangleComponent( children: [ PositionComponent(), diff --git a/packages/flame_console/test/src/debug_command_test.dart b/packages/flame_console/test/src/debug_command_test.dart index 5cdd3376c80..2853b0b5b7f 100644 --- a/packages/flame_console/test/src/debug_command_test.dart +++ b/packages/flame_console/test/src/debug_command_test.dart @@ -14,7 +14,7 @@ void main() { 'toggle debug mode on components', FlameGame.new, (game) async { - await game.world.addAll(components); + game.world.addAll(components); await game.ready(); diff --git a/packages/flame_forge2d/test/body_component_test.dart b/packages/flame_forge2d/test/body_component_test.dart index 67423f81bc6..702adc15a35 100644 --- a/packages/flame_forge2d/test/body_component_test.dart +++ b/packages/flame_forge2d/test/body_component_test.dart @@ -64,7 +64,8 @@ void main() { final component = _TestBodyComponent() ..body = body ..paint = testPaint; - await game.world.add(component); + game.world.add(component); + await component.loaded; game.camera.follow(component); }, @@ -84,7 +85,8 @@ void main() { final component = _TestBodyComponent() ..body = body ..paint = testPaint; - await game.world.add(component); + game.world.add(component); + await component.loaded; game.camera.follow(component); }, @@ -113,7 +115,8 @@ void main() { final component = _TestBodyComponent() ..body = body ..paint = testPaint; - await game.world.add(component); + game.world.add(component); + await component.loaded; game.camera.follow(component); @@ -145,7 +148,8 @@ void main() { final component = _TestBodyComponent() ..body = body ..paint = testPaint; - await game.world.add(component); + game.world.add(component); + await component.loaded; game.camera.follow(component); }, @@ -174,7 +178,8 @@ void main() { final component = _TestBodyComponent() ..body = body ..paint = testPaint; - await game.world.add(component); + game.world.add(component); + await component.loaded; game.camera.follow(component); }, @@ -491,7 +496,7 @@ void main() { body.createFixture(FixtureDef(shape)); final component = _ConsistentBodyComponent(bodyDef: bodyDef); - await game.world.add(component); + game.world.add(component); await game.ready(); component.removeFromParent(); await game.ready(); @@ -511,7 +516,7 @@ void main() { body.createFixture(FixtureDef(shape)); final component = _ConsistentBodyComponent(bodyDef: bodyDef); - await game.world.add(component); + game.world.add(component); await game.ready(); game.world = Forge2DWorld(); await game.ready(); diff --git a/packages/flame_isolate/test/flame_isolate_test.dart b/packages/flame_isolate/test/flame_isolate_test.dart index d65060f2317..99d171de4d1 100644 --- a/packages/flame_isolate/test/flame_isolate_test.dart +++ b/packages/flame_isolate/test/flame_isolate_test.dart @@ -31,7 +31,7 @@ void main() { 'Running isolateCompute in sub-component', (game) async { final isolateComponent = _IsolateComponent(); - await game.add(isolateComponent); + game.add(isolateComponent); await game.ready(); final result = isolateComponent.isolateCompute(_pow, 4); await expectLater(result, completion(16)); @@ -42,7 +42,7 @@ void main() { 'Running isolateComputeStream in sub-component', (game) async { final isolateComponent = _IsolateComponent(); - await game.add(isolateComponent); + game.add(isolateComponent); await game.ready(); final result = isolateComponent.isolateComputeStream(_messages, 4); await expectLater(result, emitsInOrder([1, 2, 3, 4])); @@ -53,7 +53,7 @@ void main() { 'Running isolateCompute or isolateComputeStream after remove gives error', (game) async { final isolateComponent = _IsolateComponent(); - await game.add(isolateComponent); + game.add(isolateComponent); await game.ready(); final result = isolateComponent.isolateCompute(_pow, 4); diff --git a/packages/flame_isolate/test/flame_tailored_isolate_test.dart b/packages/flame_isolate/test/flame_tailored_isolate_test.dart index ae2a709968f..3f1cb612d7d 100644 --- a/packages/flame_isolate/test/flame_tailored_isolate_test.dart +++ b/packages/flame_isolate/test/flame_tailored_isolate_test.dart @@ -32,7 +32,7 @@ void main() { 'Running isolateCompute in sub-component', (game) async { final isolateComponent = _IsolateComponent(); - await game.add(isolateComponent); + game.add(isolateComponent); await game.ready(); final result = isolateComponent.isolateCompute(_pow, 4); await expectLater(result, completion(16)); @@ -43,7 +43,7 @@ void main() { 'Running isolateComputeStream in sub-component', (game) async { final isolateComponent = _IsolateComponent(); - await game.add(isolateComponent); + game.add(isolateComponent); await game.ready(); final result = isolateComponent.isolateComputeStream(_messages, 4); await expectLater(result, emitsInOrder([1, 2, 3, 4])); @@ -54,7 +54,7 @@ void main() { 'Running isolateCompute or isolateComputeStream after remove gives error', (game) async { final isolateComponent = _IsolateComponent(); - await game.add(isolateComponent); + game.add(isolateComponent); await game.ready(); final result = isolateComponent.isolateCompute(_pow, 4); diff --git a/packages/flame_lottie/test/flame_lottie_test.dart b/packages/flame_lottie/test/flame_lottie_test.dart index 13abf7a3578..58e0613c066 100644 --- a/packages/flame_lottie/test/flame_lottie_test.dart +++ b/packages/flame_lottie/test/flame_lottie_test.dart @@ -17,7 +17,7 @@ void main() { final lottieComponent = LottieComponent(composition); - await game.world.add(lottieComponent); + game.world.add(lottieComponent); await game.ready(); expect(game.world.children, [lottieComponent]); diff --git a/packages/flame_markdown/example/lib/main.dart b/packages/flame_markdown/example/lib/main.dart index 86c50bc12b5..94db4ba1221 100644 --- a/packages/flame_markdown/example/lib/main.dart +++ b/packages/flame_markdown/example/lib/main.dart @@ -19,7 +19,7 @@ class MarkdownGame extends FlameGame { @override Future onLoad() async { final markdown = await Flame.assets.readFile('fire_and_ice.md'); - await add( + add( TextElementComponent.fromDocument( document: FlameMarkdown.toDocument( markdown, diff --git a/packages/flame_spine/example/lib/main.dart b/packages/flame_spine/example/lib/main.dart index f12f84e9c29..841388774c4 100644 --- a/packages/flame_spine/example/lib/main.dart +++ b/packages/flame_spine/example/lib/main.dart @@ -42,7 +42,7 @@ class SpineExample extends FlameGame with TapCallbacks { // Set the "walk" animation on track 0 in looping mode spineboy.animationState.setAnimation(0, 'walk', true); - await add(spineboy); + add(spineboy); } @override diff --git a/packages/flame_sprite_fusion/example/lib/main.dart b/packages/flame_sprite_fusion/example/lib/main.dart index a92c97b431d..567b79c67c8 100644 --- a/packages/flame_sprite_fusion/example/lib/main.dart +++ b/packages/flame_sprite_fusion/example/lib/main.dart @@ -36,7 +36,7 @@ class PlatformerGame extends FlameGame { mapJsonFile: 'map.json', spriteSheetFile: 'spritesheet.png', ); - await world.add(map); + world.add(map); camera.moveTo(map.size * 0.5); } diff --git a/packages/flame_sprite_fusion/test/sprite_fusion_tilemap_component_test.dart b/packages/flame_sprite_fusion/test/sprite_fusion_tilemap_component_test.dart index f5831753695..76758664e4e 100644 --- a/packages/flame_sprite_fusion/test/sprite_fusion_tilemap_component_test.dart +++ b/packages/flame_sprite_fusion/test/sprite_fusion_tilemap_component_test.dart @@ -97,7 +97,7 @@ void main() { images: images, tilemapPrefix: '', ); - await game.add(map); + game.add(map); await game.ready(); }, size: Vector2(360, 216), @@ -115,7 +115,7 @@ void main() { tilemapPrefix: '', position: Vector2(100, 100), ); - await game.add(map); + game.add(map); await game.ready(); }, size: Vector2(360, 216), @@ -133,7 +133,7 @@ void main() { tilemapPrefix: '', anchor: Anchor.center, ); - await game.add(map); + game.add(map); await game.ready(); }, size: Vector2(360, 216), @@ -151,7 +151,7 @@ void main() { tilemapPrefix: '', scale: Vector2.all(0.5), ); - await game.add(map); + game.add(map); await game.ready(); }, size: Vector2(360, 216), @@ -169,7 +169,7 @@ void main() { tilemapPrefix: '', angle: pi * 0.125, ); - await game.add(map); + game.add(map); await game.ready(); }, size: Vector2(360, 216), diff --git a/packages/flame_steering_behaviors/example/lib/src/entities/dot/dot.dart b/packages/flame_steering_behaviors/example/lib/src/entities/dot/dot.dart index 9e4aa11643c..eac10c4d9df 100644 --- a/packages/flame_steering_behaviors/example/lib/src/entities/dot/dot.dart +++ b/packages/flame_steering_behaviors/example/lib/src/entities/dot/dot.dart @@ -37,7 +37,7 @@ class Dot extends PositionedEntity with Steerable { @override Future onLoad() async { parent!.children.register(); - await add( + add( SeparationBehavior( parent!.children.query(), maxDistance: 1 * relativeValue, diff --git a/packages/flame_steering_behaviors/example/lib/src/example_game.dart b/packages/flame_steering_behaviors/example/lib/src/example_game.dart index 879fda6b2e4..f5cf061c359 100644 --- a/packages/flame_steering_behaviors/example/lib/src/example_game.dart +++ b/packages/flame_steering_behaviors/example/lib/src/example_game.dart @@ -15,7 +15,7 @@ class ExampleGame extends FlameGame with HasCollisionDetection { @override Future onLoad() async { - await addAll([ + addAll([ for (var i = 0; i < 100; i++) Dot(position: Vector2.random()..multiply(size)), ]); diff --git a/packages/flame_steering_behaviors/example/test/src/behaviors/screen_wrapping_behavior_test.dart b/packages/flame_steering_behaviors/example/test/src/behaviors/screen_wrapping_behavior_test.dart index 5f913fa911b..f0ec4064698 100644 --- a/packages/flame_steering_behaviors/example/test/src/behaviors/screen_wrapping_behavior_test.dart +++ b/packages/flame_steering_behaviors/example/test/src/behaviors/screen_wrapping_behavior_test.dart @@ -32,7 +32,7 @@ void main() { final screenWrappingBehavior = ScreenWrappingBehavior(); final entity = _TestEntity(); - await entity.add(screenWrappingBehavior); + entity.add(screenWrappingBehavior); await game.ensureAdd(entity); screenWrappingBehavior.onCollisionEnd(screenHitbox); @@ -46,7 +46,7 @@ void main() { final screenWrappingBehavior = ScreenWrappingBehavior(); final entity = _TestEntity(position: Vector2(-25, 0)); - await entity.add(screenWrappingBehavior); + entity.add(screenWrappingBehavior); await game.ensureAdd(entity); screenWrappingBehavior.onCollisionEnd(screenHitbox); @@ -60,7 +60,7 @@ void main() { final screenWrappingBehavior = ScreenWrappingBehavior(); final entity = _TestEntity(position: Vector2(225, 0)); - await entity.add(screenWrappingBehavior); + entity.add(screenWrappingBehavior); await game.ensureAdd(entity); screenWrappingBehavior.onCollisionEnd(screenHitbox); @@ -74,7 +74,7 @@ void main() { final screenWrappingBehavior = ScreenWrappingBehavior(); final entity = _TestEntity(position: Vector2(0, -25)); - await entity.add(screenWrappingBehavior); + entity.add(screenWrappingBehavior); await game.ensureAdd(entity); screenWrappingBehavior.onCollisionEnd(screenHitbox); @@ -88,7 +88,7 @@ void main() { final screenWrappingBehavior = ScreenWrappingBehavior(); final entity = _TestEntity(position: Vector2(0, 225)); - await entity.add(screenWrappingBehavior); + entity.add(screenWrappingBehavior); await game.ensureAdd(entity); screenWrappingBehavior.onCollisionEnd(screenHitbox); diff --git a/packages/flame_test/example/lib/game.dart b/packages/flame_test/example/lib/game.dart index f8ae25c98f1..17345008cff 100644 --- a/packages/flame_test/example/lib/game.dart +++ b/packages/flame_test/example/lib/game.dart @@ -23,6 +23,8 @@ class Background extends SpriteComponent with HasGameReference { class MyGame extends FlameGame { @override Future onLoad() async { - await world.add(Background()); + final background = Background(); + world.add(background); + await background.loaded; } } diff --git a/packages/flame_test/lib/src/flame_test.dart b/packages/flame_test/lib/src/flame_test.dart index 9fd5b3a8168..c07a3406a23 100644 --- a/packages/flame_test/lib/src/flame_test.dart +++ b/packages/flame_test/lib/src/flame_test.dart @@ -16,14 +16,14 @@ extension FlameGameExtension on Component { /// Makes sure that the [component] is added to the tree if you wait for the /// returned future to resolve. Future ensureAdd(Component component) async { - await add(component); + add(component); await component.findGame()!.ready(); } /// Makes sure that the [components] are added to the tree if you wait for the /// returned future to resolve. Future ensureAddAll(Iterable components) async { - await addAll(components); + addAll(components); await components.first.findGame()!.ready(); }