Skip to content

Commit

Permalink
fix: Subscription for events when game changes in GameWidget (flame-e…
Browse files Browse the repository at this point in the history
…ngine#1659)

Make sure that subscription to GameStateChange events is properly updated when the game: property of a GameWidget changes.
  • Loading branch information
st-pasha committed May 29, 2022
1 parent 005ca7b commit b52d115
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 4 deletions.
2 changes: 2 additions & 0 deletions packages/flame/lib/src/game/game_widget/game_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,10 @@ class _GameWidgetState<T extends Game> extends State<GameWidget<T>> {
if (oldWidget.game != widget.game) {
// Reset the loaderFuture so that onMount will run again
// (onLoad is still cached).
oldWidget.game.removeGameStateListener(_onGameStateChange);
oldWidget.game.onRemove();
_loaderFuture = null;
widget.game.addGameStateListener(_onGameStateChange);
}
}

Expand Down
10 changes: 6 additions & 4 deletions packages/flame/lib/src/game/mixins/game.dart
Original file line number Diff line number Diff line change
Expand Up @@ -287,20 +287,22 @@ mixin Game {
_refreshWidget();
}

final List<VoidCallback> _gameStateListeners = [];
@visibleForTesting
final List<VoidCallback> gameStateListeners = [];

void addGameStateListener(VoidCallback callback) {
_gameStateListeners.add(callback);
gameStateListeners.add(callback);
}

void removeGameStateListener(VoidCallback callback) {
_gameStateListeners.remove(callback);
gameStateListeners.remove(callback);
}

/// When a Game is attached to a `GameWidget`, this method will force that
/// widget to be rebuilt. This can be used when updating any property which is
/// implemented within the Flutter tree.
void _refreshWidget() {
_gameStateListeners.forEach((callback) => callback());
gameStateListeners.forEach((callback) => callback());
}
}

Expand Down
18 changes: 18 additions & 0 deletions packages/flame/test/game/game_widget/game_widget_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,22 @@ void main() {
expect(game.hasLayout, isTrue);
},
);

testWidgets('Subscription is valid after game change', (tester) async {
const key = Key('flame-game');
final game1 = FlameGame();
await tester.pumpWidget(GameWidget(key: key, game: game1));
expect(game1.isMounted, true);
expect(game1.gameStateListeners.length, 1);

final game2 = FlameGame();
await tester.pumpWidget(GameWidget(key: key, game: game2));
final widget = tester.firstWidget<GameWidget>(
find.byWidgetPredicate((widget) => widget is GameWidget),
);
expect(widget.game, game2);
expect(game2.isMounted, true);
expect(game2.gameStateListeners.length, 1);
expect(game1.gameStateListeners.length, 0);
});
}

0 comments on commit b52d115

Please sign in to comment.