Move Item
and fetch
to QueryData
from WorldQuery
(#17679)
# Objective Fixes #17662 ## Solution Moved `Item` and `fetch` from `WorldQuery` to `QueryData`, and adjusted their implementations accordingly. Currently, documentation related to `fetch` is written under `WorldQuery`. It would be more appropriate to move it to the `QueryData` documentation for clarity. I am not very experienced with making contributions. If there are any mistakes or areas for improvement, I would appreciate any suggestions you may have. ## Migration Guide The `WorldQuery::Item` type and `WorldQuery::fetch` method have been moved to `QueryData`, as they were not useful for `QueryFilter` types. --------- Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com>
This commit is contained in:
parent
6be11a8a42
commit
03af547c28
@ -9,7 +9,7 @@ use bevy_ecs::{
|
||||
archetype::Archetype,
|
||||
component::{ComponentId, Tick},
|
||||
prelude::{Entity, Resource, World},
|
||||
query::{FilteredAccess, QueryFilter, QueryItem, ReadFetch, WorldQuery},
|
||||
query::{FilteredAccess, QueryData, QueryFilter, ReadFetch, WorldQuery},
|
||||
storage::{Table, TableRow},
|
||||
world::unsafe_world_cell::UnsafeWorldCell,
|
||||
};
|
||||
@ -151,13 +151,10 @@ pub struct AssetChangedState<A: AsAssetId> {
|
||||
#[expect(unsafe_code, reason = "WorldQuery is an unsafe trait.")]
|
||||
/// SAFETY: `ROQueryFetch<Self>` is the same as `QueryFetch<Self>`
|
||||
unsafe impl<A: AsAssetId> WorldQuery for AssetChanged<A> {
|
||||
type Item<'w> = ();
|
||||
type Fetch<'w> = AssetChangedFetch<'w, A>;
|
||||
|
||||
type State = AssetChangedState<A>;
|
||||
|
||||
fn shrink<'wlong: 'wshort, 'wshort>(_: QueryItem<'wlong, Self>) -> QueryItem<'wshort, Self> {}
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
@ -228,8 +225,6 @@ unsafe impl<A: AsAssetId> WorldQuery for AssetChanged<A> {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn fetch<'w>(_: &mut Self::Fetch<'w>, _: Entity, _: TableRow) -> Self::Item<'w> {}
|
||||
|
||||
#[inline]
|
||||
fn update_component_access(state: &Self::State, access: &mut FilteredAccess<ComponentId>) {
|
||||
<&A>::update_component_access(&state.asset_id, access);
|
||||
|
@ -176,12 +176,10 @@ pub fn derive_query_data_impl(input: TokenStream) -> TokenStream {
|
||||
&path,
|
||||
&struct_name,
|
||||
&visibility,
|
||||
&item_struct_name,
|
||||
&fetch_struct_name,
|
||||
&field_types,
|
||||
&user_impl_generics,
|
||||
&user_impl_generics_with_world,
|
||||
&field_idents,
|
||||
&user_ty_generics,
|
||||
&user_ty_generics_with_world,
|
||||
&named_field_idents,
|
||||
@ -213,12 +211,10 @@ pub fn derive_query_data_impl(input: TokenStream) -> TokenStream {
|
||||
&path,
|
||||
&read_only_struct_name,
|
||||
&visibility,
|
||||
&read_only_item_struct_name,
|
||||
&read_only_fetch_struct_name,
|
||||
&read_only_field_types,
|
||||
&user_impl_generics,
|
||||
&user_impl_generics_with_world,
|
||||
&field_idents,
|
||||
&user_ty_generics,
|
||||
&user_ty_generics_with_world,
|
||||
&named_field_idents,
|
||||
@ -259,6 +255,29 @@ pub fn derive_query_data_impl(input: TokenStream) -> TokenStream {
|
||||
unsafe impl #user_impl_generics #path::query::QueryData
|
||||
for #read_only_struct_name #user_ty_generics #user_where_clauses {
|
||||
type ReadOnly = #read_only_struct_name #user_ty_generics;
|
||||
type Item<'__w> = #read_only_item_struct_name #user_ty_generics_with_world;
|
||||
|
||||
fn shrink<'__wlong: '__wshort, '__wshort>(
|
||||
item: Self::Item<'__wlong>
|
||||
) -> Self::Item<'__wshort> {
|
||||
#read_only_item_struct_name {
|
||||
#(
|
||||
#field_idents: <#read_only_field_types>::shrink(item.#field_idents),
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
/// SAFETY: we call `fetch` for each member that implements `Fetch`.
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'__w>(
|
||||
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
|
||||
_entity: #path::entity::Entity,
|
||||
_table_row: #path::storage::TableRow,
|
||||
) -> Self::Item<'__w> {
|
||||
Self::Item {
|
||||
#(#field_idents: <#read_only_field_types>::fetch(&mut _fetch.#named_field_idents, _entity, _table_row),)*
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -270,6 +289,29 @@ pub fn derive_query_data_impl(input: TokenStream) -> TokenStream {
|
||||
unsafe impl #user_impl_generics #path::query::QueryData
|
||||
for #struct_name #user_ty_generics #user_where_clauses {
|
||||
type ReadOnly = #read_only_struct_name #user_ty_generics;
|
||||
type Item<'__w> = #item_struct_name #user_ty_generics_with_world;
|
||||
|
||||
fn shrink<'__wlong: '__wshort, '__wshort>(
|
||||
item: Self::Item<'__wlong>
|
||||
) -> Self::Item<'__wshort> {
|
||||
#item_struct_name {
|
||||
#(
|
||||
#field_idents: <#field_types>::shrink(item.#field_idents),
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
/// SAFETY: we call `fetch` for each member that implements `Fetch`.
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'__w>(
|
||||
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
|
||||
_entity: #path::entity::Entity,
|
||||
_table_row: #path::storage::TableRow,
|
||||
) -> Self::Item<'__w> {
|
||||
Self::Item {
|
||||
#(#field_idents: <#field_types>::fetch(&mut _fetch.#named_field_idents, _entity, _table_row),)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#read_only_data_impl
|
||||
|
@ -4,10 +4,7 @@ use proc_macro2::{Ident, Span};
|
||||
use quote::{format_ident, quote};
|
||||
use syn::{parse_macro_input, parse_quote, Data, DataStruct, DeriveInput, Index};
|
||||
|
||||
use crate::{
|
||||
bevy_ecs_path,
|
||||
world_query::{item_struct, world_query_impl},
|
||||
};
|
||||
use crate::{bevy_ecs_path, world_query::world_query_impl};
|
||||
|
||||
mod field_attr_keywords {
|
||||
syn::custom_keyword!(ignore);
|
||||
@ -33,8 +30,6 @@ pub fn derive_query_filter_impl(input: TokenStream) -> TokenStream {
|
||||
|
||||
let struct_name = ast.ident;
|
||||
|
||||
let item_struct_name = Ident::new(&format!("{struct_name}Item"), Span::call_site());
|
||||
|
||||
let fetch_struct_name = Ident::new(&format!("{struct_name}Fetch"), Span::call_site());
|
||||
let fetch_struct_name = ensure_no_collision(fetch_struct_name, tokens.clone());
|
||||
|
||||
@ -81,35 +76,14 @@ pub fn derive_query_filter_impl(input: TokenStream) -> TokenStream {
|
||||
field_types.push(quote!(#field_ty));
|
||||
}
|
||||
|
||||
let derive_macro_call = quote!();
|
||||
|
||||
let item_struct = item_struct(
|
||||
&path,
|
||||
fields,
|
||||
&derive_macro_call,
|
||||
&struct_name,
|
||||
&visibility,
|
||||
&item_struct_name,
|
||||
&field_types,
|
||||
&user_impl_generics_with_world,
|
||||
&field_attrs,
|
||||
&field_visibilities,
|
||||
&field_idents,
|
||||
&user_ty_generics,
|
||||
&user_ty_generics_with_world,
|
||||
user_where_clauses_with_world,
|
||||
);
|
||||
|
||||
let world_query_impl = world_query_impl(
|
||||
&path,
|
||||
&struct_name,
|
||||
&visibility,
|
||||
&item_struct_name,
|
||||
&fetch_struct_name,
|
||||
&field_types,
|
||||
&user_impl_generics,
|
||||
&user_impl_generics_with_world,
|
||||
&field_idents,
|
||||
&user_ty_generics,
|
||||
&user_ty_generics_with_world,
|
||||
&named_field_idents,
|
||||
@ -142,8 +116,6 @@ pub fn derive_query_filter_impl(input: TokenStream) -> TokenStream {
|
||||
};
|
||||
|
||||
TokenStream::from(quote! {
|
||||
#item_struct
|
||||
|
||||
const _: () = {
|
||||
#[doc(hidden)]
|
||||
#[doc = concat!(
|
||||
|
@ -34,14 +34,14 @@ pub(crate) fn item_struct(
|
||||
#derive_macro_call
|
||||
#item_attrs
|
||||
#visibility struct #item_struct_name #user_impl_generics_with_world #user_where_clauses_with_world {
|
||||
#(#(#field_attrs)* #field_visibilities #field_idents: <#field_types as #path::query::WorldQuery>::Item<'__w>,)*
|
||||
#(#(#field_attrs)* #field_visibilities #field_idents: <#field_types as #path::query::QueryData>::Item<'__w>,)*
|
||||
}
|
||||
},
|
||||
Fields::Unnamed(_) => quote! {
|
||||
#derive_macro_call
|
||||
#item_attrs
|
||||
#visibility struct #item_struct_name #user_impl_generics_with_world #user_where_clauses_with_world(
|
||||
#( #field_visibilities <#field_types as #path::query::WorldQuery>::Item<'__w>, )*
|
||||
#( #field_visibilities <#field_types as #path::query::QueryData>::Item<'__w>, )*
|
||||
);
|
||||
},
|
||||
Fields::Unit => quote! {
|
||||
@ -55,12 +55,10 @@ pub(crate) fn world_query_impl(
|
||||
path: &syn::Path,
|
||||
struct_name: &Ident,
|
||||
visibility: &Visibility,
|
||||
item_struct_name: &Ident,
|
||||
fetch_struct_name: &Ident,
|
||||
field_types: &Vec<proc_macro2::TokenStream>,
|
||||
user_impl_generics: &ImplGenerics,
|
||||
user_impl_generics_with_world: &ImplGenerics,
|
||||
field_idents: &Vec<proc_macro2::TokenStream>,
|
||||
user_ty_generics: &TypeGenerics,
|
||||
user_ty_generics_with_world: &TypeGenerics,
|
||||
named_field_idents: &Vec<Ident>,
|
||||
@ -98,20 +96,9 @@ pub(crate) fn world_query_impl(
|
||||
unsafe impl #user_impl_generics #path::query::WorldQuery
|
||||
for #struct_name #user_ty_generics #user_where_clauses {
|
||||
|
||||
type Item<'__w> = #item_struct_name #user_ty_generics_with_world;
|
||||
type Fetch<'__w> = #fetch_struct_name #user_ty_generics_with_world;
|
||||
type State = #state_struct_name #user_ty_generics;
|
||||
|
||||
fn shrink<'__wlong: '__wshort, '__wshort>(
|
||||
item: <#struct_name #user_ty_generics as #path::query::WorldQuery>::Item<'__wlong>
|
||||
) -> <#struct_name #user_ty_generics as #path::query::WorldQuery>::Item<'__wshort> {
|
||||
#item_struct_name {
|
||||
#(
|
||||
#field_idents: <#field_types>::shrink(item.#field_idents),
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
fn shrink_fetch<'__wlong: '__wshort, '__wshort>(
|
||||
fetch: <#struct_name #user_ty_generics as #path::query::WorldQuery>::Fetch<'__wlong>
|
||||
) -> <#struct_name #user_ty_generics as #path::query::WorldQuery>::Fetch<'__wshort> {
|
||||
@ -165,18 +152,6 @@ pub(crate) fn world_query_impl(
|
||||
#(<#field_types>::set_table(&mut _fetch.#named_field_idents, &_state.#named_field_idents, _table);)*
|
||||
}
|
||||
|
||||
/// SAFETY: we call `fetch` for each member that implements `Fetch`.
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'__w>(
|
||||
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
|
||||
_entity: #path::entity::Entity,
|
||||
_table_row: #path::storage::TableRow,
|
||||
) -> <Self as #path::query::WorldQuery>::Item<'__w> {
|
||||
Self::Item {
|
||||
#(#field_idents: <#field_types>::fetch(&mut _fetch.#named_field_idents, _entity, _table_row),)*
|
||||
}
|
||||
}
|
||||
|
||||
fn update_component_access(state: &Self::State, _access: &mut #path::query::FilteredAccess<#path::component::ComponentId>) {
|
||||
#( <#field_types>::update_component_access(&state.#named_field_idents, _access); )*
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -66,7 +66,6 @@ use variadics_please::all_tuples;
|
||||
/// # bevy_ecs::system::assert_is_system(my_system);
|
||||
/// ```
|
||||
///
|
||||
/// [`fetch`]: Self::fetch
|
||||
/// [`matches_component_set`]: Self::matches_component_set
|
||||
/// [`Query`]: crate::system::Query
|
||||
/// [`State`]: Self::State
|
||||
@ -97,7 +96,7 @@ pub unsafe trait QueryFilter: WorldQuery {
|
||||
/// ones that are compatible with the Filter's access.
|
||||
///
|
||||
/// Implementors of this method will generally either have a trivial `true` body (required for archetypal filters),
|
||||
/// or call [`WorldQuery::fetch`] to access the raw data needed to make the final decision on filter inclusion.
|
||||
/// or access the necessary data within this function to make the final decision on filter inclusion.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
@ -141,16 +140,13 @@ pub struct With<T>(PhantomData<T>);
|
||||
|
||||
/// SAFETY:
|
||||
/// `update_component_access` does not add any accesses.
|
||||
/// This is sound because `fetch` does not access any components.
|
||||
/// This is sound because [`QueryFilter::filter_fetch`] does not access any components.
|
||||
/// `update_component_access` adds a `With` filter for `T`.
|
||||
/// This is sound because `matches_component_set` returns whether the set contains the component.
|
||||
unsafe impl<T: Component> WorldQuery for With<T> {
|
||||
type Item<'w> = ();
|
||||
type Fetch<'w> = ();
|
||||
type State = ComponentId;
|
||||
|
||||
fn shrink<'wlong: 'wshort, 'wshort>(_: Self::Item<'wlong>) -> Self::Item<'wshort> {}
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
|
||||
|
||||
#[inline]
|
||||
@ -181,14 +177,6 @@ unsafe impl<T: Component> WorldQuery for With<T> {
|
||||
#[inline]
|
||||
unsafe fn set_table(_fetch: &mut (), _state: &ComponentId, _table: &Table) {}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w>(
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> Self::Item<'w> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn update_component_access(&id: &ComponentId, access: &mut FilteredAccess<ComponentId>) {
|
||||
access.and_with(id);
|
||||
@ -252,16 +240,13 @@ pub struct Without<T>(PhantomData<T>);
|
||||
|
||||
/// SAFETY:
|
||||
/// `update_component_access` does not add any accesses.
|
||||
/// This is sound because `fetch` does not access any components.
|
||||
/// This is sound because [`QueryFilter::filter_fetch`] does not access any components.
|
||||
/// `update_component_access` adds a `Without` filter for `T`.
|
||||
/// This is sound because `matches_component_set` returns whether the set does not contain the component.
|
||||
unsafe impl<T: Component> WorldQuery for Without<T> {
|
||||
type Item<'w> = ();
|
||||
type Fetch<'w> = ();
|
||||
type State = ComponentId;
|
||||
|
||||
fn shrink<'wlong: 'wshort, 'wshort>(_: Self::Item<'wlong>) -> Self::Item<'wshort> {}
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
|
||||
|
||||
#[inline]
|
||||
@ -292,14 +277,6 @@ unsafe impl<T: Component> WorldQuery for Without<T> {
|
||||
#[inline]
|
||||
unsafe fn set_table(_fetch: &mut (), _state: &Self::State, _table: &Table) {}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w>(
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> Self::Item<'w> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn update_component_access(&id: &ComponentId, access: &mut FilteredAccess<ComponentId>) {
|
||||
access.and_without(id);
|
||||
@ -402,19 +379,14 @@ macro_rules! impl_or_query_filter {
|
||||
reason = "Zero-length tuples will generate some function bodies equivalent to `()`; however, this macro is meant for all applicable tuples, and as such it makes no sense to rewrite it just for that case."
|
||||
)]
|
||||
/// SAFETY:
|
||||
/// `fetch` accesses are a subset of the subqueries' accesses
|
||||
/// [`QueryFilter::filter_fetch`] accesses are a subset of the subqueries' accesses
|
||||
/// This is sound because `update_component_access` adds accesses according to the implementations of all the subqueries.
|
||||
/// `update_component_access` replace the filters with a disjunction where every element is a conjunction of the previous filters and the filters of one of the subqueries.
|
||||
/// This is sound because `matches_component_set` returns a disjunction of the results of the subqueries' implementations.
|
||||
unsafe impl<$($filter: QueryFilter),*> WorldQuery for Or<($($filter,)*)> {
|
||||
type Fetch<'w> = ($(OrFetch<'w, $filter>,)*);
|
||||
type Item<'w> = bool;
|
||||
type State = ($($filter::State,)*);
|
||||
|
||||
fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
|
||||
item
|
||||
}
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
let ($($filter,)*) = fetch;
|
||||
($(
|
||||
@ -468,17 +440,6 @@ macro_rules! impl_or_query_filter {
|
||||
)*
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w>(
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
table_row: TableRow
|
||||
) -> Self::Item<'w> {
|
||||
let ($($filter,)*) = fetch;
|
||||
// SAFETY: The invariants are upheld by the caller.
|
||||
false $(|| ($filter.matches && unsafe { $filter::filter_fetch(&mut $filter.fetch, entity, table_row) }))*
|
||||
}
|
||||
|
||||
fn update_component_access(state: &Self::State, access: &mut FilteredAccess<ComponentId>) {
|
||||
let ($($filter,)*) = state;
|
||||
|
||||
@ -515,6 +476,18 @@ macro_rules! impl_or_query_filter {
|
||||
}
|
||||
}
|
||||
|
||||
#[expect(
|
||||
clippy::allow_attributes,
|
||||
reason = "This is a tuple-related macro; as such the lints below may not always apply."
|
||||
)]
|
||||
#[allow(
|
||||
non_snake_case,
|
||||
reason = "The names of some variables are provided by the macro's caller, not by us."
|
||||
)]
|
||||
#[allow(
|
||||
unused_variables,
|
||||
reason = "Zero-length tuples won't use any of the parameters."
|
||||
)]
|
||||
$(#[$meta])*
|
||||
// SAFETY: This only performs access that subqueries perform, and they impl `QueryFilter` and so perform no mutable access.
|
||||
unsafe impl<$($filter: QueryFilter),*> QueryFilter for Or<($($filter,)*)> {
|
||||
@ -526,8 +499,9 @@ macro_rules! impl_or_query_filter {
|
||||
entity: Entity,
|
||||
table_row: TableRow
|
||||
) -> bool {
|
||||
let ($($filter,)*) = fetch;
|
||||
// SAFETY: The invariants are upheld by the caller.
|
||||
unsafe { Self::fetch(fetch, entity, table_row) }
|
||||
false $(|| ($filter.matches && unsafe { $filter::filter_fetch(&mut $filter.fetch, entity, table_row) }))*
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -673,19 +647,14 @@ impl<T: Component> Clone for AddedFetch<'_, T> {
|
||||
}
|
||||
|
||||
/// SAFETY:
|
||||
/// `fetch` accesses a single component in a readonly way.
|
||||
/// [`QueryFilter::filter_fetch`] accesses a single component in a readonly way.
|
||||
/// This is sound because `update_component_access` adds read access for that component and panics when appropriate.
|
||||
/// `update_component_access` adds a `With` filter for a component.
|
||||
/// This is sound because `matches_component_set` returns whether the set contains that component.
|
||||
unsafe impl<T: Component> WorldQuery for Added<T> {
|
||||
type Item<'w> = bool;
|
||||
type Fetch<'w> = AddedFetch<'w, T>;
|
||||
type State = ComponentId;
|
||||
|
||||
fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
|
||||
item
|
||||
}
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
@ -751,32 +720,6 @@ unsafe impl<T: Component> WorldQuery for Added<T> {
|
||||
unsafe { fetch.ticks.set_table(table_ticks) };
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w>(
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
table_row: TableRow,
|
||||
) -> Self::Item<'w> {
|
||||
fetch.ticks.extract(
|
||||
|table| {
|
||||
// SAFETY: set_table was previously called
|
||||
let table = unsafe { table.debug_checked_unwrap() };
|
||||
// SAFETY: The caller ensures `table_row` is in range.
|
||||
let tick = unsafe { table.get(table_row.as_usize()) };
|
||||
|
||||
tick.deref().is_newer_than(fetch.last_run, fetch.this_run)
|
||||
},
|
||||
|sparse_set| {
|
||||
// SAFETY: The caller ensures `entity` is in range.
|
||||
let tick = unsafe {
|
||||
ComponentSparseSet::get_added_tick(sparse_set, entity).debug_checked_unwrap()
|
||||
};
|
||||
|
||||
tick.deref().is_newer_than(fetch.last_run, fetch.this_run)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn update_component_access(&id: &ComponentId, access: &mut FilteredAccess<ComponentId>) {
|
||||
if access.access().has_component_write(id) {
|
||||
@ -811,7 +754,24 @@ unsafe impl<T: Component> QueryFilter for Added<T> {
|
||||
table_row: TableRow,
|
||||
) -> bool {
|
||||
// SAFETY: The invariants are upheld by the caller.
|
||||
unsafe { Self::fetch(fetch, entity, table_row) }
|
||||
fetch.ticks.extract(
|
||||
|table| {
|
||||
// SAFETY: set_table was previously called
|
||||
let table = unsafe { table.debug_checked_unwrap() };
|
||||
// SAFETY: The caller ensures `table_row` is in range.
|
||||
let tick = unsafe { table.get(table_row.as_usize()) };
|
||||
|
||||
tick.deref().is_newer_than(fetch.last_run, fetch.this_run)
|
||||
},
|
||||
|sparse_set| {
|
||||
// SAFETY: The caller ensures `entity` is in range.
|
||||
let tick = unsafe {
|
||||
ComponentSparseSet::get_added_tick(sparse_set, entity).debug_checked_unwrap()
|
||||
};
|
||||
|
||||
tick.deref().is_newer_than(fetch.last_run, fetch.this_run)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -911,14 +871,9 @@ impl<T: Component> Clone for ChangedFetch<'_, T> {
|
||||
/// `update_component_access` adds a `With` filter for a component.
|
||||
/// This is sound because `matches_component_set` returns whether the set contains that component.
|
||||
unsafe impl<T: Component> WorldQuery for Changed<T> {
|
||||
type Item<'w> = bool;
|
||||
type Fetch<'w> = ChangedFetch<'w, T>;
|
||||
type State = ComponentId;
|
||||
|
||||
fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
|
||||
item
|
||||
}
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
@ -984,32 +939,6 @@ unsafe impl<T: Component> WorldQuery for Changed<T> {
|
||||
unsafe { fetch.ticks.set_table(table_ticks) };
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w>(
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
table_row: TableRow,
|
||||
) -> Self::Item<'w> {
|
||||
fetch.ticks.extract(
|
||||
|table| {
|
||||
// SAFETY: set_table was previously called
|
||||
let table = unsafe { table.debug_checked_unwrap() };
|
||||
// SAFETY: The caller ensures `table_row` is in range.
|
||||
let tick = unsafe { table.get(table_row.as_usize()) };
|
||||
|
||||
tick.deref().is_newer_than(fetch.last_run, fetch.this_run)
|
||||
},
|
||||
|sparse_set| {
|
||||
// SAFETY: The caller ensures `entity` is in range.
|
||||
let tick = unsafe {
|
||||
ComponentSparseSet::get_changed_tick(sparse_set, entity).debug_checked_unwrap()
|
||||
};
|
||||
|
||||
tick.deref().is_newer_than(fetch.last_run, fetch.this_run)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn update_component_access(&id: &ComponentId, access: &mut FilteredAccess<ComponentId>) {
|
||||
if access.access().has_component_write(id) {
|
||||
@ -1045,7 +974,24 @@ unsafe impl<T: Component> QueryFilter for Changed<T> {
|
||||
table_row: TableRow,
|
||||
) -> bool {
|
||||
// SAFETY: The invariants are upheld by the caller.
|
||||
unsafe { Self::fetch(fetch, entity, table_row) }
|
||||
fetch.ticks.extract(
|
||||
|table| {
|
||||
// SAFETY: set_table was previously called
|
||||
let table = unsafe { table.debug_checked_unwrap() };
|
||||
// SAFETY: The caller ensures `table_row` is in range.
|
||||
let tick = unsafe { table.get(table_row.as_usize()) };
|
||||
|
||||
tick.deref().is_newer_than(fetch.last_run, fetch.this_run)
|
||||
},
|
||||
|sparse_set| {
|
||||
// SAFETY: The caller ensures `entity` is in range.
|
||||
let tick = unsafe {
|
||||
ComponentSparseSet::get_changed_tick(sparse_set, entity).debug_checked_unwrap()
|
||||
};
|
||||
|
||||
tick.deref().is_newer_than(fetch.last_run, fetch.this_run)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -809,12 +809,9 @@ mod tests {
|
||||
/// `update_component_access` adds resource read access for `R`.
|
||||
/// `update_archetype_component_access` does nothing, as this accesses no components.
|
||||
unsafe impl WorldQuery for ReadsRData {
|
||||
type Item<'w> = ();
|
||||
type Fetch<'w> = ();
|
||||
type State = ComponentId;
|
||||
|
||||
fn shrink<'wlong: 'wshort, 'wshort>(_item: Self::Item<'wlong>) -> Self::Item<'wshort> {}
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
|
||||
|
||||
unsafe fn init_fetch<'w>(
|
||||
@ -844,14 +841,6 @@ mod tests {
|
||||
) {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w>(
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> Self::Item<'w> {
|
||||
}
|
||||
|
||||
fn update_component_access(
|
||||
&component_id: &Self::State,
|
||||
access: &mut FilteredAccess<ComponentId>,
|
||||
@ -882,6 +871,17 @@ mod tests {
|
||||
/// SAFETY: `Self` is the same as `Self::ReadOnly`
|
||||
unsafe impl QueryData for ReadsRData {
|
||||
type ReadOnly = Self;
|
||||
type Item<'w> = ();
|
||||
|
||||
fn shrink<'wlong: 'wshort, 'wshort>(_item: Self::Item<'wlong>) -> Self::Item<'wshort> {}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w>(
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> Self::Item<'w> {
|
||||
}
|
||||
}
|
||||
|
||||
/// SAFETY: access is read only
|
||||
|
@ -1,9 +1,8 @@
|
||||
use crate::{
|
||||
archetype::Archetype,
|
||||
component::{ComponentId, Components, Tick},
|
||||
entity::Entity,
|
||||
query::FilteredAccess,
|
||||
storage::{Table, TableRow},
|
||||
storage::Table,
|
||||
world::{unsafe_world_cell::UnsafeWorldCell, World},
|
||||
};
|
||||
use variadics_please::all_tuples;
|
||||
@ -14,11 +13,11 @@ use variadics_please::all_tuples;
|
||||
/// # Safety
|
||||
///
|
||||
/// Implementor must ensure that
|
||||
/// [`update_component_access`], [`matches_component_set`], [`fetch`] and [`init_fetch`]
|
||||
/// [`update_component_access`], [`matches_component_set`], [`QueryData::fetch`], [`QueryFilter::filter_fetch`] and [`init_fetch`]
|
||||
/// obey the following:
|
||||
///
|
||||
/// - For each component mutably accessed by [`fetch`], [`update_component_access`] should add write access unless read or write access has already been added, in which case it should panic.
|
||||
/// - For each component readonly accessed by [`fetch`], [`update_component_access`] should add read access unless write access has already been added, in which case it should panic.
|
||||
/// - For each component mutably accessed by [`QueryData::fetch`], [`update_component_access`] should add write access unless read or write access has already been added, in which case it should panic.
|
||||
/// - For each component readonly accessed by [`QueryData::fetch`] or [`QueryFilter::filter_fetch`], [`update_component_access`] should add read access unless write access has already been added, in which case it should panic.
|
||||
/// - If `fetch` mutably accesses the same component twice, [`update_component_access`] should panic.
|
||||
/// - [`update_component_access`] may not add a `Without` filter for a component unless [`matches_component_set`] always returns `false` when the component set contains that component.
|
||||
/// - [`update_component_access`] may not add a `With` filter for a component unless [`matches_component_set`] always returns `false` when the component set doesn't contain that component.
|
||||
@ -31,7 +30,8 @@ use variadics_please::all_tuples;
|
||||
///
|
||||
/// When implementing [`update_component_access`], note that `add_read` and `add_write` both also add a `With` filter, whereas `extend_access` does not change the filters.
|
||||
///
|
||||
/// [`fetch`]: Self::fetch
|
||||
/// [`QueryData::fetch`]: crate::query::QueryData::fetch
|
||||
/// [`QueryFilter::filter_fetch`]: crate::query::QueryFilter::filter_fetch
|
||||
/// [`init_fetch`]: Self::init_fetch
|
||||
/// [`matches_component_set`]: Self::matches_component_set
|
||||
/// [`Query`]: crate::system::Query
|
||||
@ -39,19 +39,7 @@ use variadics_please::all_tuples;
|
||||
/// [`QueryData`]: crate::query::QueryData
|
||||
/// [`QueryFilter`]: crate::query::QueryFilter
|
||||
pub unsafe trait WorldQuery {
|
||||
/// The item returned by this [`WorldQuery`]
|
||||
/// For `QueryData` this will be the data retrieved by the query,
|
||||
/// and is visible to the end user when calling e.g. `Query<Self>::get`.
|
||||
///
|
||||
/// For `QueryFilter` this will be either `()`, or a `bool` indicating whether the entity should be included
|
||||
/// or a tuple of such things.
|
||||
/// Archetypal query filters (like `With`) set this to `()`,
|
||||
/// as the filtering is done by selecting the archetypes to iterate over via [`WorldQuery::matches_component_set`],
|
||||
/// while non-archetypal query filters (like `Changed`) set this to a `bool` and evaluate the filter for each entity,
|
||||
/// after the set of possible archetypes has been narrowed down.
|
||||
type Item<'a>;
|
||||
|
||||
/// Per archetype/table state retrieved by this [`WorldQuery`] to compute [`Self::Item`](WorldQuery::Item) for each entity.
|
||||
/// Per archetype/table state retrieved by this [`WorldQuery`] to compute [`Self::Item`](crate::query::QueryData::Item) for each entity.
|
||||
type Fetch<'a>: Clone;
|
||||
|
||||
/// State used to construct a [`Self::Fetch`](WorldQuery::Fetch). This will be cached inside [`QueryState`](crate::query::QueryState),
|
||||
@ -59,9 +47,6 @@ pub unsafe trait WorldQuery {
|
||||
/// constructing [`Self::Fetch`](WorldQuery::Fetch).
|
||||
type State: Send + Sync + Sized;
|
||||
|
||||
/// This function manually implements subtyping for the query items.
|
||||
fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort>;
|
||||
|
||||
/// This function manually implements subtyping for the query fetches.
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort>;
|
||||
|
||||
@ -87,8 +72,8 @@ pub unsafe trait WorldQuery {
|
||||
///
|
||||
/// This is used to select a more efficient "table iterator"
|
||||
/// for "dense" queries. If this returns true, [`WorldQuery::set_table`] must be used before
|
||||
/// [`WorldQuery::fetch`] can be called for iterators. If this returns false,
|
||||
/// [`WorldQuery::set_archetype`] must be used before [`WorldQuery::fetch`] can be called for
|
||||
/// [`QueryData::fetch`](crate::query::QueryData::fetch) can be called for iterators. If this returns false,
|
||||
/// [`WorldQuery::set_archetype`] must be used before [`QueryData::fetch`](crate::query::QueryData::fetch) can be called for
|
||||
/// iterators.
|
||||
const IS_DENSE: bool;
|
||||
|
||||
@ -122,23 +107,6 @@ pub unsafe trait WorldQuery {
|
||||
/// Called when constructing a [`QueryLens`](crate::system::QueryLens) or calling [`QueryState::from_builder`](super::QueryState::from_builder)
|
||||
fn set_access(_state: &mut Self::State, _access: &FilteredAccess<ComponentId>) {}
|
||||
|
||||
/// Fetch [`Self::Item`](`WorldQuery::Item`) for either the given `entity` in the current [`Table`],
|
||||
/// or for the given `entity` in the current [`Archetype`]. This must always be called after
|
||||
/// [`WorldQuery::set_table`] with a `table_row` in the range of the current [`Table`] or after
|
||||
/// [`WorldQuery::set_archetype`] with an `entity` in the current archetype.
|
||||
/// Accesses components registered in [`WorldQuery::update_component_access`].
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// - Must always be called _after_ [`WorldQuery::set_table`] or [`WorldQuery::set_archetype`]. `entity` and
|
||||
/// `table_row` must be in the range of the current table and archetype.
|
||||
/// - There must not be simultaneous conflicting component access registered in `update_component_access`.
|
||||
unsafe fn fetch<'w>(
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
table_row: TableRow,
|
||||
) -> Self::Item<'w>;
|
||||
|
||||
/// Adds any component accesses used by this [`WorldQuery`] to `access`.
|
||||
///
|
||||
/// Used to check which queries are disjoint and can run in parallel
|
||||
@ -191,15 +159,8 @@ macro_rules! impl_tuple_world_query {
|
||||
/// This is sound because `matches_component_set` always returns `false` if any the subqueries' implementations return `false`.
|
||||
unsafe impl<$($name: WorldQuery),*> WorldQuery for ($($name,)*) {
|
||||
type Fetch<'w> = ($($name::Fetch<'w>,)*);
|
||||
type Item<'w> = ($($name::Item<'w>,)*);
|
||||
type State = ($($name::State,)*);
|
||||
|
||||
fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
|
||||
let ($($name,)*) = item;
|
||||
($(
|
||||
$name::shrink($name),
|
||||
)*)
|
||||
}
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
let ($($name,)*) = fetch;
|
||||
@ -238,16 +199,6 @@ macro_rules! impl_tuple_world_query {
|
||||
$(unsafe { $name::set_table($name, $state, table); })*
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w>(
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
table_row: TableRow
|
||||
) -> Self::Item<'w> {
|
||||
let ($($name,)*) = fetch;
|
||||
// SAFETY: The invariants are upheld by the caller.
|
||||
($(unsafe { $name::fetch($name, entity, table_row) },)*)
|
||||
}
|
||||
|
||||
fn update_component_access(state: &Self::State, access: &mut FilteredAccess<ComponentId>) {
|
||||
let ($($name,)*) = state;
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
entity::Entity,
|
||||
query::{QueryData, QueryFilter, WorldQuery},
|
||||
query::{QueryData, QueryFilter},
|
||||
relationship::{Relationship, RelationshipTarget},
|
||||
system::Query,
|
||||
};
|
||||
@ -14,7 +14,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
||||
/// target entity of that relationship.
|
||||
pub fn related<R: Relationship>(&'w self, entity: Entity) -> Option<Entity>
|
||||
where
|
||||
<D as QueryData>::ReadOnly: WorldQuery<Item<'w> = &'w R>,
|
||||
<D as QueryData>::ReadOnly: QueryData<Item<'w> = &'w R>,
|
||||
{
|
||||
self.get(entity).map(R::get).ok()
|
||||
}
|
||||
@ -26,7 +26,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
||||
entity: Entity,
|
||||
) -> impl Iterator<Item = Entity> + 'w
|
||||
where
|
||||
<D as QueryData>::ReadOnly: WorldQuery<Item<'w> = &'w S>,
|
||||
<D as QueryData>::ReadOnly: QueryData<Item<'w> = &'w S>,
|
||||
{
|
||||
self.get(entity)
|
||||
.into_iter()
|
||||
@ -42,7 +42,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
||||
/// If your relationship is not a tree (like Bevy's hierarchy), be sure to stop if you encounter a duplicate entity.
|
||||
pub fn root_ancestor<R: Relationship>(&'w self, entity: Entity) -> Entity
|
||||
where
|
||||
<D as QueryData>::ReadOnly: WorldQuery<Item<'w> = &'w R>,
|
||||
<D as QueryData>::ReadOnly: QueryData<Item<'w> = &'w R>,
|
||||
{
|
||||
// Recursively search up the tree until we're out of parents
|
||||
match self.get(entity) {
|
||||
@ -62,7 +62,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
||||
entity: Entity,
|
||||
) -> impl Iterator<Item = Entity> + 'w
|
||||
where
|
||||
<D as QueryData>::ReadOnly: WorldQuery<Item<'w> = &'w S>,
|
||||
<D as QueryData>::ReadOnly: QueryData<Item<'w> = &'w S>,
|
||||
SourceIter<'w, S>: DoubleEndedIterator,
|
||||
{
|
||||
self.iter_descendants_depth_first(entity).filter(|entity| {
|
||||
@ -80,7 +80,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
||||
entity: Entity,
|
||||
) -> impl Iterator<Item = Entity> + 'w
|
||||
where
|
||||
D::ReadOnly: WorldQuery<Item<'w> = (Option<&'w R>, Option<&'w R::RelationshipTarget>)>,
|
||||
D::ReadOnly: QueryData<Item<'w> = (Option<&'w R>, Option<&'w R::RelationshipTarget>)>,
|
||||
{
|
||||
self.get(entity)
|
||||
.ok()
|
||||
@ -103,7 +103,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
||||
entity: Entity,
|
||||
) -> DescendantIter<'w, 's, D, F, S>
|
||||
where
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w S>,
|
||||
D::ReadOnly: QueryData<Item<'w> = &'w S>,
|
||||
{
|
||||
DescendantIter::new(self, entity)
|
||||
}
|
||||
@ -120,7 +120,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
||||
entity: Entity,
|
||||
) -> DescendantDepthFirstIter<'w, 's, D, F, S>
|
||||
where
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w S>,
|
||||
D::ReadOnly: QueryData<Item<'w> = &'w S>,
|
||||
SourceIter<'w, S>: DoubleEndedIterator,
|
||||
{
|
||||
DescendantDepthFirstIter::new(self, entity)
|
||||
@ -137,7 +137,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
||||
entity: Entity,
|
||||
) -> AncestorIter<'w, 's, D, F, R>
|
||||
where
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w R>,
|
||||
D::ReadOnly: QueryData<Item<'w> = &'w R>,
|
||||
{
|
||||
AncestorIter::new(self, entity)
|
||||
}
|
||||
@ -148,7 +148,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
||||
/// Traverses the hierarchy breadth-first.
|
||||
pub struct DescendantIter<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget>
|
||||
where
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w S>,
|
||||
D::ReadOnly: QueryData<Item<'w> = &'w S>,
|
||||
{
|
||||
children_query: &'w Query<'w, 's, D, F>,
|
||||
vecdeque: VecDeque<Entity>,
|
||||
@ -156,7 +156,7 @@ where
|
||||
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget> DescendantIter<'w, 's, D, F, S>
|
||||
where
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w S>,
|
||||
D::ReadOnly: QueryData<Item<'w> = &'w S>,
|
||||
{
|
||||
/// Returns a new [`DescendantIter`].
|
||||
pub fn new(children_query: &'w Query<'w, 's, D, F>, entity: Entity) -> Self {
|
||||
@ -174,7 +174,7 @@ where
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget> Iterator
|
||||
for DescendantIter<'w, 's, D, F, S>
|
||||
where
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w S>,
|
||||
D::ReadOnly: QueryData<Item<'w> = &'w S>,
|
||||
{
|
||||
type Item = Entity;
|
||||
|
||||
@ -194,7 +194,7 @@ where
|
||||
/// Traverses the hierarchy depth-first.
|
||||
pub struct DescendantDepthFirstIter<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget>
|
||||
where
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w S>,
|
||||
D::ReadOnly: QueryData<Item<'w> = &'w S>,
|
||||
{
|
||||
children_query: &'w Query<'w, 's, D, F>,
|
||||
stack: SmallVec<[Entity; 8]>,
|
||||
@ -203,7 +203,7 @@ where
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget>
|
||||
DescendantDepthFirstIter<'w, 's, D, F, S>
|
||||
where
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w S>,
|
||||
D::ReadOnly: QueryData<Item<'w> = &'w S>,
|
||||
SourceIter<'w, S>: DoubleEndedIterator,
|
||||
{
|
||||
/// Returns a new [`DescendantDepthFirstIter`].
|
||||
@ -220,7 +220,7 @@ where
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget> Iterator
|
||||
for DescendantDepthFirstIter<'w, 's, D, F, S>
|
||||
where
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w S>,
|
||||
D::ReadOnly: QueryData<Item<'w> = &'w S>,
|
||||
SourceIter<'w, S>: DoubleEndedIterator,
|
||||
{
|
||||
type Item = Entity;
|
||||
@ -239,7 +239,7 @@ where
|
||||
/// An [`Iterator`] of [`Entity`]s over the ancestors of an [`Entity`].
|
||||
pub struct AncestorIter<'w, 's, D: QueryData, F: QueryFilter, R: Relationship>
|
||||
where
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w R>,
|
||||
D::ReadOnly: QueryData<Item<'w> = &'w R>,
|
||||
{
|
||||
parent_query: &'w Query<'w, 's, D, F>,
|
||||
next: Option<Entity>,
|
||||
@ -247,7 +247,7 @@ where
|
||||
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter, R: Relationship> AncestorIter<'w, 's, D, F, R>
|
||||
where
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w R>,
|
||||
D::ReadOnly: QueryData<Item<'w> = &'w R>,
|
||||
{
|
||||
/// Returns a new [`AncestorIter`].
|
||||
pub fn new(parent_query: &'w Query<'w, 's, D, F>, entity: Entity) -> Self {
|
||||
@ -261,7 +261,7 @@ where
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter, R: Relationship> Iterator
|
||||
for AncestorIter<'w, 's, D, F, R>
|
||||
where
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w R>,
|
||||
D::ReadOnly: QueryData<Item<'w> = &'w R>,
|
||||
{
|
||||
type Item = Entity;
|
||||
|
||||
|
@ -285,14 +285,9 @@ mod render_entities_world_query_impls {
|
||||
/// SAFETY: defers completely to `&RenderEntity` implementation,
|
||||
/// and then only modifies the output safely.
|
||||
unsafe impl WorldQuery for RenderEntity {
|
||||
type Item<'w> = Entity;
|
||||
type Fetch<'w> = <&'static RenderEntity as WorldQuery>::Fetch<'w>;
|
||||
type State = <&'static RenderEntity as WorldQuery>::State;
|
||||
|
||||
fn shrink<'wlong: 'wshort, 'wshort>(item: Entity) -> Entity {
|
||||
item
|
||||
}
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(
|
||||
fetch: Self::Fetch<'wlong>,
|
||||
) -> Self::Fetch<'wshort> {
|
||||
@ -337,18 +332,6 @@ mod render_entities_world_query_impls {
|
||||
unsafe { <&RenderEntity as WorldQuery>::set_table(fetch, &component_id, table) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w>(
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
table_row: TableRow,
|
||||
) -> Self::Item<'w> {
|
||||
// SAFETY: defers to the `&T` implementation, with T set to `RenderEntity`.
|
||||
let component =
|
||||
unsafe { <&RenderEntity as WorldQuery>::fetch(fetch, entity, table_row) };
|
||||
component.id()
|
||||
}
|
||||
|
||||
fn update_component_access(
|
||||
&component_id: &ComponentId,
|
||||
access: &mut FilteredAccess<ComponentId>,
|
||||
@ -376,6 +359,23 @@ mod render_entities_world_query_impls {
|
||||
// Self::ReadOnly matches exactly the same archetypes/tables as Self.
|
||||
unsafe impl QueryData for RenderEntity {
|
||||
type ReadOnly = RenderEntity;
|
||||
type Item<'w> = Entity;
|
||||
|
||||
fn shrink<'wlong: 'wshort, 'wshort>(item: Entity) -> Entity {
|
||||
item
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w>(
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
table_row: TableRow,
|
||||
) -> Self::Item<'w> {
|
||||
// SAFETY: defers to the `&T` implementation, with T set to `RenderEntity`.
|
||||
let component =
|
||||
unsafe { <&RenderEntity as QueryData>::fetch(fetch, entity, table_row) };
|
||||
component.id()
|
||||
}
|
||||
}
|
||||
|
||||
// SAFETY: the underlying `Entity` is copied, and no mutable access is provided.
|
||||
@ -384,14 +384,9 @@ mod render_entities_world_query_impls {
|
||||
/// SAFETY: defers completely to `&RenderEntity` implementation,
|
||||
/// and then only modifies the output safely.
|
||||
unsafe impl WorldQuery for MainEntity {
|
||||
type Item<'w> = Entity;
|
||||
type Fetch<'w> = <&'static MainEntity as WorldQuery>::Fetch<'w>;
|
||||
type State = <&'static MainEntity as WorldQuery>::State;
|
||||
|
||||
fn shrink<'wlong: 'wshort, 'wshort>(item: Entity) -> Entity {
|
||||
item
|
||||
}
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(
|
||||
fetch: Self::Fetch<'wlong>,
|
||||
) -> Self::Fetch<'wshort> {
|
||||
@ -436,17 +431,6 @@ mod render_entities_world_query_impls {
|
||||
unsafe { <&MainEntity as WorldQuery>::set_table(fetch, &component_id, table) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w>(
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
table_row: TableRow,
|
||||
) -> Self::Item<'w> {
|
||||
// SAFETY: defers to the `&T` implementation, with T set to `MainEntity`.
|
||||
let component = unsafe { <&MainEntity as WorldQuery>::fetch(fetch, entity, table_row) };
|
||||
component.id()
|
||||
}
|
||||
|
||||
fn update_component_access(
|
||||
&component_id: &ComponentId,
|
||||
access: &mut FilteredAccess<ComponentId>,
|
||||
@ -474,6 +458,22 @@ mod render_entities_world_query_impls {
|
||||
// Self::ReadOnly matches exactly the same archetypes/tables as Self.
|
||||
unsafe impl QueryData for MainEntity {
|
||||
type ReadOnly = MainEntity;
|
||||
type Item<'w> = Entity;
|
||||
|
||||
fn shrink<'wlong: 'wshort, 'wshort>(item: Entity) -> Entity {
|
||||
item
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w>(
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
table_row: TableRow,
|
||||
) -> Self::Item<'w> {
|
||||
// SAFETY: defers to the `&T` implementation, with T set to `MainEntity`.
|
||||
let component = unsafe { <&MainEntity as QueryData>::fetch(fetch, entity, table_row) };
|
||||
component.id()
|
||||
}
|
||||
}
|
||||
|
||||
// SAFETY: the underlying `Entity` is copied, and no mutable access is provided.
|
||||
|
Loading…
Reference in New Issue
Block a user