Improvements on the overlay API (#592)

* Adding game to overlaybuilder and visible overlays

* Fixing things

* Format

* Adding Renan's suggestions

* Removing wrongly commited integration test files

* Fixing active overlay when it is null

* Update CHANGELOG.md

Co-authored-by: Jochum van der Ploeg <jochum@vdploeg.net>

* Adding some more changes from suggestions

* Removing unnecessary elvis operator

Co-authored-by: Jochum van der Ploeg <jochum@vdploeg.net>
This commit is contained in:
Erick
2020-12-30 16:37:41 -03:00
committed by GitHub
parent 3bd75c8599
commit 089438c6c8
5 changed files with 56 additions and 22 deletions

View File

@ -1,6 +1,8 @@
# CHANGELOG
## [next]
- Option for overlays to be already visible on the GameWidget
- Adding game to the overlay builder
- Rename retreive -> Retrieve
- Use internal children set in BaseComponent (fixes issue adding multiple children)
- Remove develop branches from github workflow definition

View File

@ -5,8 +5,6 @@ import 'package:flame/palette.dart';
import 'package:flutter/material.dart';
class ExampleGame extends Game with TapDetector {
bool isPaused = false;
@override
void update(double dt) {}
@ -25,14 +23,10 @@ class ExampleGame extends Game with TapDetector {
@override
void onTap() {
if (isPaused) {
if (overlays.isActive('PauseMenu')) {
overlays.remove('PauseMenu');
isPaused = false;
} else {
overlays.add(
'PauseMenu',
);
isPaused = true;
overlays.add('PauseMenu');
}
}
}

View File

@ -26,7 +26,7 @@ class MyHomePage extends StatefulWidget {
class _MyHomePageState extends State<MyHomePage> {
ExampleGame _myGame;
Widget pauseMenuBuilder(BuildContext buildContext) {
Widget pauseMenuBuilder(BuildContext buildContext, ExampleGame game) {
return Center(
child: Container(
width: 100,
@ -52,6 +52,7 @@ class _MyHomePageState extends State<MyHomePage> {
overlayBuilderMap: {
"PauseMenu": pauseMenuBuilder,
},
initialActiveOverlays: const ['PauseMenu'],
),
floatingActionButton: FloatingActionButton(
onPressed: () => newGame(),

View File

@ -191,4 +191,7 @@ class ActiveOverlaysNotifier extends ChangeNotifier {
/// A [Set] of the active overlay names.
Set<String> get value => _activeOverlays;
/// Returns if the given [overlayName] is active
bool isActive(String overlayName) => _activeOverlays.contains(overlayName);
}

View File

@ -14,6 +14,11 @@ typedef GameLoadingWidgetBuilder = Widget Function(
bool error,
);
typedef OverlayWidgetBuilder<T extends Game> = Widget Function(
BuildContext context,
T game,
);
/// A [StatefulWidget] that is in charge of attaching a [Game] instance into the flutter tree
///
class GameWidget<T extends Game> extends StatefulWidget {
@ -36,7 +41,15 @@ class GameWidget<T extends Game> extends StatefulWidget {
/// See also:
/// - [new GameWidget]
/// - [Game.overlays]
final Map<String, WidgetBuilder> overlayBuilderMap;
final Map<String, OverlayWidgetBuilder<T>> overlayBuilderMap;
/// A List of the initially active overlays, this is used only on the first build of the widget.
/// To control the overlays that are active use [Game.overlays]
///
/// See also:
/// - [new GameWidget]
/// - [Game.overlays]
final List<String> initialActiveOverlays;
/// Renders a [game] in a flutter widget tree.
///
@ -82,6 +95,7 @@ class GameWidget<T extends Game> extends StatefulWidget {
this.loadingBuilder,
this.backgroundBuilder,
this.overlayBuilderMap,
this.initialActiveOverlays,
}) : super(key: key);
/// Renders a [game] in a flutter widget tree alongside widgets overlays.
@ -89,11 +103,11 @@ class GameWidget<T extends Game> extends StatefulWidget {
/// To use overlays, the game subclass has to be mixed with [HasWidgetsOverlay],
@override
_GameWidgetState createState() => _GameWidgetState();
_GameWidgetState<T> createState() => _GameWidgetState<T>();
}
class _GameWidgetState extends State<GameWidget> {
Set<String> activeOverlays = {};
class _GameWidgetState<T extends Game> extends State<GameWidget<T>> {
Set<String> initialActiveOverlays;
Future<void> _gameLoaderFuture;
Future<void> get _gameLoaderFutureCache =>
@ -102,14 +116,30 @@ class _GameWidgetState extends State<GameWidget> {
@override
void initState() {
super.initState();
// Add the initial overlays
_initActiveOverlays();
addOverlaysListener(widget.game);
}
void _initActiveOverlays() {
if (widget.initialActiveOverlays != null) {
_checkOverlays(widget.initialActiveOverlays.toSet());
widget.initialActiveOverlays.forEach((key) {
widget.game.overlays.add(key);
});
}
}
@override
void didUpdateWidget(covariant GameWidget<Game> oldWidget) {
void didUpdateWidget(GameWidget<T> oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.game != widget.game) {
removeOverlaysListener(oldWidget.game);
// Reset the overlays
_initActiveOverlays();
addOverlaysListener(widget.game);
// Reset the loader future
@ -124,22 +154,26 @@ class _GameWidgetState extends State<GameWidget> {
}
// widget overlay stuff
void addOverlaysListener(Game game) {
void addOverlaysListener(T game) {
widget.game.overlays.addListener(onChangeActiveOverlays);
activeOverlays = widget.game.overlays.value;
initialActiveOverlays = widget.game.overlays.value;
}
void removeOverlaysListener(Game game) {
void removeOverlaysListener(T game) {
game.overlays.removeListener(onChangeActiveOverlays);
}
void onChangeActiveOverlays() {
widget.game.overlays.value.forEach((overlayKey) {
void _checkOverlays(Set<String> overlays) {
overlays.forEach((overlayKey) {
assert(widget.overlayBuilderMap.containsKey(overlayKey),
"A non mapped overlay has been added: $overlayKey");
});
}
void onChangeActiveOverlays() {
_checkOverlays(widget.game.overlays.value);
setState(() {
activeOverlays = widget.game.overlays.value;
initialActiveOverlays = widget.game.overlays.value;
});
}
@ -224,11 +258,11 @@ class _GameWidgetState extends State<GameWidget> {
if (widget.overlayBuilderMap == null) {
return stackWidgets;
}
final widgets = activeOverlays.map((String overlayKey) {
final widgets = initialActiveOverlays.map((String overlayKey) {
final builder = widget.overlayBuilderMap[overlayKey];
return KeyedSubtree(
key: ValueKey(overlayKey),
child: builder(context),
child: builder(context, widget.game),
);
});
stackWidgets.addAll(widgets);