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

feat: Add ComponentTreeRoot.lifecycleEventsProcessed future #3308

Merged
merged 5 commits into from
Sep 20, 2024

Conversation

filiph
Copy link
Contributor

@filiph filiph commented Sep 19, 2024

Description

Adds a future that will complete once all lifecycle events have been processed.

If there are no lifecycle events to be processed (hasLifecycleEvents is false), then this future returns immediately.

This is useful when you modify the component tree (by adding, moving or removing a component) and you want to make sure you react to the changed state, not the current one.

Remember, methods like Component.add don't act immediately and instead enqueue their action. This action also cannot be awaited with something like await world.add(something) since that future completes before the lifecycle events are processed.

Example usage:

player.inventory.addAll(enemy.inventory.children);
await game.lifecycleEventsProcessed;
updateUi(player.inventory);

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

Discussed here: https://discord.com/channels/509714518008528896/1285583996842934348

Copy link
Member

@erickzanardo erickzanardo left a comment

Choose a reason for hiding this comment

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

Oh this is very cool! I wonder if could in fact replace the game.ready() method that we have for our tests.

@filiph
Copy link
Contributor Author

filiph commented Sep 19, 2024

I wonder if could in fact replace the game.ready() method that we have for our tests.

The big difference is that game.ready() actually actively kicks off the lifecycle events processing, while the new addition merely awaits until the next time processLifecycleEvents() is called and finished.

So, you could use the new future in tests, but you'd also have to kick off the process somehow.

@spydon
Copy link
Member

spydon commented Sep 19, 2024

So, you could use the new future in tests, but you'd also have to kick off the process somehow.

The game.ready method could maybe use the new future, but creating another method for initializing the tests would most likely end up looking pretty much like ready already does.

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.

Overall it looks good, very good dartdocs!

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 one minor formatting issue left

packages/flame/test/components/component_test.dart Outdated Show resolved Hide resolved
@spydon spydon enabled auto-merge (squash) September 20, 2024 08:24
@spydon spydon merged commit ebc4741 into flame-engine:main Sep 20, 2024
8 checks passed
@filiph filiph deleted the feat/lifecycle-events-processed branch September 20, 2024 10:30
luanpotter pushed a commit that referenced this pull request Oct 15, 2024
Adds a future that will complete once all lifecycle events have been
processed.

If there are no lifecycle events to be processed (`hasLifecycleEvents`
is `false`), then this future returns immediately.

This is useful when you modify the component tree (by adding, moving or
removing a component) and you want to make sure you react to the changed
state, not the current one.

Remember, methods like `Component.add` don't act immediately and instead
enqueue their action. This action also cannot be awaited with something
like `await world.add(something)` since that future completes _before_
the lifecycle events are processed.

Example usage:

```dart
player.inventory.addAll(enemy.inventory.children);
await game.lifecycleEventsProcessed;
updateUi(player.inventory);
```
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