diff --git a/doc/flame/migration.md b/doc/flame/migration.md index e0047302499..933739920f6 100644 --- a/doc/flame/migration.md +++ b/doc/flame/migration.md @@ -7,6 +7,58 @@ major versions of Flame, together with the steps required to migrate your code. ## Migrating from v1.38.0 to v2.0.0 +### `Event.handled` removed in favour of `continuePropagation` + +Events used to carry two independent booleans: `handled`, which Flame never set nor read, and +`continuePropagation`, which actually controls whether an event keeps traversing down the component +tree. The former has been removed; `continuePropagation` is now the single propagation flag on every +event. + +By default, an event stops at the first component that can handle it, so a component that "consumes" +an event does not need to do anything at all — the components below it will not see it: + +```dart +// Before +class Square extends RectangleComponent with TapCallbacks { + @override + void onTapDown(TapDownEvent event) { + removeFromParent(); + event.handled = true; + } +} + +class MyWorld extends World with TapCallbacks { + @override + void onTapDown(TapDownEvent event) { + if (!event.handled) { + add(Square(event.localPosition)); + } + } +} + +// After +class Square extends RectangleComponent with TapCallbacks { + @override + void onTapDown(TapDownEvent event) { + removeFromParent(); + } +} + +class MyWorld extends World with TapCallbacks { + @override + void onTapDown(TapDownEvent event) { + add(Square(event.localPosition)); + } +} +``` + +If you were using `handled` to let an event reach several components, set +`event.continuePropagation = true` in the components that should pass it along instead. + +The equivalent field on the deprecated `*Info` event classes (`TapDownInfo.handled` and friends) has +been removed as well. + + ### `GameWidget.controlled` renamed to `GameWidget.managed` The `GameWidget.controlled` constructor has been renamed to `GameWidget.managed`. The behavior is diff --git a/packages/flame/example/lib/main.dart b/packages/flame/example/lib/main.dart index 6ba96963dde..bd5569f6849 100644 --- a/packages/flame/example/lib/main.dart +++ b/packages/flame/example/lib/main.dart @@ -26,10 +26,7 @@ class MyWorld extends World with TapCallbacks { @override void onTapDown(TapDownEvent event) { super.onTapDown(event); - if (!event.handled) { - final touchPoint = event.localPosition; - add(Square(touchPoint)); - } + add(Square(event.localPosition)); } } @@ -77,6 +74,5 @@ class Square extends RectangleComponent with TapCallbacks { @override void onTapDown(TapDownEvent event) { removeFromParent(); - event.handled = true; } } diff --git a/packages/flame/lib/src/events/messages/event.dart b/packages/flame/lib/src/events/messages/event.dart index a5797121750..8b388d51542 100644 --- a/packages/flame/lib/src/events/messages/event.dart +++ b/packages/flame/lib/src/events/messages/event.dart @@ -14,14 +14,6 @@ abstract class Event { /// The original Flutter raw event that triggered this Flame event. R raw; - /// Flag that can be used to indicate that the event was handled by one of the - /// components. - /// - /// This flag is neither set nor read by Flame. Instead, it can be set by the - /// user in a component that handles an event, and then read by the user in a - /// different component, or at the root Game level. - bool handled = false; - /// If this flag is false (default), the event will be delivered to the first /// component that can handle it. If that component sets this flag to true, /// the event will propagate further down the component tree to other eligible diff --git a/packages/flame/lib/src/gestures/events.dart b/packages/flame/lib/src/gestures/events.dart index 5af12858be7..f7b6c5ed66f 100644 --- a/packages/flame/lib/src/gestures/events.dart +++ b/packages/flame/lib/src/gestures/events.dart @@ -61,14 +61,14 @@ abstract class PositionInfo extends BaseInfo { ) : super(raw); } -class TapDownInfo extends PositionInfo with _HandledField { +class TapDownInfo extends PositionInfo { TapDownInfo.fromDetails( Game game, TapDownDetails raw, ) : super(game, raw.globalPosition, raw); } -class TapUpInfo extends PositionInfo with _HandledField { +class TapUpInfo extends PositionInfo { TapUpInfo.fromDetails( Game game, TapUpDetails raw, @@ -116,8 +116,7 @@ class PointerScrollInfo extends PositionInfo { ) : super(game, raw.position, raw); } -class PointerHoverInfo extends PositionInfo - with _HandledField { +class PointerHoverInfo extends PositionInfo { PointerHoverInfo.fromDetails( Game game, PointerHoverEvent raw, @@ -131,15 +130,14 @@ class DragDownInfo extends PositionInfo { ) : super(game, raw.globalPosition, raw); } -class DragStartInfo extends PositionInfo with _HandledField { +class DragStartInfo extends PositionInfo { DragStartInfo.fromDetails( Game game, DragStartDetails raw, ) : super(game, raw.globalPosition, raw); } -class DragUpdateInfo extends PositionInfo - with _HandledField { +class DragUpdateInfo extends PositionInfo { late final EventDelta delta = EventDelta(raw.delta); DragUpdateInfo.fromDetails( @@ -148,7 +146,7 @@ class DragUpdateInfo extends PositionInfo ) : super(game, raw.globalPosition, raw); } -class DragEndInfo extends BaseInfo with _HandledField { +class DragEndInfo extends BaseInfo { late final Vector2 velocity = raw.velocity.pixelsPerSecond.toVector2(); double? get primaryVelocity => raw.primaryVelocity; @@ -185,7 +183,3 @@ class ScaleUpdateInfo extends PositionInfo { ScaleUpdateDetails raw, ) : super(game, raw.focalPoint, raw); } - -mixin _HandledField { - bool handled = false; -} diff --git a/packages/flame/test/events/component_mixins/input_test_helper.dart b/packages/flame/test/events/component_mixins/input_test_helper.dart index 0bc8d8afddd..1f9a42cdb6f 100644 --- a/packages/flame/test/events/component_mixins/input_test_helper.dart +++ b/packages/flame/test/events/component_mixins/input_test_helper.dart @@ -22,7 +22,6 @@ mixin DragCounter on DragCallbacks { @override void onDragStart(DragStartEvent event) { super.onDragStart(event); - event.handled = true; dragStartEvent++; if (_wasDragged != isDragged) { ++isDraggedStateChange; @@ -33,14 +32,12 @@ mixin DragCounter on DragCallbacks { @override void onDragUpdate(DragUpdateEvent event) { super.onDragUpdate(event); - event.handled = true; dragUpdateEvent++; } @override void onDragEnd(DragEndEvent event) { super.onDragEnd(event); - event.handled = true; dragEndEvent++; if (_wasDragged != isDragged) { ++isDraggedStateChange; @@ -51,7 +48,6 @@ mixin DragCounter on DragCallbacks { @override void onDragCancel(DragCancelEvent event) { super.onDragCancel(event); - event.handled = true; dragCancelEvent++; } } @@ -69,7 +65,6 @@ mixin ScaleCounter on ScaleCallbacks { void onScaleStart(ScaleStartEvent event) { super.onScaleStart(event); expect(event.raw, isNotNull); - event.handled = true; scaleStartEvent++; if (_wasScaled != isScaling) { ++isScaledStateChange; @@ -81,7 +76,6 @@ mixin ScaleCounter on ScaleCallbacks { void onScaleUpdate(ScaleUpdateEvent event) { super.onScaleUpdate(event); expect(event.raw, isNotNull); - event.handled = true; scaleUpdateEvent++; } @@ -89,7 +83,6 @@ mixin ScaleCounter on ScaleCallbacks { void onScaleEnd(ScaleEndEvent event) { super.onScaleEnd(event); expect(event.raw, isNotNull); - event.handled = true; scaleEndEvent++; if (_wasScaled != isScaling) { ++isScaledStateChange; diff --git a/packages/flame/test/events/component_mixins/tap_callbacks_test.dart b/packages/flame/test/events/component_mixins/tap_callbacks_test.dart index 6b81aa15769..bf42037a15b 100644 --- a/packages/flame/test/events/component_mixins/tap_callbacks_test.dart +++ b/packages/flame/test/events/component_mixins/tap_callbacks_test.dart @@ -540,27 +540,23 @@ mixin _TapCounter on TapCallbacks { @override void onTapDown(TapDownEvent event) { expect(event.raw, isNotNull); - event.handled = true; tapDownEvent++; } @override void onLongTapDown(TapDownEvent event) { expect(event.raw, isNotNull); - event.handled = true; longTapDownEvent++; } @override void onTapUp(TapUpEvent event) { expect(event.raw, isNotNull); - event.handled = true; tapUpEvent++; } @override void onTapCancel(TapCancelEvent event) { - event.handled = true; tapCancelEvent++; } } diff --git a/packages/flame_behaviors/example/lib/behaviors/spawning_behavior.dart b/packages/flame_behaviors/example/lib/behaviors/spawning_behavior.dart index 3f9008f22e9..9393cc93576 100644 --- a/packages/flame_behaviors/example/lib/behaviors/spawning_behavior.dart +++ b/packages/flame_behaviors/example/lib/behaviors/spawning_behavior.dart @@ -20,9 +20,6 @@ class SpawningBehavior extends TappableBehavior { @override void onTapDown(TapDownEvent event) { - if (event.handled) { - return; - } parent.add(nextRandomEntity(event.canvasPosition)); } diff --git a/packages/flame_behaviors/example/lib/entities/circle/behaviors/tapping_behavior.dart b/packages/flame_behaviors/example/lib/entities/circle/behaviors/tapping_behavior.dart index ff89fd75a0c..d0317a07c02 100644 --- a/packages/flame_behaviors/example/lib/entities/circle/behaviors/tapping_behavior.dart +++ b/packages/flame_behaviors/example/lib/entities/circle/behaviors/tapping_behavior.dart @@ -4,9 +4,11 @@ import 'package:flame_behaviors_example/entities/entities.dart'; /// This behavior ensures that SpawningBehavior of the game does not spawn /// anything when we click on a circle (for dragging). +/// +/// It does so simply by existing: the tap is delivered to this behavior, and +/// since it does not set `continuePropagation`, it never reaches the game-level +/// SpawningBehavior underneath. class TappingBehavior extends TappableBehavior { @override - void onTapDown(TapDownEvent event) { - event.handled = true; - } + void onTapDown(TapDownEvent event) {} } diff --git a/packages/flame_behaviors/example/lib/entities/rectangle/behaviors/freezing_behavior.dart b/packages/flame_behaviors/example/lib/entities/rectangle/behaviors/freezing_behavior.dart index 8c59898bdc4..c2c45867933 100644 --- a/packages/flame_behaviors/example/lib/entities/rectangle/behaviors/freezing_behavior.dart +++ b/packages/flame_behaviors/example/lib/entities/rectangle/behaviors/freezing_behavior.dart @@ -22,6 +22,5 @@ class FreezingBehavior extends TappableBehavior { originalVelocity = movement?.velocity.clone(); movement?.velocity.setFrom(Vector2.zero()); } - event.handled = true; } }