-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
Fix for SceneEntityMapper + hooks panic #15405
Conversation
4fc295e
to
a8357f9
Compare
a8357f9
to
913e8cc
Compare
@alice-i-cecile Turned this into an actual fix in addition to the new test. Ready for review! |
913e8cc
to
eae723f
Compare
eae723f
to
7422176
Compare
@@ -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(); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 👍
There was a problem hiding this comment.
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..
There was a problem hiding this comment.
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.
7422176
to
d036d0f
Compare
Objective
DynamicScene::write_to_world
withMapEntities
andComponentHooks
#14300Fixes #14300
Solution
SceneEntityMapper
relies on operations onEntities
that require flushing in advance, such asalloc
andfree
. Previously, it wasn't callingworld.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:
The first option for this case seemed trickier to reason about than I wanted, since it involved the
BundleInserter
and itsUnsafeWorldCell
, 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 ofWorld
methods. Therefore, we're lettingSceneEntityMapper
be in charge of upholding its own invariants and callingflush_entities
when it's created.Testing
Added a new test case modeled after #14300