diff --git a/lib/game/components/alien_zone/alien_bumper/behaviors/alien_bumper_contact_behavior.dart b/lib/game/components/alien_zone/alien_bumper/behaviors/alien_bumper_contact_behavior.dart index 80187f40..ce4b8e0a 100644 --- a/lib/game/components/alien_zone/alien_bumper/behaviors/alien_bumper_contact_behavior.dart +++ b/lib/game/components/alien_zone/alien_bumper/behaviors/alien_bumper_contact_behavior.dart @@ -3,16 +3,12 @@ import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_flame/pinball_flame.dart'; -class AlienBumperContactBehavior extends Component with ContactCallbacks { +class AlienBumperContactBehavior extends Component + with ContactCallbacks, ParentIsA { @override Future onLoad() async { await super.onLoad(); - // TODO(alestiago): Refactor once the following is merged: - // https://github.com/flame-engine/flame/pull/1566 - final parent = this.parent; - if (parent is! AlienBumper) return; - final userData = parent.body.userData; if (userData is ContactCallbacksNotifer) { userData.addCallback(this); @@ -25,12 +21,6 @@ class AlienBumperContactBehavior extends Component with ContactCallbacks { void beginContact(Object other, Contact contact) { super.beginContact(other, contact); if (other is! Ball) return; - - // TODO(alestiago): Refactor once the following is merged: - // https://github.com/flame-engine/flame/pull/1566 - final parent = this.parent; - if (parent is! AlienBumper) return; - parent.state = AlienBumperState.inactive; } } diff --git a/lib/game/components/alien_zone/alien_bumper/behaviors/alien_bumper_sprite_behavior.dart b/lib/game/components/alien_zone/alien_bumper/behaviors/alien_bumper_sprite_behavior.dart index 011872b0..0e2068d1 100644 --- a/lib/game/components/alien_zone/alien_bumper/behaviors/alien_bumper_sprite_behavior.dart +++ b/lib/game/components/alien_zone/alien_bumper/behaviors/alien_bumper_sprite_behavior.dart @@ -1,10 +1,12 @@ import 'package:flame/components.dart'; import 'package:pinball_components/pinball_components.dart'; +import 'package:pinball_flame/pinball_flame.dart'; /// {@template alien_bumper_sprite_behavior} /// /// {@endtemplate} -class AlienBumperSpriteBehavior extends TimerComponent { +class AlienBumperSpriteBehavior extends TimerComponent + with ParentIsA { /// {@macro alien_bumper_sprite_behavior} AlienBumperSpriteBehavior() : super( @@ -28,12 +30,6 @@ class AlienBumperSpriteBehavior extends TimerComponent { @override Future onLoad() async { await super.onLoad(); - - // TODO(alestiago): Refactor once the following is merged: - // https://github.com/flame-engine/flame/pull/1566 - final parent = this.parent; - if (parent is! AlienBumper) return; - timer.stop(); parent.stream.listen(_onNewState); } @@ -41,11 +37,6 @@ class AlienBumperSpriteBehavior extends TimerComponent { @override void onTick() { super.onTick(); - // TODO(alestiago): Refactor once the following is merged: - // https://github.com/flame-engine/flame/pull/1566 - final parent = this.parent; - if (parent is! AlienBumper) return; - parent.state = AlienBumperState.active; } } diff --git a/lib/game/components/scoring_behaviour.dart b/lib/game/components/scoring_behaviour.dart index fad8ce04..ba57578e 100644 --- a/lib/game/components/scoring_behaviour.dart +++ b/lib/game/components/scoring_behaviour.dart @@ -10,7 +10,10 @@ import 'package:pinball_flame/pinball_flame.dart'; /// /// {@endtemplate} class ScoringBehaviour extends Component - with ContactCallbacksNotifer, HasGameRef { + with + ContactCallbacksNotifer, + HasGameRef, + ParentIsA { /// {@macro scoring_behaviour} ScoringBehaviour({ required int points, @@ -22,11 +25,6 @@ class ScoringBehaviour extends Component Future onLoad() async { await super.onLoad(); - // TODO(alestiago): Refactor once the following is merged: - // https://github.com/flame-engine/flame/pull/1566 - final parent = this.parent; - if (parent is! BodyComponent) return; - final userData = parent.body.userData; if (userData is ContactCallbacksNotifer) { userData.addCallback(this); diff --git a/packages/pinball_components/lib/src/components/alien_bumper.dart b/packages/pinball_components/lib/src/components/alien_bumper.dart index 0b8a19b4..9555fd43 100644 --- a/packages/pinball_components/lib/src/components/alien_bumper.dart +++ b/packages/pinball_components/lib/src/components/alien_bumper.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:flame/components.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:pinball_components/pinball_components.dart'; +import 'package:pinball_flame/pinball_flame.dart'; abstract class State { // TODO(alestiago): Investigate approaches to avoid having this as late. @@ -19,6 +20,10 @@ abstract class State { final StreamController _stream = StreamController.broadcast(); Stream get stream => _stream.stream; + + void close() { + _stream.close(); + } } /// Indicates the [AlienBumper]'s current sprite state. @@ -93,6 +98,12 @@ class AlienBumper extends BodyComponent await add(_spriteGroupComponent); } + @override + void onRemove() { + close(); + super.onRemove(); + } + @override Body createBody() { final shape = EllipseShape( @@ -113,7 +124,8 @@ class AlienBumper extends BodyComponent } class _AlienBumperSpriteGroupComponent - extends SpriteGroupComponent with HasGameRef { + extends SpriteGroupComponent + with HasGameRef, ParentIsA { _AlienBumperSpriteGroupComponent({ required String onAssetPath, required String offAssetPath, @@ -143,11 +155,6 @@ class _AlienBumperSpriteGroupComponent this.sprites = sprites; size = sprites[current]!.originalSize / 10; - // TODO(alestiago): Refactor once the following is merged: - // https://github.com/flame-engine/flame/pull/1566 - final parent = this.parent; - if (parent is! AlienBumper) return; - parent.stream.listen((state) => current = state); } } diff --git a/packages/pinball_flame/lib/pinball_flame.dart b/packages/pinball_flame/lib/pinball_flame.dart index 1d8bc7ac..cdda47b7 100644 --- a/packages/pinball_flame/lib/pinball_flame.dart +++ b/packages/pinball_flame/lib/pinball_flame.dart @@ -4,4 +4,5 @@ export 'src/blueprint.dart'; export 'src/component_controller.dart'; export 'src/contacts_callbacks_adder.dart'; export 'src/keyboard_input_controller.dart'; +export 'src/parent_is_a.dart'; export 'src/sprite_animation.dart'; diff --git a/packages/pinball_flame/lib/src/parent_is_a.dart b/packages/pinball_flame/lib/src/parent_is_a.dart new file mode 100644 index 00000000..91866b97 --- /dev/null +++ b/packages/pinball_flame/lib/src/parent_is_a.dart @@ -0,0 +1,16 @@ +import 'package:flame/components.dart'; + +// TODO(alestiago): Remove once the following is merged: +// https://github.com/flame-engine/flame/pull/1566 + +/// A mixin that ensures a parent is of the given type [T]. +mixin ParentIsA on Component { + @override + T get parent => super.parent! as T; + + @override + Future? addToParent(Component parent) { + assert(parent is T, 'Parent must be of type $T'); + return super.addToParent(parent); + } +}