You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Allow users to read / write from all components of a given entity using an AllWorldQuery types #4278
What problem does this solve or what need does it fill?
From time to time, users want to fetch all of the components from a given set of entities.
To do so, they must use the EntityRef or EntityMut API, in an exclusive system.
Fundamentally though, there's no reason this must be done in an exclusive system: this does not impact resource data, and we can limit the archetypes affected when combined with query filters.
What solution would you like?
Create a All type that parallels the API of EntityRef.
This would enable users to write e.g. Query<&All, With<Networked>> in an ordinary system, allowing them to read from any component of the given entity.
This will require some interesting new logic around defining which fetches are needed, but should be relatively straightforward.
Alternatives considered
Initially, I thought we could use EntityRef and EntityMut for this by implementing the WorldQuery trait on them directly. However, EntityMut allows users to add components, which cannot be done in parallel due to the potential impacts on archetypes.
Without the ability to reuse the APIs, IMO it makes more sense just to create a new type and use the standard & vs &mut distinction.
Alternatively alternatively, we could instead use one of the more 🧪 ideas to allow for instant component addition / removals in parallel systems and then just use EntityRef and EntityMut, likely by deferring the archetype updates until the next sync point and storing new component data in a scratch space of sorts.
You can sort of do this with ReflectComponent, though this both requires Reflect impls, still requires an exclusive system, and is mostly for the dynamic case where the types are not known at compile time. However, I'm not sure what kind of use case for AllComponents would work where we know the types at compile time that isn't served by generic systems and the existing query type.
This would enable users to write e.g. Query<&AllComponents, With<Networked>> in an ordinary system, allowing them to read from any component of the given entity.
Could you expand on how that would be used?
fnmy_system(query:Query<&AllComponents,With<Networked>>){for all_components in query.iter(){// how do you use this all_components?}}
Without going full dynamic, you'll need to provide the concrete component type, so why not put it in the query anyway?
changed the title [-]Allow users to read / write from all components of a given entity using an AllComponents API[/-][+]Allow users to read / write from all components of a given entity using an `All` `WorldQuery` type[/+]on Mar 21, 2022
Maybe we trade concurrency for ergonomics and provide this as a separate SystemParam that just doesn't block resources.
This is better than nothing, but IMO the ability to additionally filter this down based on specific components is an important usability win. In most of the cases I can foresee (networking, saving), you're going to want to restrict this based on the presence or absence of a marker component.
This still doesn't give mutable access to Entity components yet. We need a version of EntityMut that doesn't give access to structural mutations first.
changed the title [-]Allow users to read / write from all components of a given entity using an `All` `WorldQuery` type[/-][+]Allow users to read / write from all components of a given entity using `EntityRef` and `EntityMut` `WorldQuery` types[/+]on Jun 23, 2023
changed the title [-]Allow users to read / write from all components of a given entity using `EntityRef` and `EntityMut` `WorldQuery` types[/-][+]Allow users to read / write from all components of a given entity using an `All` `WorldQuery` types[/+]on Jun 23, 2023
Activity
james7132 commentedon Mar 21, 2022
You can sort of do this with
ReflectComponent, though this both requiresReflectimpls, still requires an exclusive system, and is mostly for the dynamic case where the types are not known at compile time. However, I'm not sure what kind of use case forAllComponentswould work where we know the types at compile time that isn't served by generic systems and the existing query type.alice-i-cecile commentedon Mar 21, 2022
Agreed, this would be dramatically more useful after we have dynamic components.
maniwani commentedon Mar 21, 2022
Pretty sure the only thing this query can return is the de-powered version of
EntityRef/Mut.The type system doesn't allow queries to yield a mix of different component fetch tuples.
mockersf commentedon Mar 21, 2022
Could you expand on how that would be used?
Without going full dynamic, you'll need to provide the concrete component type, so why not put it in the query anyway?
maniwani commentedon Mar 21, 2022
Maybe we trade concurrency for ergonomics and provide this as a separate
SystemParamthat just doesn't block resources.[-]Allow users to read / write from all components of a given entity using an AllComponents API[/-][+]Allow users to read / write from all components of a given entity using an `All` `WorldQuery` type[/+]alice-i-cecile commentedon Mar 21, 2022
This is better than nothing, but IMO the ability to additionally filter this down based on specific components is an important usability win. In most of the cases I can foresee (networking, saving), you're going to want to restrict this based on the presence or absence of a marker component.
Implement WorldQuery for EntityRef (#6960)
james7132 commentedon Jun 22, 2023
This still doesn't give mutable access to Entity components yet. We need a version of EntityMut that doesn't give access to structural mutations first.
[-]Allow users to read / write from all components of a given entity using an `All` `WorldQuery` type[/-][+]Allow users to read / write from all components of a given entity using `EntityRef` and `EntityMut` `WorldQuery` types[/+][-]Allow users to read / write from all components of a given entity using `EntityRef` and `EntityMut` `WorldQuery` types[/-][+]Allow users to read / write from all components of a given entity using an `All` `WorldQuery` types[/+]Allow disjoint mutable world access via `EntityMut` (#9419)
Allow disjoint mutable world access via `EntityMut` (bevyengine#9419)