-
-
Notifications
You must be signed in to change notification settings - Fork 900
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Integration of flame_riverpod (#2367)
Previously discussed with @spydon and referenced in issue #2353, flame_riverpod is to be integrated into the monorepo.
- Loading branch information
1 parent
81930e2
commit 0c74560
Showing
22 changed files
with
1,083 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# Component | ||
|
||
|
||
## ComponentRef | ||
|
||
`ComponentRef` exposes Riverpod functionality to individual `Component`s, and is comparable to | ||
`flutter_riverpod`'s `WidgetRef`. | ||
|
||
|
||
## RiverpodComponentMixin | ||
|
||
`RiverpodComponentMixin` manages the lifecycle of listeners on behalf of individual `Component`s. | ||
|
||
`Component`s using this mixin must use `addToGameWidgetBuild` in their `onMount` method to add | ||
listeners (e.g. `ref.watch` or `ref.listen`) *prior to* calling `super.onMount`, which manages the | ||
staged listeners and disposes of them on the user's behalf inside `onRemove`. | ||
|
||
```dart | ||
class RiverpodAwareTextComponent extends PositionComponent | ||
with RiverpodComponentMixin { | ||
late TextComponent textComponent; | ||
int currentValue = 0; | ||
@override | ||
void onMount() { | ||
addToGameWidgetBuild(() { | ||
ref.listen(countingStreamProvider, (p0, p1) { | ||
if (p1.hasValue) { | ||
currentValue = p1.value!; | ||
textComponent.text = '$currentValue'; | ||
} | ||
}); | ||
}); | ||
super.onMount(); | ||
add(textComponent = TextComponent(position: position + Vector2(0, 27))); | ||
} | ||
} | ||
``` | ||
|
||
|
||
## RiverpodGameMixin | ||
|
||
`RiverpodGameMixin` provides listeners from all components to the build method of the | ||
`RiverpodAwareGameWidget`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# flame_riverpod | ||
|
||
```{toctree} | ||
Overview <riverpod.md> | ||
Component <component.md> | ||
Widget <widget.md> | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# flame_riverpod | ||
|
||
|
||
## Riverpod | ||
|
||
[Riverpod](https://riverpod.dev/) is a reactive caching and data-binding | ||
framework for Dart & Flutter. | ||
|
||
In `flutter_riverpod`, widgets can be configured to rebuild when the state | ||
of a provider changes. | ||
|
||
When using Flame, we are interacting with components, which are *not* Widgets. | ||
|
||
`flame_riverpod` provides the `RiverpodAwareGameWidget`, `RiverpodGameMixin`, and | ||
`RiverpodComponentMixin` to facilitate managing state from `Provider`s in your Flame Game. | ||
|
||
|
||
## Usage | ||
|
||
You should use the `RiverpodAwareGameWidget` as your Flame `GameWidget`, the `RiverpodGameMixin` | ||
mixin on your game that extends `FlameGame`, and the `RiverpodComponentMixin` on any components | ||
interacting with Riverpod providers. | ||
|
||
Subscriptions to a provider are managed in accordance with the lifecycle | ||
of a Flame Component: initialization occurs when a Component is mounted, and disposal | ||
occurs when a Component is removed. | ||
|
||
By default, the `RiverpodAwareGameWidget` is rebuilt when | ||
Riverpod-aware (i.e. using the `RiverpodComponentMixin`) components are mounted and when they are | ||
removed. | ||
|
||
```dart | ||
/// An excerpt from the Example. Check it out! | ||
class RefExampleGame extends FlameGame with RiverpodGameMixin { | ||
@override | ||
Future<void> onLoad() async { | ||
await super.onLoad(); | ||
add(TextComponent(text: 'Flame')); | ||
add(RiverpodAwareTextComponent()); | ||
} | ||
} | ||
class RiverpodAwareTextComponent extends PositionComponent | ||
with RiverpodComponentMixin { | ||
late TextComponent textComponent; | ||
int currentValue = 0; | ||
@override | ||
void onMount() { | ||
addToGameWidgetBuild(() { | ||
ref.listen(countingStreamProvider, (p0, p1) { | ||
if (p1.hasValue) { | ||
currentValue = p1.value!; | ||
textComponent.text = '$currentValue'; | ||
} | ||
}); | ||
}); | ||
super.onMount(); | ||
add(textComponent = TextComponent(position: position + Vector2(0, 27))); | ||
} | ||
} | ||
``` | ||
|
||
The order of operations in `Component.onMount` is important. The `RiverpodComponentMixin` | ||
interacts with `RiverpodGameMixin` (inside of `RiverpodComponentMixin.onMount`) to co-ordinate | ||
adding and removing listeners as the corresponding component is mounted and removed, respectively. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Widget | ||
|
||
|
||
## RiverpodAwareGameWidget | ||
|
||
`RiverpodAwareGameWidget` is a GameWidget with a `State` object of type | ||
`RiverpodAwareGameWidgetState`. | ||
|
||
The required `GlobalKey` argument is used to provide `Component`s using `RiverpodComponentMixin` | ||
access to `Provider`s via `RiverpodAwareGameWidgetState`. | ||
|
||
|
||
## RiverpodAwareGameWidgetState | ||
|
||
`RiverpodAwareGameWidgetState` performs the duties associated with the | ||
`ConsumerStatefulElement` in `flutter_riverpod` and `GameWidgetState` in `flame`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
## 5.0.0 | ||
|
||
* New API with breaking changes. Added [RiverpodAwareGameWidget], [RiverpodGameMixin], [RiverpodComponentMixin]. See the example for details. | ||
|
||
## 4.0.0+2 | ||
|
||
* Miscellaneous format post-processing on the files. | ||
|
||
## 4.0.0+1 | ||
|
||
* Miscellaneous tidy-up of package internals. | ||
|
||
## 4.0.0 | ||
|
||
* Made [WidgetRef] property on [ComponentRef] private. It should not be accessed directly. | ||
* Removed the [riverpodAwar`eGameProvider]. If required, this is better handled at the application-level. | ||
|
||
## 3.0.0 | ||
|
||
* Changes to focus on [FlameGame]. | ||
* [riverpodAwareGameProvider] now expects a [FlameGame]. | ||
* Removed the [HasComponentRef] on Game. | ||
* Renamed [RiverpodComponentMixin] to [HasComponentRef] | ||
* [HasComponentRef] now has a static setter for a WidgetRef. Components that use the new [HasComponentRef] mixin no | ||
longer need to explicitly provide a [ComponentRef]. | ||
* Renamed the [WidgetRef] property on the [ComponentRef] to [widgetRef]. | ||
* Updated Example to reflect changes. | ||
* Updated README to reflect changes. | ||
|
||
## 2.0.0 | ||
|
||
* Pruned the public API, removing custom widget definitions (these have now been defined inside the example for | ||
reference) | ||
* Renamed [RiverpodAwareGameMixin] -> [HasComponentRef] to bring closer to the Flame 'house-style' for mixins. | ||
|
||
## 1.1.0+2 | ||
|
||
* Another correction to README and example code. onMount should not call super.onLoad. | ||
|
||
## 1.1.0+1 | ||
|
||
* Correction to README to reflect API change. | ||
|
||
## 1.1.0 | ||
|
||
* Added [RiverpodComponentMixin] to handle disposing of [ProviderSubscription]s. | ||
* Correction to the [RiverpodGameWidget] initializeGame constructor - param is now | ||
[RiverpodAwareGameMixin Function (ref)] as originally intended. | ||
|
||
## 1.0.0+1 | ||
|
||
* Reduced package description length. | ||
* Ran dart format. | ||
|
||
## 1.0.0 | ||
|
||
* Initial release. | ||
* ComponentRef | ||
* riverpodAwareGameProvider | ||
* RiverpodAwareFlameGame | ||
* RiverpodAwareGame | ||
* RiverpodGameWidget |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2023 Blue Fire | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# flame_riverpod | ||
|
||
[Riverpod](https://pub.dev/packages/flutter_riverpod) is a reactive caching and data-binding | ||
framework for Dart & Flutter. | ||
|
||
In `flutter_riverpod`, widgets can be configured to rebuild when the state | ||
of a provider changes. | ||
|
||
When using Flame, we are interacting with components, which are *not* Widgets. | ||
|
||
`flame_riverpod` provides the `RiverpodAwareGameWidget`, `RiverpodGameMixin`, and | ||
`RiverpodComponentMixin` to facilitate managing state from Providers in your Flame Game. | ||
|
||
|
||
## Usage | ||
|
||
You should use the `RiverpodAwareGameWidget` as your Flame `GameWidget`, the `RiverpodGameMixin` | ||
mixin on your game that extends `FlameGame`, and the `RiverpodComponentMixin` on any components | ||
interacting with Riverpod providers. | ||
|
||
The full range of operations defined in Riverpod's `WidgetRef` definition are accessible from | ||
components. | ||
|
||
Subscriptions to a provider are managed in accordance with the lifecycle | ||
of a Flame Component: initialization occurs when a Component is mounted, and disposal | ||
occurs when a Component is removed. By default, the `RiverpodAwareGameWidget` is rebuilt when | ||
Riverpod-aware (i.e. using the `RiverpodComponentMixin`) components are mounted and when they are | ||
removed. | ||
|
||
```dart | ||
/// An excerpt from the Example. Check it out! | ||
class RefExampleGame extends FlameGame with RiverpodGameMixin { | ||
@override | ||
Future<void> onLoad() async { | ||
await super.onLoad(); | ||
add(TextComponent(text: 'Flame')); | ||
add(RiverpodAwareTextComponent()); | ||
} | ||
} | ||
class RiverpodAwareTextComponent extends PositionComponent | ||
with RiverpodComponentMixin { | ||
late TextComponent textComponent; | ||
int currentValue = 0; | ||
/// [onMount] should be used over [onLoad] to initialize subscriptions, | ||
/// cancellation is handled for the user inside [onRemove], | ||
/// which is only called if the [Component] was mounted. | ||
/// | ||
/// [RiverpodComponentMixin.addToGameWidgetBuild] **must** be invoked in | ||
/// your Component **before** [RiverpodComponentMixin.onMount] in order to | ||
/// have the provided function invoked on | ||
/// [RiverpodAwareGameWidgetState.build]. | ||
/// | ||
/// From `flame_riverpod` 5.0.0, [WidgetRef.watch], is also accessible from | ||
/// components. | ||
@override | ||
void onMount() { | ||
addToGameWidgetBuild(() { | ||
ref.listen(countingStreamProvider, (p0, p1) { | ||
if (p1.hasValue) { | ||
currentValue = p1.value!; | ||
textComponent.text = '$currentValue'; | ||
} | ||
}); | ||
}); | ||
super.onMount(); | ||
add(textComponent = TextComponent(position: position + Vector2(0, 27))); | ||
} | ||
} | ||
``` | ||
|
||
|
||
## Credits | ||
|
||
[Mark Videon](https://markvideon.dev) for the initial groundwork and implementation. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
include: package:flame_lint/analysis_options.yaml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# This file tracks properties of this Flutter project. | ||
# Used by Flutter tool to assess capabilities and perform upgrades etc. | ||
# | ||
# This file should be version controlled and should not be manually edited. | ||
|
||
version: | ||
revision: "efbf63d9c66b9f6ec30e9ad4611189aa80003d31" | ||
channel: "stable" | ||
|
||
project_type: app | ||
|
||
# Tracks metadata for the flutter migrate command | ||
migration: | ||
platforms: | ||
- platform: root | ||
create_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 | ||
base_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 | ||
- platform: macos | ||
create_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 | ||
base_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 | ||
|
||
# User provided section | ||
|
||
# List of Local paths (relative to this file) that should be | ||
# ignored by the migrate tool. | ||
# | ||
# Files that are not part of the templates will be ignored by default. | ||
unmanaged_files: | ||
- 'lib/main.dart' | ||
- 'ios/Runner.xcodeproj/project.pbxproj' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# flame_riverpod_example | ||
|
||
The example consists of a very simple FlameGame with a custom | ||
Component, updated alongside a comparable Flutter widget. | ||
|
||
Both the Component and the Widget depend on a `StreamProvider` | ||
that counts upwards indefinitely. | ||
|
||
Both a Flame Component and a Flutter Text Widget update in real-time from | ||
the same data source. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
include: package:flame_lint/analysis_options.yaml |
Oops, something went wrong.