-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
bevy_ecs: flush entities after running observers and hooks in despawn #15398
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
bevy_ecs: flush entities after running observers and hooks in despawn #15398
Conversation
5b7eb1e to
ab440e7
Compare
|
Let me know when this is ready for review :) |
b32026c to
5d6968f
Compare
|
@alice-i-cecile Ready! |
|
Ooh, a miri failure. That's a new one for me! |
5d6968f to
ab9bf68
Compare
alice-i-cecile
left a comment
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.
Some clarity nits about the test, but I agree with the fix and the test design is good.
iiYese
left a comment
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.
The flushes need explaining but other than that lgtm.
ab9bf68 to
909f30c
Compare
909f30c to
0669dd1
Compare
|
|
||
| // Observers and on_remove hooks may reserve new entities, which | ||
| // requires a flush before Entities::free may be called. | ||
| 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.
There's also a call to world.flush_entities(); at the top of this method. Do we need both, or did that one just need to get moved down here?
It looks like prior to #10756 the flush() call was right before the free() call, and the hooks and observers code got added in between. The calls to deferred_world.trigger_on_foo in bundle.rs don't have flush() calls. That makes me think that we don't need to flush before triggering things, and we only need the single call here, right before the free().
It doesn't look like anything bad can happen if we flush twice, though, so it should be fine to leave both even if they're not both needed.
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.
Hmm, so if I remove the first world.flush_entities(), the tests all pass and everything appears to work fine. As long as observers and hooks are unable to call any methods on Entities that verify_flushed(), it's safe to move. Since all of those require mutable access to Entities and thus exclusive World access as far as I'm aware, we should be OK to remove the first one.
|
Merging; thanks for the careful work and clear explanations :) |
Head branch was pushed to by a user without write access
08aa6a1 to
12c5e3e
Compare
|
Whoops, left an extra line in my test that broke CI. Should be good to go now @alice-i-cecile |
Objective
Fixes #14467
Observers and component lifecycle hooks are allowed to perform operations that subsequently require
Entitiesto be flushed, such as reserving a new entity. If this occurs during anon_removehook or anOnRemoveevent trigger during anEntityWorldMut::despawn, a panic will occur.Solution
Call
world.flush_entities()after runningon_removehooks/observers duringdespawnTesting
Added a new test that fails before the fix and succeeds afterward.