bevy
bevy copied to clipboard
get `unchecked_mut` variants to `by_id` methods
Objective
The World
stores its components and resources in UnsafeCell
s, which means that (with the necessary care) you can get a &mut T
from a &World
soundly. Having two &mut World
s however is unsound.
To support use cases like bevy's systems where multiple callers share a &World
but mutably access different parts of it, there are _unchecked
versions of many functions:
-
EntityRef::get_unchecked_mut
-
World::get_resource_unchecked_mut
-
Query:.get_unchecked
- ... (https://docs.rs/bevy_ecs/latest/bevy_ecs/?search=unchecked_mut)
I have a use case where I have two &Worlds
where one may access resources and the other one may access components, and I would like to use untyped by_id
methods there.
Solution
- add
World::get_resource_unchecked_mut_by_id
- add
EntityRef::get_unchecked_mut_by_id
both with safety comments like the by_id variant.
Changelog
- add
World::get_resource_unchecked_mut_by_id
andEntityRef::get_unchecked_mut_by_id
for manually synchronized mutable world access with untyped pointers
We should be moving in the opposite direction here, removing EntityRef::get_unchecked_mut
not adding a _by_id
variant
Isn't this pretty central to the design of the bevy world?
The world contains UnsafeCell
s in the storages, so multiple systems can share a &World
while carefully making sure that their access patterns are disjoint.
How would that work without &World -> &mut T
methods?
&World
means shared access to components, we may use &World
for interior mutability in places but this is a terrible idea as we also use &World
to actually mean "shared access to all components".
I opened #6404 implementing my thoughts in #5956 on how to split our usages of &World
to mean "shared access to the world" and &World
to mean "manually synchronized through a mechanism like systems, but can actually mutably use specific things".
I rebased this PR anyways in hopes that if #6404 does not get merged in time for 0.9, that we can merge this PR instead as a stop gap solution.
I agree that we should be moving into a direction where get_unchecked_mut
does not exist, but until then I would much prefer
fn World::get_resource_unchecked_mut
fn World::get_resource_unchecked_mut_by_id
fn EntityRef::get_unchecked_mut
fn EntityRef::get_unchecked_mut_by_id
over
fn World::get_resource_unchecked_mut
fn EntityRef::get_unchecked_mut
which already exists but is incomplete and makes certain things unimplementable as third-party crate authors.
Closing in favor of #6404, which resolves the same issues.