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 for SceneEntityMapper + hooks panic #15405

Merged
merged 3 commits into from
Sep 24, 2024

Conversation

jrobsonchase
Copy link
Contributor

@jrobsonchase jrobsonchase commented Sep 24, 2024

Objective

Fixes #14300

Solution

SceneEntityMapper relies on operations on Entities that require flushing in advance, such as alloc and free. Previously, it wasn't calling world.flush_entities() itself and relied on its caller having flushed beforehand. This wasn't an issue before observers and hooks were released, since entity reservation was happening at expected times. Now that hooks and observers are a thing, they can introduce a need to flush.

We have a few options:

  • Flush after each observer/hook run
  • Flush between each paired observer/hook and operation that requires a flush
  • Flush before operations requiring it

The first option for this case seemed trickier to reason about than I wanted, since it involved the BundleInserter and its UnsafeWorldCell, and the second is generally harder to track down. The third seemed the most straightforward and conventional, since we can see a flush occurring at the start of a number of World methods. Therefore, we're letting SceneEntityMapper be in charge of upholding its own invariants and calling flush_entities when it's created.

Testing

Added a new test case modeled after #14300

@alice-i-cecile alice-i-cecile added S-Blocked This cannot move forward until something else changes C-Testing A change that impacts how we test Bevy or how users test their apps A-Scenes Serialized ECS data stored on the disk labels Sep 24, 2024
@alice-i-cecile alice-i-cecile changed the title Add a regression test for #14300 Add a regression test for scenes + hooks Sep 24, 2024
@jrobsonchase jrobsonchase force-pushed the regression_test_14300 branch 2 times, most recently from 4fc295e to a8357f9 Compare September 24, 2024 10:40
@jrobsonchase jrobsonchase changed the title Add a regression test for scenes + hooks Fix for SceneEntityMapper + hooks panic Sep 24, 2024
@jrobsonchase jrobsonchase marked this pull request as ready for review September 24, 2024 10:55
@jrobsonchase
Copy link
Contributor Author

@alice-i-cecile Turned this into an actual fix in addition to the new test. Ready for review!

@alice-i-cecile alice-i-cecile added S-Needs-Review Needs reviewer attention (from anyone!) to move forward C-Bug An unexpected or incorrect behavior and removed S-Blocked This cannot move forward until something else changes labels Sep 24, 2024
@alice-i-cecile alice-i-cecile added this to the 0.15 milestone Sep 24, 2024
@@ -183,6 +183,9 @@ impl<'m> SceneEntityMapper<'m> {

/// Creates a new [`SceneEntityMapper`], spawning a temporary base [`Entity`] in the provided [`World`]
pub fn new(map: &'m mut EntityHashMap<Entity>, world: &mut World) -> Self {
// We're going to be calling methods on `Entities` that require advance
// flushing, such as `alloc` and `free`.
world.flush_entities();
Copy link
Contributor

Choose a reason for hiding this comment

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

Are there any perf consequences to flushing more often?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unsure. I assume that an unnecessary flush is cheap, or at least as inexpensive as checking if a flush is needed, but I don't know that for certain.

let mut scene_world = World::new();
scene_world.insert_resource(reg.clone());
scene_world.spawn((B(Entity::PLACEHOLDER), A));
let scene = DynamicScene::from_world(&scene_world);
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be possible to have a regression test that doesn't involved DynamicScene? I'm not super clear on the internals, but it looks like it might be possible to reproduce the issue with just A and B, and no DynamicScene?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Technically, this can be tested entirely in bevy_ecs with SceneEntityMapper. I can add that one too 👍

Copy link
Contributor

@cBournhonesque cBournhonesque Sep 24, 2024

Choose a reason for hiding this comment

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

But is the Scene part important? Can't we trigger the panic just with MapEntities + hooks?
Oh i guess the only internal EntityMapper we have in bevy is SceneEntityMapper..

Copy link
Member

Choose a reason for hiding this comment

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

Technically, this can be tested entirely in bevy_ecs with SceneEntityMapper. I can add that one too 👍

This would be very helpful to make sure it doesn't regress during the BSN work.

@alice-i-cecile alice-i-cecile added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Sep 24, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Sep 24, 2024
Merged via the queue into bevyengine:main with commit fcddb54 Sep 24, 2024
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Scenes Serialized ECS data stored on the disk C-Bug An unexpected or incorrect behavior C-Testing A change that impacts how we test Bevy or how users test their apps S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Panic calling DynamicScene::write_to_world with MapEntities and ComponentHooks
3 participants