-
-
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
Allow disjoint mutable world access via EntityMut
#9419
Conversation
I would like identified cases of when. The API duplication is getting ridiculous now
Should try not to bloat this further until refactors on the horizon are possible. If no good argument can be made for or against keeping |
I like to think of That said, I'm open to doing it if we decide it's a good idea. I think the path with the least API breakages would be to remove |
I've added some unit tests that are known to fail due to limitations in our current access model. Since the issue is with overly restrictive accesses, it will not cause undefined behavior, so I think it is okay to fix this issue later. Also, note that this issue already existed on the main branch with |
I have merged |
I have also renamed |
EntityMut
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.
This looks good to me. I mostly wanted to make sure the access is sound.
I think renaming the existing types is a little strange, but ig it's better for queries to get the types with shorter names. It's fine if there's some type duplication between "queried" and "direct-world" access though. We may find a need for an EntityWorldRef
later.
I think there are subtle merge conflicts here @JoJoJet; can you rebase and verify things work locally? |
# Objective Fix bevyengine#4278 Fix bevyengine#5504 Fix bevyengine#9422 Provide safe ways to borrow an entire entity, while allowing disjoint mutable access. `EntityRef` and `EntityMut` are not suitable for this, since they provide access to the entire world -- they are just helper types for working with `&World`/`&mut World`. This has potential uses for reflection and serialization ## Solution Remove `EntityRef::world`, which allows it to soundly be used within queries. `EntityMut` no longer supports structural world mutations, which allows multiple instances of it to exist for different entities at once. Structural world mutations are performed using the new type `EntityWorldMut`. ```rust fn disjoint_system( q2: Query<&mut A>, q1: Query<EntityMut, Without<A>>, ) { ... } let [entity1, entity2] = world.many_entities_mut([id1, id2]); *entity1.get_mut::<T>().unwrap() = *entity2.get().unwrap(); for entity in world.iter_entities_mut() { ... } ``` --- ## Changelog - Removed `EntityRef::world`, to fix a soundness issue with queries. + Removed the ability to structurally mutate the world using `EntityMut`, which allows it to be used in queries. + Added `EntityWorldMut`, which is used to perform structural mutations that are no longer allowed using `EntityMut`. ## Migration Guide **Note for maintainers: ensure that the guide for bevyengine#9604 is updated accordingly.** Removed the method `EntityRef::world`, to fix a soundness issue with queries. If you need access to `&World` while using an `EntityRef`, consider passing the world as a separate parameter. `EntityMut` can no longer perform 'structural' world mutations, such as adding or removing components, or despawning the entity. Additionally, `EntityMut::world`, `EntityMut::world_mut` , and `EntityMut::world_scope` have been removed. Instead, use the newly-added type `EntityWorldMut`, which is a helper type for working with `&mut World`. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Objective
Fix #4278
Fix #5504
Fix #9422
Provide safe ways to borrow an entire entity, while allowing disjoint mutable access.
EntityRef
andEntityMut
are not suitable for this, since they provide access to the entire world -- they are just helper types for working with&World
/&mut World
.This has potential uses for reflection and serialization
Solution
Remove
EntityRef::world
, which allows it to soundly be used within queries.EntityMut
no longer supports structural world mutations, which allows multiple instances of it to exist for different entities at once. Structural world mutations are performed using the new typeEntityWorldMut
.Changelog
EntityRef::world
, to fix a soundness issue with queries.EntityMut
, which allows it to be used in queries.EntityWorldMut
, which is used to perform structural mutations that are no longer allowed usingEntityMut
.Migration Guide
Note for maintainers: ensure that the guide for #9604 is updated accordingly.
Removed the method
EntityRef::world
, to fix a soundness issue with queries. If you need access to&World
while using anEntityRef
, consider passing the world as a separate parameter.EntityMut
can no longer perform 'structural' world mutations, such as adding or removing components, or despawning the entity. Additionally,EntityMut::world
,EntityMut::world_mut
, andEntityMut::world_scope
have been removed.Instead, use the newly-added type
EntityWorldMut
, which is a helper type for working with&mut World
.