bevy icon indicating copy to clipboard operation
bevy copied to clipboard

Iterate ALL Entities in world (get EntityRef/EntityMut)

Open Moulberry opened this issue 3 years ago • 1 comments

What problem does this solve or what need does it fill?

There are cases where direct access to EntityRef/EntityMut is needed in an iterating context

What solution would you like?

An archetype-based solution, ideally we could have a &EntityRef or &mut EntityMut in queries, which would automatically imply exclusive world access thinking. (https://github.com/bevyengine/bevy/discussions/5496#discussioncomment-3288227)

What alternative(s) have you considered?

Iterating Entity (the ID) and calling World::entity. This solution works, but it is unintuitive and suffers from worse performance than a built-in solution for iterating EntityRef/EntityMut

Additional context

Original discussion: https://github.com/bevyengine/bevy/discussions/5496

Moulberry avatar Jul 31 '22 08:07 Moulberry

Blocked on #4166. This work will require us to fully unify exclusive and ordinary systems.

alice-i-cecile avatar Jul 31 '22 11:07 alice-i-cecile

#6843 should add support to get an iterator of EntityRef over all entities given a World, however getting an Iterator of EntityMut is going to be highly unsound without LendingIterator to ensure only one EntityMut is valid at any given time.

james7132 avatar Dec 04 '22 04:12 james7132

however getting an Iterator of EntityMut is going to be highly unsound without LendingIterator to ensure only one EntityMut is valid at any given time.

This is just because we currently store a &mut World in EntityMut, right? In theory nothing prevents us from having two EntityMuts that refer to different entities that are alive at the same time?

jakobhellermann avatar Jan 17 '23 10:01 jakobhellermann

In theory nothing prevents us from having two EntityMuts that refer to different entities that are alive at the same time?

Correction: only if we remove EntityRef::world and EntityMut::into_world_mut/world_scope/world_mut/world.

jakobhellermann avatar Jan 17 '23 10:01 jakobhellermann

This is just because we currently store a &mut World in EntityMut, right? In theory nothing prevents us from having two EntityMuts that refer to different entities that are alive at the same time?

Due to the use of swap_remove and entity locations being updated, structural mutations (adding/removing components) to entities via EntityMut can and will invalidate the locations in other EntityRefs/EntityMuts and the metadata used to make the original iterator.

We'd likely need a mutable version of EntityRef that disallows structural mutations.

james7132 avatar Jan 17 '23 15:01 james7132