Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Package flame_riverpod, setState() or markNeedsBuild() called during build. #2943

Merged
merged 4 commits into from
Dec 21, 2023

Conversation

markvideon
Copy link
Contributor

Description

The forceRebuild function now has an "isDirty" check to determine whether setState should be called. Previously, setState was uncritically invoked which could produce the Flutter framework error that occurs when setState is called while widgets are still being rebuilt.

The setState call inside ref.watch has been replaced with a call to forceRebuild, and forceRebuild now has checks to prevent setState from being called while a build is in progress. A persistent frame callback has been added to reset supporting flags.

Checklist

  • I have followed the Contributor Guide when preparing my PR.
  • I have updated/added tests for ALL new/updated/fixed functionality.
  • I have updated/added relevant documentation in docs and added dartdoc comments with ///.
  • I have updated/added relevant examples in examples or docs.

Breaking Change?

  • Yes, this PR is a breaking change.
  • No, this PR is not a breaking change.

Related Issues

N/A. Customer reported issue via Discord.

@markvideon markvideon changed the title fix: flame_riverpod, setState() or markNeedsBuild() called during build. Fix: flame_riverpod, setState() or markNeedsBuild() called during build. Dec 21, 2023
@markvideon markvideon changed the title Fix: flame_riverpod, setState() or markNeedsBuild() called during build. fix: flame_riverpod, setState() or markNeedsBuild() called during build. Dec 21, 2023
@markvideon markvideon changed the title fix: flame_riverpod, setState() or markNeedsBuild() called during build. fix: Package flame_riverpod, setState() or markNeedsBuild() called during build. Dec 21, 2023
Copy link
Member

@spydon spydon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lgtm, just a comment about a comment

packages/flame_riverpod/lib/src/widget.dart Outdated Show resolved Hide resolved
Comment on lines +54 to +56
/// As it is undesirable to call [setState] while the widget may be building,
/// this function honours (potential) subsequent requests to rebuild by
/// setting a flag.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even better

@spydon spydon enabled auto-merge (squash) December 21, 2023 13:21
@spydon spydon merged commit 54d0e95 into flame-engine:main Dec 21, 2023
8 checks passed
spydon pushed a commit that referenced this pull request Dec 22, 2023
In #2943 a persistent frame callback was added to
RiverpodAwareGameWidget's state class, in order to handle multiple
requests in rapid succession to rebuild the widget safely, in response
to [this
thread](https://discord.com/channels/509714518008528896/516639688581316629/1186421112217813062)
on the Discord.

<details>
  <summary>Walkthrough of issue with previous block</summary>
  
**Stage 1:**
forceBuild has been called for the first time, `_isForceBuilding` set to
true

**Stage 2:**
forceBuild has been called a second time before the setState has
completed. `_hasQueuedBuild` is set to true.

**Stage 3:**
The persistent callback is hit. As `_hasQueuedBuild` is true,
`_isForceBuilding` is set to true again, `_hasQueuedBuild` is set to
false / consumed, forceBuild is called again.

**Stage 4:** 
Inside forceBuild, `_isForceBuilding` is still true as it was set inside
the persistent frame callback. Repeat Stage 2
</details>


N/A
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants