bevy/crates/bevy_ecs/src
James Liu 70f91b2b9e
Implement WorldQuery for EntityRef (#6960)
# Objective
Partially address #5504. Fix #4278. Provide "whole entity" access in
queries. This can be useful when you don't know at compile time what
you're accessing (i.e. reflection via `ReflectComponent`).

## Solution
Implement `WorldQuery` for `EntityRef`. 

- This provides read-only access to the entire entity, and supports
anything that `EntityRef` can normally do.
- It matches all archetypes and tables and will densely iterate when
possible.
- It marks all of the ArchetypeComponentIds of a matched archetype as
read.
- Adding it to a query will cause it to panic if used in conjunction
with any other mutable access.
 - Expanded the docs on Query to advertise this feature.
 - Added tests to ensure the panics were working as intended.
 - Added `EntityRef` to the ECS prelude.

To make this safe, `EntityRef::world` was removed as it gave potential
`UnsafeCell`-like access to other parts of the `World` including aliased
mutable access to the components it would otherwise read safely.

## Performance
Not great beyond the additional parallelization opportunity over
exclusive systems. The `EntityRef` is fetched from `Entities` like any
other call to `World::entity`, which can be very random access heavy.
This could be simplified if `ArchetypeRow` is available in
`WorldQuery::fetch`'s arguments, but that's likely not something we
should optimize for.

## Future work
An equivalent API where it gives mutable access to all components on a
entity can be done with a scoped version of `EntityMut` where it does
not provide `&mut World` access nor allow for structural changes to the
entity is feasible as well. This could be done as a safe alternative to
exclusive system when structural mutation isn't required or the target
set of entities is scoped.

---

## Changelog
Added: `Access::has_any_write`
Added: `EntityRef` now implements `WorldQuery`. Allows read-only access
to the entire entity, incompatible with any other mutable access, can be
mixed with `With`/`Without` filters for more targeted use.
Added: `EntityRef` to `bevy::ecs::prelude`.
Removed: `EntityRef::world`

## Migration Guide
TODO

---------

Co-authored-by: Carter Weinberg <weinbergcarter@gmail.com>
Co-authored-by: Jakob Hellermann <jakob.hellermann@protonmail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2023-06-22 21:20:00 +00:00
..
entity Document every public item in bevy_ecs (#8731) 2023-06-10 23:23:48 +00:00
query Implement WorldQuery for EntityRef (#6960) 2023-06-22 21:20:00 +00:00
reflect Move AppTypeRegistry to bevy_ecs (#8901) 2023-06-21 17:25:01 +00:00
schedule Document every public item in bevy_ecs (#8731) 2023-06-10 23:23:48 +00:00
storage Document every public item in bevy_ecs (#8731) 2023-06-10 23:23:48 +00:00
system Implement WorldQuery for EntityRef (#6960) 2023-06-22 21:20:00 +00:00
world Migrate the rest of the engine to UnsafeWorldCell (#8833) 2023-06-15 01:31:56 +00:00
archetype.rs Document every public item in bevy_ecs (#8731) 2023-06-10 23:23:48 +00:00
bundle.rs Document every public item in bevy_ecs (#8731) 2023-06-10 23:23:48 +00:00
change_detection.rs Allow unsized types as mapped value in Ref::map (#8817) 2023-06-12 17:52:11 +00:00
component.rs Simplify the ComponentIdFor type (#8845) 2023-06-15 12:57:47 +00:00
event.rs Document every public item in bevy_ecs (#8731) 2023-06-10 23:23:48 +00:00
lib.rs Implement WorldQuery for EntityRef (#6960) 2023-06-22 21:20:00 +00:00
removal_detection.rs Simplify the ComponentIdFor type (#8845) 2023-06-15 12:57:47 +00:00