@@ -2666,31 +2666,184 @@ impl<'__w, T: Component<Mutability = Mutable>> ContiguousQueryData for Mut<'__w,
26662666///
26672667/// # Example
26682668///
2669+ /// The simplest way to use a `NestedQuery` is with a `#[derive(QueryData)]` struct.
2670+ /// The `Query` will be available on the generated `Item` struct,
2671+ /// and we can use the query in methods on that struct.
2672+ ///
26692673/// ```
26702674/// # use bevy_ecs::prelude::*;
2671- /// # use bevy_ecs::query::{QueryData, NestedQuery };
2675+ /// # use bevy_ecs::query::{NestedQuery, QueryData, QueryFilter, ReadOnlyQueryData };
26722676/// #
2673- /// #[derive(Component)]
2674- /// struct A(Entity);
2677+ /// # #[derive(Component)]
2678+ /// # struct Data(usize);
2679+ /// #
2680+ /// # let mut world = World::new();
2681+ /// #
2682+ /// // We want to create a relational query data
2683+ /// // that lets us query components on an entity's parent,
2684+ /// // like this:
2685+ /// let root = world.spawn(Data(3)).id();
2686+ /// let child = world.spawn(ChildOf(root)).id();
26752687///
2676- /// #[derive(Component)]
2677- /// struct Name(String);
2688+ /// let mut query = world.query::<Parent<&Data>>();
2689+ /// let &Data(data) = query.query(&mut world).get(child).unwrap().data().unwrap();
2690+ /// assert_eq!(data, 3);
26782691///
2692+ /// // We derive a query data struct that contains the relation plus a `NestedQuery`
26792693/// #[derive(QueryData)]
2680- /// struct NameFromA {
2681- /// a: &'static A,
2682- /// query: NestedQuery<&'static Name>,
2694+ /// struct Parent<D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static = ()> {
2695+ /// // This will query `ChildOf` on the entity itself,
2696+ /// // so we can find the parent entity
2697+ /// parent: &'static ChildOf,
2698+ /// // This will provide a `Query` that we can use to
2699+ /// // query data on the parent entity
2700+ /// nested_query: NestedQuery<D, F>,
2701+ /// }
2702+ ///
2703+ /// // And add a method on the generated item struct to invoke the nested query.
2704+ /// impl<'w, 's, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> ParentItem<'w, 's, D, F> {
2705+ /// fn data(&self) -> Option<D::Item<'w, 's>> {
2706+ /// // We need to use `_inner` methods to return the full `'w` lifetime.
2707+ /// self.nested_query.get_inner(self.parent.parent()).ok()
2708+ /// }
2709+ /// }
2710+ /// ```
2711+ ///
2712+ /// In order to make a query that returns the inner query data directly,
2713+ /// instead of through an intermediate `Item` struct,
2714+ /// you can implement `QueryData` manually by delegating to `NestedQuery`.
2715+ ///
2716+ /// ```
2717+ /// # use bevy_ecs::{
2718+ /// # archetype::Archetype,
2719+ /// # change_detection::Tick,
2720+ /// # component::{ComponentId, Components},
2721+ /// # prelude::*,
2722+ /// # query::{
2723+ /// # EcsAccessType, FilteredAccess, IterQueryData, NestedQuery, QueryData, QueryFilter,
2724+ /// # ReadOnlyQueryData, ReleaseStateQueryData, WorldQuery,
2725+ /// # },
2726+ /// # storage::{Table, TableRow},
2727+ /// # world::unsafe_world_cell::UnsafeWorldCell,
2728+ /// # };
2729+ /// #
2730+ /// # #[derive(Component)]
2731+ /// # struct Data(usize);
2732+ /// #
2733+ /// # let mut world = World::new();
2734+ /// #
2735+ /// // We want to create a relational query data
2736+ /// // that lets us query components on an entity's parent,
2737+ /// // like this:
2738+ /// let root = world.spawn(Data(3)).id();
2739+ /// let child = world.spawn(ChildOf(root)).id();
2740+ ///
2741+ /// let mut query = world.query::<Parent<&Data>>();
2742+ /// let &Data(data) = query.query(&mut world).get(child).unwrap();
2743+ /// assert_eq!(data, 3);
2744+ ///
2745+ /// // This is the relational query data.
2746+ /// // This will never actually be constructed,
2747+ /// // and is only used as a `QueryData` type.
2748+ /// pub struct Parent<D: ReadOnlyQueryData, F: QueryFilter = ()>(D, F);
2749+ ///
2750+ /// // A type alias to delegate the `QueryData` impls to.
2751+ /// // We need to refer to this type a lot, so the alias will help.
2752+ /// // This could also be a `#[derive(QueryData)]` type.
2753+ /// type ParentInner<D, F> = (
2754+ /// // This will query `ChildOf` on the entity itself,
2755+ /// // so we can find the parent entity
2756+ /// &'static ChildOf,
2757+ /// // This will provide a `Query` that we can use to
2758+ /// // query data on the parent entity
2759+ /// NestedQuery<D, F>,
2760+ /// );
2761+ ///
2762+ /// unsafe impl<D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> QueryData for Parent<D, F> {
2763+ /// // Set `Item` to what we need for this relational query.
2764+ /// // Here we use the output of `D`.
2765+ /// type Item<'w, 's> = D::Item<'w, 's>;
2766+ ///
2767+ /// unsafe fn fetch<'w, 's>(state: &'s Self::State, fetch: &mut Self::Fetch<'w>, entity: Entity, table_row: TableRow) -> Option<Self::Item<'w, 's>> {
2768+ /// // In `fetch`, first delegate to the type alias to get the parts:
2769+ /// let (&ChildOf(parent), nested_query) =
2770+ /// <ParentInner<D, F> as QueryData>::fetch(state, fetch, entity, table_row)?;
2771+ /// // Then use the `NestedQuery` to get the data we need.
2772+ /// // We need to use `_inner` methods to return the full `'w` lifetime.
2773+ /// nested_query.get_inner(parent).ok()
2774+ /// }
2775+ ///
2776+ /// fn shrink<'wlong: 'wshort, 'wshort, 's>(item: Self::Item<'wlong, 's>) -> Self::Item<'wshort, 's> {
2777+ /// D::shrink(item)
2778+ /// }
2779+ ///
2780+ /// // Set `ReadOnly` to `Self`,
2781+ /// // as `NestedQuery` does not yet support mutable queries.
2782+ /// type ReadOnly = Self;
2783+ ///
2784+ /// // Delegate everything else on `QueryData` and `WorldQuery` to the type alias.
2785+ /// // This is sound for `unsafe` items because they delegate to the
2786+ /// // sound implementations on the type alias.
2787+ /// const IS_READ_ONLY: bool = <ParentInner<D, F> as QueryData>::IS_READ_ONLY;
2788+ /// const IS_ARCHETYPAL: bool = <ParentInner<D, F> as QueryData>::IS_ARCHETYPAL;
2789+ ///
2790+ /// fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
2791+ /// <ParentInner<D, F> as QueryData>::iter_access(state)
2792+ /// }
26832793/// }
26842794///
2685- /// impl<'w, 's> NameFromAItem<'w, 's> {
2686- /// fn name(&self) -> Option<&str> {
2687- /// self.query.get(self.a.0).ok().map(|name| &*name.0)
2795+ /// unsafe impl<D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> WorldQuery for Parent<D, F> {
2796+ /// type Fetch<'w> = <ParentInner<D, F> as WorldQuery>::Fetch<'w>;
2797+ /// type State = <ParentInner<D, F> as WorldQuery>::State;
2798+ ///
2799+ /// fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2800+ /// <ParentInner<D, F> as WorldQuery>::shrink_fetch(fetch)
2801+ /// }
2802+ ///
2803+ /// unsafe fn init_fetch<'w, 's>(world: UnsafeWorldCell<'w>, state: &'s Self::State, last_run: Tick, this_run: Tick) -> Self::Fetch<'w> {
2804+ /// <ParentInner<D, F> as WorldQuery>::init_fetch(world, state, last_run, this_run)
2805+ /// }
2806+ ///
2807+ /// const IS_DENSE: bool = <ParentInner<D, F> as WorldQuery>::IS_DENSE;
2808+ ///
2809+ /// unsafe fn set_archetype<'w, 's>(fetch: &mut Self::Fetch<'w>, state: &'s Self::State, archetype: &'w Archetype, table: &'w Table) {
2810+ /// <ParentInner<D, F> as WorldQuery>::set_archetype(fetch, state, archetype, table)
2811+ /// }
2812+ ///
2813+ /// unsafe fn set_table<'w, 's>(fetch: &mut Self::Fetch<'w>, state: &'s Self::State, table: &'w Table) {
2814+ /// <ParentInner<D, F> as WorldQuery>::set_table(fetch, state, table)
2815+ /// }
2816+ ///
2817+ /// fn update_component_access(state: &Self::State, access: &mut FilteredAccess) {
2818+ /// <ParentInner<D, F> as WorldQuery>::update_component_access(state, access)
2819+ /// }
2820+ ///
2821+ /// fn init_state(world: &mut World) -> Self::State {
2822+ /// <ParentInner<D, F> as WorldQuery>::init_state(world)
2823+ /// }
2824+ ///
2825+ /// fn get_state(components: &Components) -> Option<Self::State> {
2826+ /// <ParentInner<D, F> as WorldQuery>::get_state(components)
2827+ /// }
2828+ ///
2829+ /// fn matches_component_set(state: &Self::State, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool {
2830+ /// <ParentInner<D, F> as WorldQuery>::matches_component_set(state, set_contains_id)
26882831/// }
26892832/// }
26902833///
2691- /// fn system(query: Query<NameFromA>) {
2692- /// for item in query {
2693- /// let name: Option<&str> = item.name();
2834+ /// // Also impl `ReadOnlyQueryData`, `IterQueryData`, and `ReleaseStateQueryData`
2835+ /// // These are safe because they delegate to the type alias, which is also read-only.
2836+ /// // Do *not* impl `ArchetypeQueryData`, because `fetch` sometimes returns `None`,
2837+ /// // and do *not* impl `SingleEntityQueryData`, because `NestedQuery` accesses other entities.
2838+ /// unsafe impl<D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> ReadOnlyQueryData for Parent<D, F> {}
2839+ ///
2840+ /// unsafe impl<D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> IterQueryData for Parent<D, F> {}
2841+ ///
2842+ /// impl<D: ReadOnlyQueryData + ReleaseStateQueryData + 'static, F: QueryFilter + 'static>
2843+ /// ReleaseStateQueryData for Parent<D, F>
2844+ /// {
2845+ /// fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2846+ /// D::release_state(item)
26942847/// }
26952848/// }
26962849/// ```
0 commit comments