-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Upstream reflect_query #8816
Upstream reflect_query #8816
Conversation
Read the cuicui_reflect_query README for motivation. <https://crates.io/crates/cuicui_reflect_query>
/// [`map_all_entities`](Self::map_all_entities), this is applied to specific entities, not all values | ||
/// in the [`EntityMap`]. | ||
/// | ||
/// This is useful mostly for when you need to be careful not to update components that already contain valid entity |
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.
It sounds like there could be a map_absent_entities
method built in to abstract over this pattern.
@@ -0,0 +1,169 @@ | |||
//! Define wrapper types & traits for bevy's `QueryState` and `QueryIter`. |
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.
Doc links please.
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.
I like the split, docs are excellent. I think this makes more sense upstream in Bevy than as a third-party crate. This is effectively the last missing piece to making dynamic components work properly.
Macro-generated docs are a bit controversial, but I'm fine with them here.
I'd like to see:
- tests
- an end user example that demonstrates a semi-realistic use of this for teaching and API evaluation purposes
- expanded module level docs to explain what reflection is and why users might actually care
yeah FYI I'm not sure this deserves being merged. I won't spend much time on this unless there is a clear interest from various people. I think a solution similar to #6390 is closer to what we want. There is no reasons we can't have a I'll probably open a PR to split the |
I agree, this should be done regardless and is best suited to a quick merge. |
Superseded by #9774 |
Read the cuicui_reflect_query README for motivation.
https://crates.io/crates/cuicui_reflect_query
Objective
Bevy's
ReflectComponent
allows extracting a value from aEntityRef
orEntityMut
, this can be useful, but generally not enough.ReflectComponent
is missing ways to query for the reflected thing.Without this ability, you would be stuck iterating over all
EntityRef
andchecking if it contains the component in question. This is O(n) (where
n
isthe total count of entities) while querying just for a single entity is O(1).
Solution
Split the
reflect.rs
module inbevy_ecs
into smaller parts.Add the following methods to
ReflectComponent
:reflect_ref
: This is similar toReflectComponent::reflect
, but also includeschange tick data. This allows reading change ticks on the reflected component
in an immutable way.
Furthermore, the
reflect_mut
method has lifetime limitations, this might be a goodway to work around them.
query{,_entities,_ref,_mut}
: Iterate over all entities with the reflected component.Like with
world.query
, you need to call.query(world)
on the return valueto iterate over the query results.
get_single{,_entity,_ref,_mut}
: similar toworld.get_single
, it will returna value only if there is exactly one entity containing the reflected component.
A bit of precision:
_entity
variants return anEntity
or an iterator of entities insteadof the
dyn Reflect
version of the component._ref
variants return aRef<_>
over_
, this let you read change informationin an immutable maner.
Similar work
WorldQuery
with runtime values #6390Changelog
ReflectComponent
to allow querying from aWorld
the components in question:reflect_ref: fn(EntityRef) -> Option<Ref<dyn Reflect>>
,get_single: fn(&mut World) -> SingleResult<&dyn Reflect>
,get_single_entity: fn(&mut World) -> SingleResult<Entity>
,get_single_ref: fn(&mut World) -> SingleResult<Ref<dyn Reflect>>
,get_single_mut: fn(&mut World) -> SingleResult<Mut<dyn Reflect>>
,query: fn(&mut World) -> Querydyn
,query_entities: fn(&mut World) -> EntityQuerydyn
,query_ref: fn(&mut World) -> RefQuerydyn
,query_mut: fn(&mut World) -> MutQuerydyn
,EntityRef::get_ref
to get a value + change tick.Ref::map
method to accept unsizedU
s