Remove 's
lifetime from WorldQuery::Fetch
(#19720)
# Objective Unblock #18162. #15396 added the `'s` lifetime to `QueryData::Item` to make it possible for query items to borrow from the state. The state isn't passed directly to `QueryData::fetch()`, so it also added the `'s` lifetime to `WorldQuery::Fetch` so that we can pass the borrows through there. Unfortunately, having `WorldQuery::Fetch` borrow from the state makes it impossible to have owned state, because we store the state and the `Fetch` in the same `struct` during iteration. ## Solution Undo the change to add the `'s` lifetime to `WorldQuery::Fetch`. Instead, add a `&'s Self::State` parameter to `QueryData::fetch()` and `QueryFilter::filter_fetch()` so that borrows from the state can be passed directly to query items. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: Emerson Coskey <emerson@coskey.dev>
This commit is contained in:
parent
4e694aea53
commit
d0550f58ae
@ -150,13 +150,11 @@ 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 Fetch<'w, 's> = AssetChangedFetch<'w, A>;
|
||||
type Fetch<'w> = AssetChangedFetch<'w, A>;
|
||||
|
||||
type State = AssetChangedState<A>;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -165,7 +163,7 @@ unsafe impl<A: AsAssetId> WorldQuery for AssetChanged<A> {
|
||||
state: &'s Self::State,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
// SAFETY:
|
||||
// - `AssetChanges` is private and only accessed mutably in the `AssetEventSystems` system set.
|
||||
// - `resource_id` was obtained from the type ID of `AssetChanges<A::Asset>`.
|
||||
@ -204,7 +202,7 @@ unsafe impl<A: AsAssetId> WorldQuery for AssetChanged<A> {
|
||||
const IS_DENSE: bool = <&A>::IS_DENSE;
|
||||
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
state: &'s Self::State,
|
||||
archetype: &'w Archetype,
|
||||
table: &'w Table,
|
||||
@ -218,7 +216,7 @@ unsafe impl<A: AsAssetId> WorldQuery for AssetChanged<A> {
|
||||
}
|
||||
|
||||
unsafe fn set_table<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
state: &Self::State,
|
||||
table: &'w Table,
|
||||
) {
|
||||
@ -271,14 +269,15 @@ unsafe impl<A: AsAssetId> QueryFilter for AssetChanged<A> {
|
||||
|
||||
#[inline]
|
||||
unsafe fn filter_fetch(
|
||||
fetch: &mut Self::Fetch<'_, '_>,
|
||||
state: &Self::State,
|
||||
fetch: &mut Self::Fetch<'_>,
|
||||
entity: Entity,
|
||||
table_row: TableRow,
|
||||
) -> bool {
|
||||
fetch.inner.as_mut().is_some_and(|inner| {
|
||||
// SAFETY: We delegate to the inner `fetch` for `A`
|
||||
unsafe {
|
||||
let handle = <&A>::fetch(inner, entity, table_row);
|
||||
let handle = <&A>::fetch(&state.asset_id, inner, entity, table_row);
|
||||
fetch.check.has_changed(handle)
|
||||
}
|
||||
})
|
||||
|
@ -74,13 +74,23 @@ pub fn derive_query_data_impl(input: TokenStream) -> TokenStream {
|
||||
let user_generics = ast.generics.clone();
|
||||
let (user_impl_generics, user_ty_generics, user_where_clauses) = user_generics.split_for_impl();
|
||||
let user_generics_with_world = {
|
||||
let mut generics = ast.generics.clone();
|
||||
generics.params.insert(0, parse_quote!('__w));
|
||||
generics
|
||||
};
|
||||
let (user_impl_generics_with_world, user_ty_generics_with_world, user_where_clauses_with_world) =
|
||||
user_generics_with_world.split_for_impl();
|
||||
let user_generics_with_world_and_state = {
|
||||
let mut generics = ast.generics;
|
||||
generics.params.insert(0, parse_quote!('__w));
|
||||
generics.params.insert(0, parse_quote!('__s));
|
||||
generics
|
||||
};
|
||||
let (user_impl_generics_with_world, user_ty_generics_with_world, user_where_clauses_with_world) =
|
||||
user_generics_with_world.split_for_impl();
|
||||
let (
|
||||
user_impl_generics_with_world_and_state,
|
||||
user_ty_generics_with_world_and_state,
|
||||
user_where_clauses_with_world_and_state,
|
||||
) = user_generics_with_world_and_state.split_for_impl();
|
||||
|
||||
let struct_name = ast.ident;
|
||||
let read_only_struct_name = if attributes.is_mutable {
|
||||
@ -165,13 +175,13 @@ pub fn derive_query_data_impl(input: TokenStream) -> TokenStream {
|
||||
&visibility,
|
||||
&item_struct_name,
|
||||
&field_types,
|
||||
&user_impl_generics_with_world,
|
||||
&user_impl_generics_with_world_and_state,
|
||||
&field_attrs,
|
||||
&field_visibilities,
|
||||
&field_idents,
|
||||
&user_ty_generics,
|
||||
&user_ty_generics_with_world,
|
||||
user_where_clauses_with_world,
|
||||
&user_ty_generics_with_world_and_state,
|
||||
user_where_clauses_with_world_and_state,
|
||||
);
|
||||
let mutable_world_query_impl = world_query_impl(
|
||||
&path,
|
||||
@ -200,13 +210,13 @@ pub fn derive_query_data_impl(input: TokenStream) -> TokenStream {
|
||||
&visibility,
|
||||
&read_only_item_struct_name,
|
||||
&read_only_field_types,
|
||||
&user_impl_generics_with_world,
|
||||
&user_impl_generics_with_world_and_state,
|
||||
&field_attrs,
|
||||
&field_visibilities,
|
||||
&field_idents,
|
||||
&user_ty_generics,
|
||||
&user_ty_generics_with_world,
|
||||
user_where_clauses_with_world,
|
||||
&user_ty_generics_with_world_and_state,
|
||||
user_where_clauses_with_world_and_state,
|
||||
);
|
||||
let readonly_world_query_impl = world_query_impl(
|
||||
&path,
|
||||
@ -257,7 +267,7 @@ pub fn derive_query_data_impl(input: TokenStream) -> TokenStream {
|
||||
for #read_only_struct_name #user_ty_generics #user_where_clauses {
|
||||
const IS_READ_ONLY: bool = true;
|
||||
type ReadOnly = #read_only_struct_name #user_ty_generics;
|
||||
type Item<'__w, '__s> = #read_only_item_struct_name #user_ty_generics_with_world;
|
||||
type Item<'__w, '__s> = #read_only_item_struct_name #user_ty_generics_with_world_and_state;
|
||||
|
||||
fn shrink<'__wlong: '__wshort, '__wshort, '__s>(
|
||||
item: Self::Item<'__wlong, '__s>
|
||||
@ -280,12 +290,13 @@ pub fn derive_query_data_impl(input: TokenStream) -> TokenStream {
|
||||
/// SAFETY: we call `fetch` for each member that implements `Fetch`.
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'__w, '__s>(
|
||||
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w, '__s>,
|
||||
_state: &'__s Self::State,
|
||||
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
|
||||
_entity: #path::entity::Entity,
|
||||
_table_row: #path::storage::TableRow,
|
||||
) -> Self::Item<'__w, '__s> {
|
||||
Self::Item {
|
||||
#(#field_idents: <#read_only_field_types>::fetch(&mut _fetch.#named_field_idents, _entity, _table_row),)*
|
||||
#(#field_idents: <#read_only_field_types>::fetch(&_state.#named_field_idents, &mut _fetch.#named_field_idents, _entity, _table_row),)*
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -314,7 +325,7 @@ pub fn derive_query_data_impl(input: TokenStream) -> TokenStream {
|
||||
for #struct_name #user_ty_generics #user_where_clauses {
|
||||
const IS_READ_ONLY: bool = #is_read_only;
|
||||
type ReadOnly = #read_only_struct_name #user_ty_generics;
|
||||
type Item<'__w, '__s> = #item_struct_name #user_ty_generics_with_world;
|
||||
type Item<'__w, '__s> = #item_struct_name #user_ty_generics_with_world_and_state;
|
||||
|
||||
fn shrink<'__wlong: '__wshort, '__wshort, '__s>(
|
||||
item: Self::Item<'__wlong, '__s>
|
||||
@ -337,12 +348,13 @@ pub fn derive_query_data_impl(input: TokenStream) -> TokenStream {
|
||||
/// SAFETY: we call `fetch` for each member that implements `Fetch`.
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'__w, '__s>(
|
||||
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w, '__s>,
|
||||
_state: &'__s Self::State,
|
||||
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
|
||||
_entity: #path::entity::Entity,
|
||||
_table_row: #path::storage::TableRow,
|
||||
) -> Self::Item<'__w, '__s> {
|
||||
Self::Item {
|
||||
#(#field_idents: <#field_types>::fetch(&mut _fetch.#named_field_idents, _entity, _table_row),)*
|
||||
#(#field_idents: <#field_types>::fetch(&_state.#named_field_idents, &mut _fetch.#named_field_idents, _entity, _table_row),)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ pub fn derive_query_filter_impl(input: TokenStream) -> TokenStream {
|
||||
let user_generics_with_world = {
|
||||
let mut generics = ast.generics;
|
||||
generics.params.insert(0, parse_quote!('__w));
|
||||
generics.params.insert(0, parse_quote!('__s));
|
||||
generics
|
||||
};
|
||||
let (user_impl_generics_with_world, user_ty_generics_with_world, user_where_clauses_with_world) =
|
||||
@ -102,12 +101,13 @@ pub fn derive_query_filter_impl(input: TokenStream) -> TokenStream {
|
||||
|
||||
#[allow(unused_variables)]
|
||||
#[inline(always)]
|
||||
unsafe fn filter_fetch<'__w, '__s>(
|
||||
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w, '__s>,
|
||||
unsafe fn filter_fetch<'__w>(
|
||||
_state: &Self::State,
|
||||
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
|
||||
_entity: #path::entity::Entity,
|
||||
_table_row: #path::storage::TableRow,
|
||||
) -> bool {
|
||||
true #(&& <#field_types>::filter_fetch(&mut _fetch.#named_field_idents, _entity, _table_row))*
|
||||
true #(&& <#field_types>::filter_fetch(&_state.#named_field_idents, &mut _fetch.#named_field_idents, _entity, _table_row))*
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -10,13 +10,13 @@ pub(crate) fn item_struct(
|
||||
visibility: &Visibility,
|
||||
item_struct_name: &Ident,
|
||||
field_types: &Vec<proc_macro2::TokenStream>,
|
||||
user_impl_generics_with_world: &ImplGenerics,
|
||||
user_impl_generics_with_world_and_state: &ImplGenerics,
|
||||
field_attrs: &Vec<Vec<Attribute>>,
|
||||
field_visibilities: &Vec<Visibility>,
|
||||
field_idents: &Vec<proc_macro2::TokenStream>,
|
||||
user_ty_generics: &TypeGenerics,
|
||||
user_ty_generics_with_world: &TypeGenerics,
|
||||
user_where_clauses_with_world: Option<&WhereClause>,
|
||||
user_ty_generics_with_world_and_state: &TypeGenerics,
|
||||
user_where_clauses_with_world_and_state: Option<&WhereClause>,
|
||||
) -> proc_macro2::TokenStream {
|
||||
let item_attrs = quote! {
|
||||
#[doc = concat!(
|
||||
@ -33,20 +33,20 @@ pub(crate) fn item_struct(
|
||||
Fields::Named(_) => quote! {
|
||||
#derive_macro_call
|
||||
#item_attrs
|
||||
#visibility struct #item_struct_name #user_impl_generics_with_world #user_where_clauses_with_world {
|
||||
#visibility struct #item_struct_name #user_impl_generics_with_world_and_state #user_where_clauses_with_world_and_state {
|
||||
#(#(#field_attrs)* #field_visibilities #field_idents: <#field_types as #path::query::QueryData>::Item<'__w, '__s>,)*
|
||||
}
|
||||
},
|
||||
Fields::Unnamed(_) => quote! {
|
||||
#derive_macro_call
|
||||
#item_attrs
|
||||
#visibility struct #item_struct_name #user_impl_generics_with_world #user_where_clauses_with_world(
|
||||
#visibility struct #item_struct_name #user_impl_generics_with_world_and_state #user_where_clauses_with_world_and_state(
|
||||
#( #field_visibilities <#field_types as #path::query::QueryData>::Item<'__w, '__s>, )*
|
||||
);
|
||||
},
|
||||
Fields::Unit => quote! {
|
||||
#item_attrs
|
||||
#visibility type #item_struct_name #user_ty_generics_with_world = #struct_name #user_ty_generics;
|
||||
#visibility type #item_struct_name #user_ty_generics_with_world_and_state = #struct_name #user_ty_generics;
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -78,8 +78,8 @@ pub(crate) fn world_query_impl(
|
||||
)]
|
||||
#[automatically_derived]
|
||||
#visibility struct #fetch_struct_name #user_impl_generics_with_world #user_where_clauses_with_world {
|
||||
#(#named_field_idents: <#field_types as #path::query::WorldQuery>::Fetch<'__w, '__s>,)*
|
||||
#marker_name: (&'__w(), &'__s()),
|
||||
#(#named_field_idents: <#field_types as #path::query::WorldQuery>::Fetch<'__w>,)*
|
||||
#marker_name: &'__w(),
|
||||
}
|
||||
|
||||
impl #user_impl_generics_with_world Clone for #fetch_struct_name #user_ty_generics_with_world
|
||||
@ -87,7 +87,7 @@ pub(crate) fn world_query_impl(
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
#(#named_field_idents: self.#named_field_idents.clone(),)*
|
||||
#marker_name: (&(), &()),
|
||||
#marker_name: &(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -96,17 +96,17 @@ pub(crate) fn world_query_impl(
|
||||
unsafe impl #user_impl_generics #path::query::WorldQuery
|
||||
for #struct_name #user_ty_generics #user_where_clauses {
|
||||
|
||||
type Fetch<'__w, '__s> = #fetch_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_fetch<'__wlong: '__wshort, '__wshort, '__s>(
|
||||
fetch: <#struct_name #user_ty_generics as #path::query::WorldQuery>::Fetch<'__wlong, '__s>
|
||||
) -> <#struct_name #user_ty_generics as #path::query::WorldQuery>::Fetch<'__wshort, '__s> {
|
||||
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> {
|
||||
#fetch_struct_name {
|
||||
#(
|
||||
#named_field_idents: <#field_types>::shrink_fetch(fetch.#named_field_idents),
|
||||
)*
|
||||
#marker_name: (&(), &()),
|
||||
#marker_name: &(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,7 +115,7 @@ pub(crate) fn world_query_impl(
|
||||
state: &'__s Self::State,
|
||||
_last_run: #path::component::Tick,
|
||||
_this_run: #path::component::Tick,
|
||||
) -> <Self as #path::query::WorldQuery>::Fetch<'__w, '__s> {
|
||||
) -> <Self as #path::query::WorldQuery>::Fetch<'__w> {
|
||||
#fetch_struct_name {
|
||||
#(#named_field_idents:
|
||||
<#field_types>::init_fetch(
|
||||
@ -125,7 +125,7 @@ pub(crate) fn world_query_impl(
|
||||
_this_run,
|
||||
),
|
||||
)*
|
||||
#marker_name: (&(), &()),
|
||||
#marker_name: &(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,7 +134,7 @@ pub(crate) fn world_query_impl(
|
||||
/// SAFETY: we call `set_archetype` for each member that implements `Fetch`
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'__w, '__s>(
|
||||
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w, '__s>,
|
||||
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
|
||||
_state: &'__s Self::State,
|
||||
_archetype: &'__w #path::archetype::Archetype,
|
||||
_table: &'__w #path::storage::Table
|
||||
@ -145,7 +145,7 @@ pub(crate) fn world_query_impl(
|
||||
/// SAFETY: we call `set_table` for each member that implements `Fetch`
|
||||
#[inline]
|
||||
unsafe fn set_table<'__w, '__s>(
|
||||
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w, '__s>,
|
||||
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
|
||||
_state: &'__s Self::State,
|
||||
_table: &'__w #path::storage::Table
|
||||
) {
|
||||
|
@ -326,7 +326,8 @@ pub unsafe trait QueryData: WorldQuery {
|
||||
/// `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, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
state: &'s Self::State,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
table_row: TableRow,
|
||||
) -> Self::Item<'w, 's>;
|
||||
@ -359,27 +360,24 @@ pub trait ReleaseStateQueryData: QueryData {
|
||||
/// `update_component_access` does nothing.
|
||||
/// This is sound because `fetch` does not access components.
|
||||
unsafe impl WorldQuery for Entity {
|
||||
type Fetch<'w, 's> = ();
|
||||
type Fetch<'w> = ();
|
||||
type State = ();
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
_: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
}
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
|
||||
|
||||
unsafe fn init_fetch<'w, 's>(
|
||||
_world: UnsafeWorldCell<'w>,
|
||||
_state: &'s Self::State,
|
||||
_last_run: Tick,
|
||||
_this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
}
|
||||
|
||||
const IS_DENSE: bool = true;
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s Self::State,
|
||||
_archetype: &'w Archetype,
|
||||
_table: &Table,
|
||||
@ -388,7 +386,7 @@ unsafe impl WorldQuery for Entity {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s Self::State,
|
||||
_table: &'w Table,
|
||||
) {
|
||||
@ -425,7 +423,8 @@ unsafe impl QueryData for Entity {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s Self::State,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
@ -446,12 +445,10 @@ impl ReleaseStateQueryData for Entity {
|
||||
/// `update_component_access` does nothing.
|
||||
/// This is sound because `fetch` does not access components.
|
||||
unsafe impl WorldQuery for EntityLocation {
|
||||
type Fetch<'w, 's> = &'w Entities;
|
||||
type Fetch<'w> = &'w Entities;
|
||||
type State = ();
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -460,7 +457,7 @@ unsafe impl WorldQuery for EntityLocation {
|
||||
_state: &'s Self::State,
|
||||
_last_run: Tick,
|
||||
_this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
world.entities()
|
||||
}
|
||||
|
||||
@ -470,7 +467,7 @@ unsafe impl WorldQuery for EntityLocation {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s Self::State,
|
||||
_archetype: &'w Archetype,
|
||||
_table: &Table,
|
||||
@ -479,7 +476,7 @@ unsafe impl WorldQuery for EntityLocation {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s Self::State,
|
||||
_table: &'w Table,
|
||||
) {
|
||||
@ -515,7 +512,8 @@ unsafe impl QueryData for EntityLocation {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s Self::State,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
@ -606,12 +604,10 @@ pub struct SpawnDetailsFetch<'w> {
|
||||
// SAFETY:
|
||||
// No components are accessed.
|
||||
unsafe impl WorldQuery for SpawnDetails {
|
||||
type Fetch<'w, 's> = SpawnDetailsFetch<'w>;
|
||||
type Fetch<'w> = SpawnDetailsFetch<'w>;
|
||||
type State = ();
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -620,7 +616,7 @@ unsafe impl WorldQuery for SpawnDetails {
|
||||
_state: &'s Self::State,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
SpawnDetailsFetch {
|
||||
entities: world.entities(),
|
||||
last_run,
|
||||
@ -632,7 +628,7 @@ unsafe impl WorldQuery for SpawnDetails {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s Self::State,
|
||||
_archetype: &'w Archetype,
|
||||
_table: &'w Table,
|
||||
@ -641,7 +637,7 @@ unsafe impl WorldQuery for SpawnDetails {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s Self::State,
|
||||
_table: &'w Table,
|
||||
) {
|
||||
@ -679,7 +675,8 @@ unsafe impl QueryData for SpawnDetails {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s Self::State,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
@ -722,12 +719,10 @@ pub struct EntityFetch<'w> {
|
||||
/// This is sound because `update_component_access` sets read access for all components and panic when appropriate.
|
||||
/// Filters are unchanged.
|
||||
unsafe impl<'a> WorldQuery for EntityRef<'a> {
|
||||
type Fetch<'w, 's> = EntityFetch<'w>;
|
||||
type Fetch<'w> = EntityFetch<'w>;
|
||||
type State = ();
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -736,7 +731,7 @@ unsafe impl<'a> WorldQuery for EntityRef<'a> {
|
||||
_state: &'s Self::State,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
EntityFetch {
|
||||
world,
|
||||
last_run,
|
||||
@ -748,7 +743,7 @@ unsafe impl<'a> WorldQuery for EntityRef<'a> {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s Self::State,
|
||||
_archetype: &'w Archetype,
|
||||
_table: &Table,
|
||||
@ -757,7 +752,7 @@ unsafe impl<'a> WorldQuery for EntityRef<'a> {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s Self::State,
|
||||
_table: &'w Table,
|
||||
) {
|
||||
@ -799,7 +794,8 @@ unsafe impl<'a> QueryData for EntityRef<'a> {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s Self::State,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
@ -826,12 +822,10 @@ impl ReleaseStateQueryData for EntityRef<'_> {
|
||||
|
||||
/// SAFETY: The accesses of `Self::ReadOnly` are a subset of the accesses of `Self`
|
||||
unsafe impl<'a> WorldQuery for EntityMut<'a> {
|
||||
type Fetch<'w, 's> = EntityFetch<'w>;
|
||||
type Fetch<'w> = EntityFetch<'w>;
|
||||
type State = ();
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -840,7 +834,7 @@ unsafe impl<'a> WorldQuery for EntityMut<'a> {
|
||||
_state: &'s Self::State,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
EntityFetch {
|
||||
world,
|
||||
last_run,
|
||||
@ -852,7 +846,7 @@ unsafe impl<'a> WorldQuery for EntityMut<'a> {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s Self::State,
|
||||
_archetype: &'w Archetype,
|
||||
_table: &Table,
|
||||
@ -861,7 +855,7 @@ unsafe impl<'a> WorldQuery for EntityMut<'a> {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s Self::State,
|
||||
_table: &'w Table,
|
||||
) {
|
||||
@ -903,7 +897,8 @@ unsafe impl<'a> QueryData for EntityMut<'a> {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s Self::State,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
@ -927,12 +922,10 @@ impl ReleaseStateQueryData for EntityMut<'_> {
|
||||
|
||||
/// SAFETY: The accesses of `Self::ReadOnly` are a subset of the accesses of `Self`
|
||||
unsafe impl<'a> WorldQuery for FilteredEntityRef<'a> {
|
||||
type Fetch<'w, 's> = (EntityFetch<'w>, Access<ComponentId>);
|
||||
type Fetch<'w> = (EntityFetch<'w>, Access<ComponentId>);
|
||||
type State = Access<ComponentId>;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -943,7 +936,7 @@ unsafe impl<'a> WorldQuery for FilteredEntityRef<'a> {
|
||||
_state: &'s Self::State,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
let mut access = Access::default();
|
||||
access.read_all_components();
|
||||
(
|
||||
@ -958,7 +951,7 @@ unsafe impl<'a> WorldQuery for FilteredEntityRef<'a> {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
state: &'s Self::State,
|
||||
_: &'w Archetype,
|
||||
_table: &Table,
|
||||
@ -967,11 +960,7 @@ unsafe impl<'a> WorldQuery for FilteredEntityRef<'a> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
state: &'s Self::State,
|
||||
_: &'w Table,
|
||||
) {
|
||||
unsafe fn set_table<'w, 's>(fetch: &mut Self::Fetch<'w>, state: &'s Self::State, _: &'w Table) {
|
||||
fetch.1.clone_from(state);
|
||||
}
|
||||
|
||||
@ -1035,7 +1024,8 @@ unsafe impl<'a> QueryData for FilteredEntityRef<'a> {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
(fetch, access): &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s Self::State,
|
||||
(fetch, access): &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
@ -1056,12 +1046,10 @@ unsafe impl ReadOnlyQueryData for FilteredEntityRef<'_> {}
|
||||
|
||||
/// SAFETY: The accesses of `Self::ReadOnly` are a subset of the accesses of `Self`
|
||||
unsafe impl<'a> WorldQuery for FilteredEntityMut<'a> {
|
||||
type Fetch<'w, 's> = (EntityFetch<'w>, Access<ComponentId>);
|
||||
type Fetch<'w> = (EntityFetch<'w>, Access<ComponentId>);
|
||||
type State = Access<ComponentId>;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -1072,7 +1060,7 @@ unsafe impl<'a> WorldQuery for FilteredEntityMut<'a> {
|
||||
_state: &'s Self::State,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
let mut access = Access::default();
|
||||
access.write_all_components();
|
||||
(
|
||||
@ -1087,7 +1075,7 @@ unsafe impl<'a> WorldQuery for FilteredEntityMut<'a> {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
state: &'s Self::State,
|
||||
_: &'w Archetype,
|
||||
_table: &Table,
|
||||
@ -1096,11 +1084,7 @@ unsafe impl<'a> WorldQuery for FilteredEntityMut<'a> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
state: &'s Self::State,
|
||||
_: &'w Table,
|
||||
) {
|
||||
unsafe fn set_table<'w, 's>(fetch: &mut Self::Fetch<'w>, state: &'s Self::State, _: &'w Table) {
|
||||
fetch.1.clone_from(state);
|
||||
}
|
||||
|
||||
@ -1162,7 +1146,8 @@ unsafe impl<'a> QueryData for FilteredEntityMut<'a> {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
(fetch, access): &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s Self::State,
|
||||
(fetch, access): &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
@ -1185,12 +1170,10 @@ unsafe impl<'a, B> WorldQuery for EntityRefExcept<'a, B>
|
||||
where
|
||||
B: Bundle,
|
||||
{
|
||||
type Fetch<'w, 's> = EntityFetch<'w>;
|
||||
type Fetch<'w> = EntityFetch<'w>;
|
||||
type State = SmallVec<[ComponentId; 4]>;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -1199,7 +1182,7 @@ where
|
||||
_: &'s Self::State,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
EntityFetch {
|
||||
world,
|
||||
last_run,
|
||||
@ -1210,14 +1193,14 @@ where
|
||||
const IS_DENSE: bool = true;
|
||||
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
_: &mut Self::Fetch<'w, 's>,
|
||||
_: &mut Self::Fetch<'w>,
|
||||
_: &'s Self::State,
|
||||
_: &'w Archetype,
|
||||
_: &'w Table,
|
||||
) {
|
||||
}
|
||||
|
||||
unsafe fn set_table<'w, 's>(_: &mut Self::Fetch<'w, 's>, _: &'s Self::State, _: &'w Table) {}
|
||||
unsafe fn set_table<'w, 's>(_: &mut Self::Fetch<'w>, _: &'s Self::State, _: &'w Table) {}
|
||||
|
||||
fn update_component_access(
|
||||
state: &Self::State,
|
||||
@ -1273,7 +1256,8 @@ where
|
||||
}
|
||||
|
||||
unsafe fn fetch<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s Self::State,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
_: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
@ -1296,12 +1280,10 @@ unsafe impl<'a, B> WorldQuery for EntityMutExcept<'a, B>
|
||||
where
|
||||
B: Bundle,
|
||||
{
|
||||
type Fetch<'w, 's> = EntityFetch<'w>;
|
||||
type Fetch<'w> = EntityFetch<'w>;
|
||||
type State = SmallVec<[ComponentId; 4]>;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -1310,7 +1292,7 @@ where
|
||||
_: &'s Self::State,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
EntityFetch {
|
||||
world,
|
||||
last_run,
|
||||
@ -1321,14 +1303,14 @@ where
|
||||
const IS_DENSE: bool = true;
|
||||
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
_: &mut Self::Fetch<'w, 's>,
|
||||
_: &mut Self::Fetch<'w>,
|
||||
_: &'s Self::State,
|
||||
_: &'w Archetype,
|
||||
_: &'w Table,
|
||||
) {
|
||||
}
|
||||
|
||||
unsafe fn set_table<'w, 's>(_: &mut Self::Fetch<'w, 's>, _: &'s Self::State, _: &'w Table) {}
|
||||
unsafe fn set_table<'w, 's>(_: &mut Self::Fetch<'w>, _: &'s Self::State, _: &'w Table) {}
|
||||
|
||||
fn update_component_access(
|
||||
state: &Self::State,
|
||||
@ -1385,7 +1367,8 @@ where
|
||||
}
|
||||
|
||||
unsafe fn fetch<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s Self::State,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
_: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
@ -1401,12 +1384,10 @@ where
|
||||
/// `update_component_access` does nothing.
|
||||
/// This is sound because `fetch` does not access components.
|
||||
unsafe impl WorldQuery for &Archetype {
|
||||
type Fetch<'w, 's> = (&'w Entities, &'w Archetypes);
|
||||
type Fetch<'w> = (&'w Entities, &'w Archetypes);
|
||||
type State = ();
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -1415,7 +1396,7 @@ unsafe impl WorldQuery for &Archetype {
|
||||
_state: &'s Self::State,
|
||||
_last_run: Tick,
|
||||
_this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
(world.entities(), world.archetypes())
|
||||
}
|
||||
|
||||
@ -1425,7 +1406,7 @@ unsafe impl WorldQuery for &Archetype {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s Self::State,
|
||||
_archetype: &'w Archetype,
|
||||
_table: &Table,
|
||||
@ -1434,7 +1415,7 @@ unsafe impl WorldQuery for &Archetype {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s Self::State,
|
||||
_table: &'w Table,
|
||||
) {
|
||||
@ -1470,7 +1451,8 @@ unsafe impl QueryData for &Archetype {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s Self::State,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
@ -1515,12 +1497,10 @@ impl<T: Component> Copy for ReadFetch<'_, 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 &T {
|
||||
type Fetch<'w, 's> = ReadFetch<'w, T>;
|
||||
type Fetch<'w> = ReadFetch<'w, T>;
|
||||
type State = ComponentId;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -1625,7 +1605,8 @@ unsafe impl<T: Component> QueryData for &T {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s Self::State,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
@ -1692,12 +1673,10 @@ impl<T: Component> Copy for RefFetch<'_, 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<'__w, T: Component> WorldQuery for Ref<'__w, T> {
|
||||
type Fetch<'w, 's> = RefFetch<'w, T>;
|
||||
type Fetch<'w> = RefFetch<'w, T>;
|
||||
type State = ComponentId;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -1811,7 +1790,8 @@ unsafe impl<'__w, T: Component> QueryData for Ref<'__w, T> {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s Self::State,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
@ -1901,12 +1881,10 @@ impl<T: Component> Copy for WriteFetch<'_, 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<'__w, T: Component> WorldQuery for &'__w mut T {
|
||||
type Fetch<'w, 's> = WriteFetch<'w, T>;
|
||||
type Fetch<'w> = WriteFetch<'w, T>;
|
||||
type State = ComponentId;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -2020,7 +1998,8 @@ unsafe impl<'__w, T: Component<Mutability = Mutable>> QueryData for &'__w mut T
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s Self::State,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
@ -2085,12 +2064,10 @@ impl<T: Component<Mutability = Mutable>> ReleaseStateQueryData for &mut 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<'__w, T: Component> WorldQuery for Mut<'__w, T> {
|
||||
type Fetch<'w, 's> = WriteFetch<'w, T>;
|
||||
type Fetch<'w> = WriteFetch<'w, T>;
|
||||
type State = ComponentId;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -2175,13 +2152,14 @@ unsafe impl<'__w, T: Component<Mutability = Mutable>> QueryData for Mut<'__w, T>
|
||||
#[inline(always)]
|
||||
// Forwarded to `&mut T`
|
||||
unsafe fn fetch<'w, 's>(
|
||||
state: &'s Self::State,
|
||||
// Rust complains about lifetime bounds not matching the trait if I directly use `WriteFetch<'w, T>` right here.
|
||||
// But it complains nowhere else in the entire trait implementation.
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
<&mut T as QueryData>::fetch(fetch, entity, table_row)
|
||||
<&mut T as QueryData>::fetch(state, fetch, entity, table_row)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2192,12 +2170,12 @@ impl<T: Component<Mutability = Mutable>> ReleaseStateQueryData for Mut<'_, T> {
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct OptionFetch<'w, 's, T: WorldQuery> {
|
||||
fetch: T::Fetch<'w, 's>,
|
||||
pub struct OptionFetch<'w, T: WorldQuery> {
|
||||
fetch: T::Fetch<'w>,
|
||||
matches: bool,
|
||||
}
|
||||
|
||||
impl<T: WorldQuery> Clone for OptionFetch<'_, '_, T> {
|
||||
impl<T: WorldQuery> Clone for OptionFetch<'_, T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
fetch: self.fetch.clone(),
|
||||
@ -2211,12 +2189,10 @@ impl<T: WorldQuery> Clone for OptionFetch<'_, '_, T> {
|
||||
/// This is sound because `update_component_access` adds the same accesses as `T`.
|
||||
/// Filters are unchanged.
|
||||
unsafe impl<T: WorldQuery> WorldQuery for Option<T> {
|
||||
type Fetch<'w, 's> = OptionFetch<'w, 's, T>;
|
||||
type Fetch<'w> = OptionFetch<'w, T>;
|
||||
type State = T::State;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
OptionFetch {
|
||||
fetch: T::shrink_fetch(fetch.fetch),
|
||||
matches: fetch.matches,
|
||||
@ -2229,7 +2205,7 @@ unsafe impl<T: WorldQuery> WorldQuery for Option<T> {
|
||||
state: &'s T::State,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> OptionFetch<'w, 's, T> {
|
||||
) -> OptionFetch<'w, T> {
|
||||
OptionFetch {
|
||||
// SAFETY: The invariants are upheld by the caller.
|
||||
fetch: unsafe { T::init_fetch(world, state, last_run, this_run) },
|
||||
@ -2241,7 +2217,7 @@ unsafe impl<T: WorldQuery> WorldQuery for Option<T> {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
fetch: &mut OptionFetch<'w, 's, T>,
|
||||
fetch: &mut OptionFetch<'w, T>,
|
||||
state: &'s T::State,
|
||||
archetype: &'w Archetype,
|
||||
table: &'w Table,
|
||||
@ -2257,7 +2233,7 @@ unsafe impl<T: WorldQuery> WorldQuery for Option<T> {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(
|
||||
fetch: &mut OptionFetch<'w, 's, T>,
|
||||
fetch: &mut OptionFetch<'w, T>,
|
||||
state: &'s T::State,
|
||||
table: &'w Table,
|
||||
) {
|
||||
@ -2315,14 +2291,15 @@ unsafe impl<T: QueryData> QueryData for Option<T> {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
state: &'s Self::State,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
fetch
|
||||
.matches
|
||||
// SAFETY: The invariants are upheld by the caller.
|
||||
.then(|| unsafe { T::fetch(&mut fetch.fetch, entity, table_row) })
|
||||
.then(|| unsafe { T::fetch(state, &mut fetch.fetch, entity, table_row) })
|
||||
}
|
||||
}
|
||||
|
||||
@ -2410,12 +2387,10 @@ impl<T> core::fmt::Debug for Has<T> {
|
||||
/// `update_component_access` does nothing.
|
||||
/// This is sound because `fetch` does not access components.
|
||||
unsafe impl<T: Component> WorldQuery for Has<T> {
|
||||
type Fetch<'w, 's> = bool;
|
||||
type Fetch<'w> = bool;
|
||||
type State = ComponentId;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -2425,7 +2400,7 @@ unsafe impl<T: Component> WorldQuery for Has<T> {
|
||||
_state: &'s Self::State,
|
||||
_last_run: Tick,
|
||||
_this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
false
|
||||
}
|
||||
|
||||
@ -2438,7 +2413,7 @@ unsafe impl<T: Component> WorldQuery for Has<T> {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
state: &'s Self::State,
|
||||
archetype: &'w Archetype,
|
||||
_table: &Table,
|
||||
@ -2448,7 +2423,7 @@ unsafe impl<T: Component> WorldQuery for Has<T> {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
state: &'s Self::State,
|
||||
table: &'w Table,
|
||||
) {
|
||||
@ -2493,7 +2468,8 @@ unsafe impl<T: Component> QueryData for Has<T> {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s Self::State,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
_entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
@ -2518,7 +2494,7 @@ impl<T: Component> ReleaseStateQueryData for Has<T> {
|
||||
pub struct AnyOf<T>(PhantomData<T>);
|
||||
|
||||
macro_rules! impl_tuple_query_data {
|
||||
($(#[$meta:meta])* $(($name: ident, $item: ident)),*) => {
|
||||
($(#[$meta:meta])* $(($name: ident, $item: ident, $state: ident)),*) => {
|
||||
#[expect(
|
||||
clippy::allow_attributes,
|
||||
reason = "This is a tuple-related macro; as such the lints below may not always apply."
|
||||
@ -2561,13 +2537,15 @@ macro_rules! impl_tuple_query_data {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
state: &'s Self::State,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
table_row: TableRow
|
||||
) -> Self::Item<'w, 's> {
|
||||
let ($($state,)*) = state;
|
||||
let ($($name,)*) = fetch;
|
||||
// SAFETY: The invariants are upheld by the caller.
|
||||
($(unsafe { $name::fetch($name, entity, table_row) },)*)
|
||||
($(unsafe { $name::fetch($state, $name, entity, table_row) },)*)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2615,10 +2593,10 @@ macro_rules! impl_anytuple_fetch {
|
||||
/// `update_component_access` replaces 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<$($name: WorldQuery),*> WorldQuery for AnyOf<($($name,)*)> {
|
||||
type Fetch<'w, 's> = ($(($name::Fetch<'w, 's>, bool),)*);
|
||||
type Fetch<'w> = ($(($name::Fetch<'w>, bool),)*);
|
||||
type State = ($($name::State,)*);
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(fetch: Self::Fetch<'wlong, 's>) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
let ($($name,)*) = fetch;
|
||||
($(
|
||||
($name::shrink_fetch($name.0), $name.1),
|
||||
@ -2626,7 +2604,7 @@ macro_rules! impl_anytuple_fetch {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn init_fetch<'w, 's>(_world: UnsafeWorldCell<'w>, state: &'s Self::State, _last_run: Tick, _this_run: Tick) -> Self::Fetch<'w, 's> {
|
||||
unsafe fn init_fetch<'w, 's>(_world: UnsafeWorldCell<'w>, state: &'s Self::State, _last_run: Tick, _this_run: Tick) -> Self::Fetch<'w> {
|
||||
let ($($name,)*) = state;
|
||||
// SAFETY: The invariants are upheld by the caller.
|
||||
($(( unsafe { $name::init_fetch(_world, $name, _last_run, _this_run) }, false),)*)
|
||||
@ -2636,7 +2614,7 @@ macro_rules! impl_anytuple_fetch {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s Self::State,
|
||||
_archetype: &'w Archetype,
|
||||
_table: &'w Table
|
||||
@ -2653,7 +2631,7 @@ macro_rules! impl_anytuple_fetch {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(_fetch: &mut Self::Fetch<'w, 's>, _state: &'s Self::State, _table: &'w Table) {
|
||||
unsafe fn set_table<'w, 's>(_fetch: &mut Self::Fetch<'w>, _state: &'s Self::State, _table: &'w Table) {
|
||||
let ($($name,)*) = _fetch;
|
||||
let ($($state,)*) = _state;
|
||||
$(
|
||||
@ -2736,14 +2714,16 @@ macro_rules! impl_anytuple_fetch {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s Self::State,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_entity: Entity,
|
||||
_table_row: TableRow
|
||||
) -> Self::Item<'w, 's> {
|
||||
let ($($name,)*) = _fetch;
|
||||
let ($($state,)*) = _state;
|
||||
($(
|
||||
// SAFETY: The invariants are required to be upheld by the caller.
|
||||
$name.1.then(|| unsafe { $name::fetch(&mut $name.0, _entity, _table_row) }),
|
||||
$name.1.then(|| unsafe { $name::fetch($state, &mut $name.0, _entity, _table_row) }),
|
||||
)*)
|
||||
}
|
||||
}
|
||||
@ -2774,7 +2754,8 @@ all_tuples!(
|
||||
0,
|
||||
15,
|
||||
F,
|
||||
i
|
||||
i,
|
||||
s
|
||||
);
|
||||
all_tuples!(
|
||||
#[doc(fake_variadic)]
|
||||
@ -2795,12 +2776,10 @@ pub(crate) struct NopWorldQuery<D: QueryData>(PhantomData<D>);
|
||||
/// `update_component_access` does nothing.
|
||||
/// This is sound because `fetch` does not access components.
|
||||
unsafe impl<D: QueryData> WorldQuery for NopWorldQuery<D> {
|
||||
type Fetch<'w, 's> = ();
|
||||
type Fetch<'w> = ();
|
||||
type State = D::State;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
_fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(_fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
@ -2857,7 +2836,8 @@ unsafe impl<D: QueryData> QueryData for NopWorldQuery<D> {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s Self::State,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
@ -2875,13 +2855,11 @@ impl<D: QueryData> ReleaseStateQueryData for NopWorldQuery<D> {
|
||||
/// `update_component_access` does nothing.
|
||||
/// This is sound because `fetch` does not access components.
|
||||
unsafe impl<T: ?Sized> WorldQuery for PhantomData<T> {
|
||||
type Fetch<'w, 's> = ();
|
||||
type Fetch<'w> = ();
|
||||
|
||||
type State = ();
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
_fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(_fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
}
|
||||
|
||||
unsafe fn init_fetch<'w, 's>(
|
||||
@ -2889,7 +2867,7 @@ unsafe impl<T: ?Sized> WorldQuery for PhantomData<T> {
|
||||
_state: &'s Self::State,
|
||||
_last_run: Tick,
|
||||
_this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
}
|
||||
|
||||
// `PhantomData` does not match any components, so all components it matches
|
||||
@ -2897,7 +2875,7 @@ unsafe impl<T: ?Sized> WorldQuery for PhantomData<T> {
|
||||
const IS_DENSE: bool = true;
|
||||
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s Self::State,
|
||||
_archetype: &'w Archetype,
|
||||
_table: &'w Table,
|
||||
@ -2905,7 +2883,7 @@ unsafe impl<T: ?Sized> WorldQuery for PhantomData<T> {
|
||||
}
|
||||
|
||||
unsafe fn set_table<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s Self::State,
|
||||
_table: &'w Table,
|
||||
) {
|
||||
@ -2939,7 +2917,8 @@ unsafe impl<T: ?Sized> QueryData for PhantomData<T> {
|
||||
}
|
||||
|
||||
unsafe fn fetch<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s Self::State,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
@ -3077,12 +3056,12 @@ mod tests {
|
||||
/// `update_component_access` and `update_archetype_component_access` do nothing.
|
||||
/// This is sound because `fetch` does not access components.
|
||||
unsafe impl WorldQuery for NonReleaseQueryData {
|
||||
type Fetch<'w, 's> = ();
|
||||
type Fetch<'w> = ();
|
||||
type State = ();
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
_: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(
|
||||
_: Self::Fetch<'wlong>,
|
||||
) -> Self::Fetch<'wshort> {
|
||||
}
|
||||
|
||||
unsafe fn init_fetch<'w, 's>(
|
||||
@ -3090,14 +3069,14 @@ mod tests {
|
||||
_state: &'s Self::State,
|
||||
_last_run: Tick,
|
||||
_this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
}
|
||||
|
||||
const IS_DENSE: bool = true;
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s Self::State,
|
||||
_archetype: &'w Archetype,
|
||||
_table: &Table,
|
||||
@ -3106,7 +3085,7 @@ mod tests {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s Self::State,
|
||||
_table: &'w Table,
|
||||
) {
|
||||
@ -3146,7 +3125,8 @@ mod tests {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s Self::State,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
|
@ -104,7 +104,8 @@ pub unsafe trait QueryFilter: WorldQuery {
|
||||
/// 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.
|
||||
unsafe fn filter_fetch(
|
||||
fetch: &mut Self::Fetch<'_, '_>,
|
||||
state: &Self::State,
|
||||
fetch: &mut Self::Fetch<'_>,
|
||||
entity: Entity,
|
||||
table_row: TableRow,
|
||||
) -> bool;
|
||||
@ -145,13 +146,10 @@ pub struct With<T>(PhantomData<T>);
|
||||
/// `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 Fetch<'w, 's> = ();
|
||||
type Fetch<'w> = ();
|
||||
type State = ComponentId;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
_: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
}
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
|
||||
|
||||
#[inline]
|
||||
unsafe fn init_fetch(
|
||||
@ -208,7 +206,8 @@ unsafe impl<T: Component> QueryFilter for With<T> {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn filter_fetch(
|
||||
_fetch: &mut Self::Fetch<'_, '_>,
|
||||
_state: &Self::State,
|
||||
_fetch: &mut Self::Fetch<'_>,
|
||||
_entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> bool {
|
||||
@ -248,13 +247,10 @@ pub struct Without<T>(PhantomData<T>);
|
||||
/// `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 Fetch<'w, 's> = ();
|
||||
type Fetch<'w> = ();
|
||||
type State = ComponentId;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
_: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
}
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
|
||||
|
||||
#[inline]
|
||||
unsafe fn init_fetch(
|
||||
@ -311,7 +307,8 @@ unsafe impl<T: Component> QueryFilter for Without<T> {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn filter_fetch(
|
||||
_fetch: &mut Self::Fetch<'_, '_>,
|
||||
_state: &Self::State,
|
||||
_fetch: &mut Self::Fetch<'_>,
|
||||
_entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> bool {
|
||||
@ -352,12 +349,12 @@ unsafe impl<T: Component> QueryFilter for Without<T> {
|
||||
pub struct Or<T>(PhantomData<T>);
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct OrFetch<'w, 's, T: WorldQuery> {
|
||||
fetch: T::Fetch<'w, 's>,
|
||||
pub struct OrFetch<'w, T: WorldQuery> {
|
||||
fetch: T::Fetch<'w>,
|
||||
matches: bool,
|
||||
}
|
||||
|
||||
impl<T: WorldQuery> Clone for OrFetch<'_, '_, T> {
|
||||
impl<T: WorldQuery> Clone for OrFetch<'_, T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
fetch: self.fetch.clone(),
|
||||
@ -391,10 +388,10 @@ macro_rules! impl_or_query_filter {
|
||||
/// `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, 's> = ($(OrFetch<'w, 's, $filter>,)*);
|
||||
type Fetch<'w> = ($(OrFetch<'w, $filter>,)*);
|
||||
type State = ($($filter::State,)*);
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(fetch: Self::Fetch<'wlong, 's>) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
let ($($filter,)*) = fetch;
|
||||
($(
|
||||
OrFetch {
|
||||
@ -407,7 +404,7 @@ macro_rules! impl_or_query_filter {
|
||||
const IS_DENSE: bool = true $(&& $filter::IS_DENSE)*;
|
||||
|
||||
#[inline]
|
||||
unsafe fn init_fetch<'w, 's>(world: UnsafeWorldCell<'w>, state: &'s Self::State, last_run: Tick, this_run: Tick) -> Self::Fetch<'w, 's> {
|
||||
unsafe fn init_fetch<'w, 's>(world: UnsafeWorldCell<'w>, state: &'s Self::State, last_run: Tick, this_run: Tick) -> Self::Fetch<'w> {
|
||||
let ($($filter,)*) = state;
|
||||
($(OrFetch {
|
||||
// SAFETY: The invariants are upheld by the caller.
|
||||
@ -417,7 +414,7 @@ macro_rules! impl_or_query_filter {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(fetch: &mut Self::Fetch<'w, 's>, state: &'s Self::State, table: &'w Table) {
|
||||
unsafe fn set_table<'w, 's>(fetch: &mut Self::Fetch<'w>, state: &'s Self::State, table: &'w Table) {
|
||||
let ($($filter,)*) = fetch;
|
||||
let ($($state,)*) = state;
|
||||
$(
|
||||
@ -431,7 +428,7 @@ macro_rules! impl_or_query_filter {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
state: &'s Self::State,
|
||||
archetype: &'w Archetype,
|
||||
table: &'w Table
|
||||
@ -502,20 +499,22 @@ macro_rules! impl_or_query_filter {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn filter_fetch(
|
||||
fetch: &mut Self::Fetch<'_, '_>,
|
||||
state: &Self::State,
|
||||
fetch: &mut Self::Fetch<'_>,
|
||||
entity: Entity,
|
||||
table_row: TableRow
|
||||
) -> bool {
|
||||
let ($($state,)*) = state;
|
||||
let ($($filter,)*) = fetch;
|
||||
// SAFETY: The invariants are upheld by the caller.
|
||||
false $(|| ($filter.matches && unsafe { $filter::filter_fetch(&mut $filter.fetch, entity, table_row) }))*
|
||||
false $(|| ($filter.matches && unsafe { $filter::filter_fetch($state, &mut $filter.fetch, entity, table_row) }))*
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_tuple_query_filter {
|
||||
($(#[$meta:meta])* $($name: ident),*) => {
|
||||
($(#[$meta:meta])* $(($name: ident, $state: ident)),*) => {
|
||||
#[expect(
|
||||
clippy::allow_attributes,
|
||||
reason = "This is a tuple-related macro; as such the lints below may not always apply."
|
||||
@ -535,13 +534,15 @@ macro_rules! impl_tuple_query_filter {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn filter_fetch(
|
||||
fetch: &mut Self::Fetch<'_, '_>,
|
||||
state: &Self::State,
|
||||
fetch: &mut Self::Fetch<'_>,
|
||||
entity: Entity,
|
||||
table_row: TableRow
|
||||
) -> bool {
|
||||
let ($($state,)*) = state;
|
||||
let ($($name,)*) = fetch;
|
||||
// SAFETY: The invariants are upheld by the caller.
|
||||
true $(&& unsafe { $name::filter_fetch($name, entity, table_row) })*
|
||||
true $(&& unsafe { $name::filter_fetch($state, $name, entity, table_row) })*
|
||||
}
|
||||
}
|
||||
|
||||
@ -553,7 +554,8 @@ all_tuples!(
|
||||
impl_tuple_query_filter,
|
||||
0,
|
||||
15,
|
||||
F
|
||||
F,
|
||||
S
|
||||
);
|
||||
all_tuples!(
|
||||
#[doc(fake_variadic)]
|
||||
@ -575,13 +577,10 @@ pub struct Allows<T>(PhantomData<T>);
|
||||
/// `update_component_access` adds an archetypal filter for `T`.
|
||||
/// This is sound because it doesn't affect the query
|
||||
unsafe impl<T: Component> WorldQuery for Allows<T> {
|
||||
type Fetch<'w, 's> = ();
|
||||
type Fetch<'w> = ();
|
||||
type State = ComponentId;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
_: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
}
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
|
||||
|
||||
#[inline]
|
||||
unsafe fn init_fetch(_: UnsafeWorldCell, _: &ComponentId, _: Tick, _: Tick) {}
|
||||
@ -619,7 +618,12 @@ unsafe impl<T: Component> QueryFilter for Allows<T> {
|
||||
const IS_ARCHETYPAL: bool = true;
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn filter_fetch(_: &mut Self::Fetch<'_, '_>, _: Entity, _: TableRow) -> bool {
|
||||
unsafe fn filter_fetch(
|
||||
_: &Self::State,
|
||||
_: &mut Self::Fetch<'_>,
|
||||
_: Entity,
|
||||
_: TableRow,
|
||||
) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
@ -720,12 +724,10 @@ impl<T: Component> Clone for AddedFetch<'_, 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 Added<T> {
|
||||
type Fetch<'w, 's> = AddedFetch<'w, T>;
|
||||
type Fetch<'w> = AddedFetch<'w, T>;
|
||||
type State = ComponentId;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -735,8 +737,8 @@ unsafe impl<T: Component> WorldQuery for Added<T> {
|
||||
&id: &'s ComponentId,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
Self::Fetch::<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
Self::Fetch::<'w> {
|
||||
ticks: StorageSwitch::new(
|
||||
|| None,
|
||||
|| {
|
||||
@ -761,7 +763,7 @@ unsafe impl<T: Component> WorldQuery for Added<T> {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
component_id: &'s ComponentId,
|
||||
_archetype: &'w Archetype,
|
||||
table: &'w Table,
|
||||
@ -776,7 +778,7 @@ unsafe impl<T: Component> WorldQuery for Added<T> {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
&component_id: &'s ComponentId,
|
||||
table: &'w Table,
|
||||
) {
|
||||
@ -819,7 +821,8 @@ unsafe impl<T: Component> QueryFilter for Added<T> {
|
||||
const IS_ARCHETYPAL: bool = false;
|
||||
#[inline(always)]
|
||||
unsafe fn filter_fetch(
|
||||
fetch: &mut Self::Fetch<'_, '_>,
|
||||
_state: &Self::State,
|
||||
fetch: &mut Self::Fetch<'_>,
|
||||
entity: Entity,
|
||||
table_row: TableRow,
|
||||
) -> bool {
|
||||
@ -948,12 +951,10 @@ 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 Fetch<'w, 's> = ChangedFetch<'w, T>;
|
||||
type Fetch<'w> = ChangedFetch<'w, T>;
|
||||
type State = ComponentId;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -963,8 +964,8 @@ unsafe impl<T: Component> WorldQuery for Changed<T> {
|
||||
&id: &'s ComponentId,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
Self::Fetch::<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
Self::Fetch::<'w> {
|
||||
ticks: StorageSwitch::new(
|
||||
|| None,
|
||||
|| {
|
||||
@ -989,7 +990,7 @@ unsafe impl<T: Component> WorldQuery for Changed<T> {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
component_id: &'s ComponentId,
|
||||
_archetype: &'w Archetype,
|
||||
table: &'w Table,
|
||||
@ -1004,7 +1005,7 @@ unsafe impl<T: Component> WorldQuery for Changed<T> {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
&component_id: &'s ComponentId,
|
||||
table: &'w Table,
|
||||
) {
|
||||
@ -1048,7 +1049,8 @@ unsafe impl<T: Component> QueryFilter for Changed<T> {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn filter_fetch(
|
||||
fetch: &mut Self::Fetch<'_, '_>,
|
||||
_state: &Self::State,
|
||||
fetch: &mut Self::Fetch<'_>,
|
||||
entity: Entity,
|
||||
table_row: TableRow,
|
||||
) -> bool {
|
||||
@ -1147,12 +1149,10 @@ pub struct SpawnedFetch<'w> {
|
||||
|
||||
// SAFETY: WorldQuery impl accesses no components or component ticks
|
||||
unsafe impl WorldQuery for Spawned {
|
||||
type Fetch<'w, 's> = SpawnedFetch<'w>;
|
||||
type Fetch<'w> = SpawnedFetch<'w>;
|
||||
type State = ();
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -1162,7 +1162,7 @@ unsafe impl WorldQuery for Spawned {
|
||||
_state: &'s (),
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
SpawnedFetch {
|
||||
entities: world.entities(),
|
||||
last_run,
|
||||
@ -1174,7 +1174,7 @@ unsafe impl WorldQuery for Spawned {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s (),
|
||||
_archetype: &'w Archetype,
|
||||
_table: &'w Table,
|
||||
@ -1182,12 +1182,7 @@ unsafe impl WorldQuery for Spawned {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s (),
|
||||
_table: &'w Table,
|
||||
) {
|
||||
}
|
||||
unsafe fn set_table<'w, 's>(_fetch: &mut Self::Fetch<'w>, _state: &'s (), _table: &'w Table) {}
|
||||
|
||||
#[inline]
|
||||
fn update_component_access(_state: &(), _access: &mut FilteredAccess<ComponentId>) {}
|
||||
@ -1209,7 +1204,8 @@ unsafe impl QueryFilter for Spawned {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn filter_fetch(
|
||||
fetch: &mut Self::Fetch<'_, '_>,
|
||||
_state: &Self::State,
|
||||
fetch: &mut Self::Fetch<'_>,
|
||||
entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> bool {
|
||||
|
@ -225,14 +225,26 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
|
||||
|
||||
// SAFETY: set_table was called prior.
|
||||
// Caller assures `row` in range of the current archetype.
|
||||
let fetched = unsafe { !F::filter_fetch(&mut self.cursor.filter, *entity, row) };
|
||||
let fetched = unsafe {
|
||||
!F::filter_fetch(
|
||||
&self.query_state.filter_state,
|
||||
&mut self.cursor.filter,
|
||||
*entity,
|
||||
row,
|
||||
)
|
||||
};
|
||||
if fetched {
|
||||
continue;
|
||||
}
|
||||
|
||||
// SAFETY: set_table was called prior.
|
||||
// Caller assures `row` in range of the current archetype.
|
||||
let item = D::fetch(&mut self.cursor.fetch, *entity, row);
|
||||
let item = D::fetch(
|
||||
&self.query_state.fetch_state,
|
||||
&mut self.cursor.fetch,
|
||||
*entity,
|
||||
row,
|
||||
);
|
||||
|
||||
accum = func(accum, item);
|
||||
}
|
||||
@ -283,6 +295,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
|
||||
// Caller assures `index` in range of the current archetype.
|
||||
let fetched = unsafe {
|
||||
!F::filter_fetch(
|
||||
&self.query_state.filter_state,
|
||||
&mut self.cursor.filter,
|
||||
archetype_entity.id(),
|
||||
archetype_entity.table_row(),
|
||||
@ -296,6 +309,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
|
||||
// Caller assures `index` in range of the current archetype.
|
||||
let item = unsafe {
|
||||
D::fetch(
|
||||
&self.query_state.fetch_state,
|
||||
&mut self.cursor.fetch,
|
||||
archetype_entity.id(),
|
||||
archetype_entity.table_row(),
|
||||
@ -356,14 +370,26 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
|
||||
|
||||
// SAFETY: set_table was called prior.
|
||||
// Caller assures `row` in range of the current archetype.
|
||||
let filter_matched = unsafe { F::filter_fetch(&mut self.cursor.filter, entity, row) };
|
||||
let filter_matched = unsafe {
|
||||
F::filter_fetch(
|
||||
&self.query_state.filter_state,
|
||||
&mut self.cursor.filter,
|
||||
entity,
|
||||
row,
|
||||
)
|
||||
};
|
||||
if !filter_matched {
|
||||
continue;
|
||||
}
|
||||
|
||||
// SAFETY: set_table was called prior.
|
||||
// Caller assures `row` in range of the current archetype.
|
||||
let item = D::fetch(&mut self.cursor.fetch, entity, row);
|
||||
let item = D::fetch(
|
||||
&self.query_state.fetch_state,
|
||||
&mut self.cursor.fetch,
|
||||
entity,
|
||||
row,
|
||||
);
|
||||
|
||||
accum = func(accum, item);
|
||||
}
|
||||
@ -979,7 +1005,7 @@ where
|
||||
entities: &'w Entities,
|
||||
tables: &'w Tables,
|
||||
archetypes: &'w Archetypes,
|
||||
fetch: D::Fetch<'w, 's>,
|
||||
fetch: D::Fetch<'w>,
|
||||
query_state: &'s QueryState<D, F>,
|
||||
}
|
||||
|
||||
@ -1043,7 +1069,14 @@ where
|
||||
// SAFETY:
|
||||
// - set_archetype was called prior, `location.archetype_row` is an archetype index in range of the current archetype
|
||||
// - fetch is only called once for each entity.
|
||||
unsafe { D::fetch(&mut self.fetch, entity, location.table_row) }
|
||||
unsafe {
|
||||
D::fetch(
|
||||
&self.query_state.fetch_state,
|
||||
&mut self.fetch,
|
||||
entity,
|
||||
location.table_row,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1123,8 +1156,8 @@ pub struct QueryManyIter<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item:
|
||||
entities: &'w Entities,
|
||||
tables: &'w Tables,
|
||||
archetypes: &'w Archetypes,
|
||||
fetch: D::Fetch<'w, 's>,
|
||||
filter: F::Fetch<'w, 's>,
|
||||
fetch: D::Fetch<'w>,
|
||||
filter: F::Fetch<'w>,
|
||||
query_state: &'s QueryState<D, F>,
|
||||
}
|
||||
|
||||
@ -1171,8 +1204,8 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>
|
||||
entities: &'w Entities,
|
||||
tables: &'w Tables,
|
||||
archetypes: &'w Archetypes,
|
||||
fetch: &mut D::Fetch<'w, 's>,
|
||||
filter: &mut F::Fetch<'w, 's>,
|
||||
fetch: &mut D::Fetch<'w>,
|
||||
filter: &mut F::Fetch<'w>,
|
||||
query_state: &'s QueryState<D, F>,
|
||||
) -> Option<D::Item<'w, 's>> {
|
||||
for entity_borrow in entity_iter {
|
||||
@ -1204,11 +1237,20 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>
|
||||
|
||||
// SAFETY: set_archetype was called prior.
|
||||
// `location.archetype_row` is an archetype index row in range of the current archetype, because if it was not, the match above would have `continue`d
|
||||
if unsafe { F::filter_fetch(filter, entity, location.table_row) } {
|
||||
if unsafe {
|
||||
F::filter_fetch(
|
||||
&query_state.filter_state,
|
||||
filter,
|
||||
entity,
|
||||
location.table_row,
|
||||
)
|
||||
} {
|
||||
// SAFETY:
|
||||
// - set_archetype was called prior, `location.archetype_row` is an archetype index in range of the current archetype
|
||||
// - fetch is only called once for each entity.
|
||||
return Some(unsafe { D::fetch(fetch, entity, location.table_row) });
|
||||
return Some(unsafe {
|
||||
D::fetch(&query_state.fetch_state, fetch, entity, location.table_row)
|
||||
});
|
||||
}
|
||||
}
|
||||
None
|
||||
@ -1919,7 +1961,7 @@ pub struct QuerySortedManyIter<'w, 's, D: QueryData, F: QueryFilter, I: Iterator
|
||||
entities: &'w Entities,
|
||||
tables: &'w Tables,
|
||||
archetypes: &'w Archetypes,
|
||||
fetch: D::Fetch<'w, 's>,
|
||||
fetch: D::Fetch<'w>,
|
||||
query_state: &'s QueryState<D, F>,
|
||||
}
|
||||
|
||||
@ -1987,7 +2029,14 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item = Entity>>
|
||||
// SAFETY:
|
||||
// - set_archetype was called prior, `location.archetype_row` is an archetype index in range of the current archetype
|
||||
// - fetch is only called once for each entity.
|
||||
unsafe { D::fetch(&mut self.fetch, entity, location.table_row) }
|
||||
unsafe {
|
||||
D::fetch(
|
||||
&self.query_state.fetch_state,
|
||||
&mut self.fetch,
|
||||
entity,
|
||||
location.table_row,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get next result from the query
|
||||
@ -2219,7 +2268,8 @@ impl<'w, 's, D: QueryData, F: QueryFilter, const K: usize> QueryCombinationIter<
|
||||
|
||||
let ptr = values.as_mut_ptr().cast::<D::Item<'w, 's>>();
|
||||
for (offset, cursor) in self.cursors.iter_mut().enumerate() {
|
||||
ptr.add(offset).write(cursor.peek_last().unwrap());
|
||||
ptr.add(offset)
|
||||
.write(cursor.peek_last(self.query_state).unwrap());
|
||||
}
|
||||
|
||||
Some(values.assume_init())
|
||||
@ -2313,8 +2363,8 @@ struct QueryIterationCursor<'w, 's, D: QueryData, F: QueryFilter> {
|
||||
storage_id_iter: core::slice::Iter<'s, StorageId>,
|
||||
table_entities: &'w [Entity],
|
||||
archetype_entities: &'w [ArchetypeEntity],
|
||||
fetch: D::Fetch<'w, 's>,
|
||||
filter: F::Fetch<'w, 's>,
|
||||
fetch: D::Fetch<'w>,
|
||||
filter: F::Fetch<'w>,
|
||||
// length of the table or length of the archetype, depending on whether both `D`'s and `F`'s fetches are dense
|
||||
current_len: u32,
|
||||
// either table row or archetype index, depending on whether both `D`'s and `F`'s fetches are dense
|
||||
@ -2394,7 +2444,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
|
||||
/// The result of `next` and any previous calls to `peek_last` with this row must have been
|
||||
/// dropped to prevent aliasing mutable references.
|
||||
#[inline]
|
||||
unsafe fn peek_last(&mut self) -> Option<D::Item<'w, 's>> {
|
||||
unsafe fn peek_last(&mut self, query_state: &'s QueryState<D, F>) -> Option<D::Item<'w, 's>> {
|
||||
if self.current_row > 0 {
|
||||
let index = self.current_row - 1;
|
||||
if self.is_dense {
|
||||
@ -2405,6 +2455,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
|
||||
// - `*entity` and `index` are in the current table.
|
||||
unsafe {
|
||||
Some(D::fetch(
|
||||
&query_state.fetch_state,
|
||||
&mut self.fetch,
|
||||
*entity,
|
||||
// SAFETY: This is from an exclusive range, so it can't be max.
|
||||
@ -2420,6 +2471,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
|
||||
// - `archetype_entity.id()` and `archetype_entity.table_row()` are in the current archetype.
|
||||
unsafe {
|
||||
Some(D::fetch(
|
||||
&query_state.fetch_state,
|
||||
&mut self.fetch,
|
||||
archetype_entity.id(),
|
||||
archetype_entity.table_row(),
|
||||
@ -2488,7 +2540,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
|
||||
unsafe { self.table_entities.get_unchecked(self.current_row as usize) };
|
||||
// SAFETY: The row is less than the u32 len, so it must not be max.
|
||||
let row = unsafe { TableRow::new(NonMaxU32::new_unchecked(self.current_row)) };
|
||||
if !F::filter_fetch(&mut self.filter, *entity, row) {
|
||||
if !F::filter_fetch(&query_state.filter_state, &mut self.filter, *entity, row) {
|
||||
self.current_row += 1;
|
||||
continue;
|
||||
}
|
||||
@ -2498,7 +2550,8 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
|
||||
// - `current_row` must be a table row in range of the current table,
|
||||
// because if it was not, then the above would have been executed.
|
||||
// - fetch is only called once for each `entity`.
|
||||
let item = unsafe { D::fetch(&mut self.fetch, *entity, row) };
|
||||
let item =
|
||||
unsafe { D::fetch(&query_state.fetch_state, &mut self.fetch, *entity, row) };
|
||||
|
||||
self.current_row += 1;
|
||||
return Some(item);
|
||||
@ -2540,6 +2593,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
|
||||
.get_unchecked(self.current_row as usize)
|
||||
};
|
||||
if !F::filter_fetch(
|
||||
&query_state.filter_state,
|
||||
&mut self.filter,
|
||||
archetype_entity.id(),
|
||||
archetype_entity.table_row(),
|
||||
@ -2555,6 +2609,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
|
||||
// - fetch is only called once for each `archetype_entity`.
|
||||
let item = unsafe {
|
||||
D::fetch(
|
||||
&query_state.fetch_state,
|
||||
&mut self.fetch,
|
||||
archetype_entity.id(),
|
||||
archetype_entity.table_row(),
|
||||
|
@ -819,27 +819,24 @@ mod tests {
|
||||
/// SAFETY:
|
||||
/// `update_component_access` adds resource read access for `R`.
|
||||
unsafe impl WorldQuery for ReadsRData {
|
||||
type Fetch<'w, 's> = ();
|
||||
type Fetch<'w> = ();
|
||||
type State = ComponentId;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
_: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
}
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
|
||||
|
||||
unsafe fn init_fetch<'w, 's>(
|
||||
_world: UnsafeWorldCell<'w>,
|
||||
_state: &'s Self::State,
|
||||
_last_run: Tick,
|
||||
_this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
}
|
||||
|
||||
const IS_DENSE: bool = true;
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s Self::State,
|
||||
_archetype: &'w Archetype,
|
||||
_table: &Table,
|
||||
@ -848,7 +845,7 @@ mod tests {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_state: &'s Self::State,
|
||||
_table: &'w Table,
|
||||
) {
|
||||
@ -894,7 +891,8 @@ mod tests {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
_fetch: &mut Self::Fetch<'w, 's>,
|
||||
_state: &'s Self::State,
|
||||
_fetch: &mut Self::Fetch<'w>,
|
||||
_entity: Entity,
|
||||
_table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
|
@ -42,7 +42,7 @@ use variadics_please::all_tuples;
|
||||
/// [`QueryFilter`]: crate::query::QueryFilter
|
||||
pub unsafe trait WorldQuery {
|
||||
/// Per archetype/table state retrieved by this [`WorldQuery`] to compute [`Self::Item`](crate::query::QueryData::Item) for each entity.
|
||||
type Fetch<'w, 's>: Clone;
|
||||
type Fetch<'w>: Clone;
|
||||
|
||||
/// State used to construct a [`Self::Fetch`](WorldQuery::Fetch). This will be cached inside [`QueryState`](crate::query::QueryState),
|
||||
/// so it is best to move as much data / computation here as possible to reduce the cost of
|
||||
@ -50,9 +50,7 @@ pub unsafe trait WorldQuery {
|
||||
type State: Send + Sync + Sized;
|
||||
|
||||
/// This function manually implements subtyping for the query fetches.
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's>;
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort>;
|
||||
|
||||
/// Creates a new instance of [`Self::Fetch`](WorldQuery::Fetch),
|
||||
/// by combining data from the [`World`] with the cached [`Self::State`](WorldQuery::State).
|
||||
@ -69,7 +67,7 @@ pub unsafe trait WorldQuery {
|
||||
state: &'s Self::State,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's>;
|
||||
) -> Self::Fetch<'w>;
|
||||
|
||||
/// Returns true if (and only if) every table of every archetype matched by this fetch contains
|
||||
/// all of the matched components.
|
||||
@ -90,7 +88,7 @@ pub unsafe trait WorldQuery {
|
||||
/// - `table` must correspond to `archetype`.
|
||||
/// - `state` must be the [`State`](Self::State) that `fetch` was initialized with.
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
state: &'s Self::State,
|
||||
archetype: &'w Archetype,
|
||||
table: &'w Table,
|
||||
@ -104,7 +102,7 @@ pub unsafe trait WorldQuery {
|
||||
/// - `table` must be from the same [`World`] that [`WorldQuery::init_state`] was called on.
|
||||
/// - `state` must be the [`State`](Self::State) that `fetch` was initialized with.
|
||||
unsafe fn set_table<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
state: &'s Self::State,
|
||||
table: &'w Table,
|
||||
);
|
||||
@ -160,11 +158,11 @@ macro_rules! impl_tuple_world_query {
|
||||
/// `update_component_access` adds all `With` and `Without` filters from the subqueries.
|
||||
/// 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, 's> = ($($name::Fetch<'w, 's>,)*);
|
||||
type Fetch<'w> = ($($name::Fetch<'w>,)*);
|
||||
type State = ($($name::State,)*);
|
||||
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(fetch: Self::Fetch<'wlong, 's>) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
||||
let ($($name,)*) = fetch;
|
||||
($(
|
||||
$name::shrink_fetch($name),
|
||||
@ -172,7 +170,7 @@ macro_rules! impl_tuple_world_query {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn init_fetch<'w, 's>(world: UnsafeWorldCell<'w>, state: &'s Self::State, last_run: Tick, this_run: Tick) -> Self::Fetch<'w, 's> {
|
||||
unsafe fn init_fetch<'w, 's>(world: UnsafeWorldCell<'w>, state: &'s Self::State, last_run: Tick, this_run: Tick) -> Self::Fetch<'w> {
|
||||
let ($($name,)*) = state;
|
||||
// SAFETY: The invariants are upheld by the caller.
|
||||
($(unsafe { $name::init_fetch(world, $name, last_run, this_run) },)*)
|
||||
@ -182,7 +180,7 @@ macro_rules! impl_tuple_world_query {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
state: &'s Self::State,
|
||||
archetype: &'w Archetype,
|
||||
table: &'w Table
|
||||
@ -194,7 +192,7 @@ macro_rules! impl_tuple_world_query {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(fetch: &mut Self::Fetch<'w, 's>, state: &'s Self::State, table: &'w Table) {
|
||||
unsafe fn set_table<'w, 's>(fetch: &mut Self::Fetch<'w>, state: &'s Self::State, table: &'w Table) {
|
||||
let ($($name,)*) = fetch;
|
||||
let ($($state,)*) = state;
|
||||
// SAFETY: The invariants are upheld by the caller.
|
||||
|
@ -1582,8 +1582,18 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
||||
D::set_archetype(&mut fetch, &self.state.fetch_state, archetype, table);
|
||||
F::set_archetype(&mut filter, &self.state.filter_state, archetype, table);
|
||||
|
||||
if F::filter_fetch(&mut filter, entity, location.table_row) {
|
||||
Ok(D::fetch(&mut fetch, entity, location.table_row))
|
||||
if F::filter_fetch(
|
||||
&self.state.filter_state,
|
||||
&mut filter,
|
||||
entity,
|
||||
location.table_row,
|
||||
) {
|
||||
Ok(D::fetch(
|
||||
&self.state.fetch_state,
|
||||
&mut fetch,
|
||||
entity,
|
||||
location.table_row,
|
||||
))
|
||||
} else {
|
||||
Err(QueryEntityError::QueryDoesNotMatch(
|
||||
entity,
|
||||
|
@ -1030,7 +1030,7 @@ impl<'w> UnsafeEntityCell<'w> {
|
||||
// Table corresponds to archetype. State is the same state used to init fetch above.
|
||||
unsafe { Q::set_archetype(&mut fetch, &state, archetype, table) }
|
||||
// SAFETY: Called after set_archetype above. Entity and location are guaranteed to exist.
|
||||
let item = unsafe { Q::fetch(&mut fetch, self.id(), location.table_row) };
|
||||
let item = unsafe { Q::fetch(&state, &mut fetch, self.id(), location.table_row) };
|
||||
Some(Q::release_state(item))
|
||||
} else {
|
||||
None
|
||||
|
@ -289,12 +289,12 @@ 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 Fetch<'w, 's> = <&'static RenderEntity as WorldQuery>::Fetch<'w, 's>;
|
||||
type Fetch<'w> = <&'static RenderEntity as WorldQuery>::Fetch<'w>;
|
||||
type State = <&'static RenderEntity as WorldQuery>::State;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(
|
||||
fetch: Self::Fetch<'wlong>,
|
||||
) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -304,7 +304,7 @@ mod render_entities_world_query_impls {
|
||||
component_id: &'s ComponentId,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
// SAFETY: defers to the `&T` implementation, with T set to `RenderEntity`.
|
||||
unsafe {
|
||||
<&RenderEntity as WorldQuery>::init_fetch(world, component_id, last_run, this_run)
|
||||
@ -315,7 +315,7 @@ mod render_entities_world_query_impls {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
component_id: &'s ComponentId,
|
||||
archetype: &'w Archetype,
|
||||
table: &'w Table,
|
||||
@ -328,7 +328,7 @@ mod render_entities_world_query_impls {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
&component_id: &'s ComponentId,
|
||||
table: &'w Table,
|
||||
) {
|
||||
@ -374,13 +374,14 @@ mod render_entities_world_query_impls {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
state: &'s Self::State,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
// SAFETY: defers to the `&T` implementation, with T set to `RenderEntity`.
|
||||
let component =
|
||||
unsafe { <&RenderEntity as QueryData>::fetch(fetch, entity, table_row) };
|
||||
unsafe { <&RenderEntity as QueryData>::fetch(state, fetch, entity, table_row) };
|
||||
component.id()
|
||||
}
|
||||
}
|
||||
@ -397,12 +398,12 @@ 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 Fetch<'w, 's> = <&'static MainEntity as WorldQuery>::Fetch<'w, 's>;
|
||||
type Fetch<'w> = <&'static MainEntity as WorldQuery>::Fetch<'w>;
|
||||
type State = <&'static MainEntity as WorldQuery>::State;
|
||||
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||
fetch: Self::Fetch<'wlong, 's>,
|
||||
) -> Self::Fetch<'wshort, 's> {
|
||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(
|
||||
fetch: Self::Fetch<'wlong>,
|
||||
) -> Self::Fetch<'wshort> {
|
||||
fetch
|
||||
}
|
||||
|
||||
@ -412,7 +413,7 @@ mod render_entities_world_query_impls {
|
||||
component_id: &'s ComponentId,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Self::Fetch<'w, 's> {
|
||||
) -> Self::Fetch<'w> {
|
||||
// SAFETY: defers to the `&T` implementation, with T set to `MainEntity`.
|
||||
unsafe {
|
||||
<&MainEntity as WorldQuery>::init_fetch(world, component_id, last_run, this_run)
|
||||
@ -423,7 +424,7 @@ mod render_entities_world_query_impls {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_archetype<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
component_id: &ComponentId,
|
||||
archetype: &'w Archetype,
|
||||
table: &'w Table,
|
||||
@ -436,7 +437,7 @@ mod render_entities_world_query_impls {
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_table<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
&component_id: &'s ComponentId,
|
||||
table: &'w Table,
|
||||
) {
|
||||
@ -482,12 +483,14 @@ mod render_entities_world_query_impls {
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w, 's>(
|
||||
fetch: &mut Self::Fetch<'w, 's>,
|
||||
state: &'s Self::State,
|
||||
fetch: &mut Self::Fetch<'w>,
|
||||
entity: Entity,
|
||||
table_row: TableRow,
|
||||
) -> Self::Item<'w, 's> {
|
||||
// SAFETY: defers to the `&T` implementation, with T set to `MainEntity`.
|
||||
let component = unsafe { <&MainEntity as QueryData>::fetch(fetch, entity, table_row) };
|
||||
let component =
|
||||
unsafe { <&MainEntity as QueryData>::fetch(state, fetch, entity, table_row) };
|
||||
component.id()
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
---
|
||||
title: Query items can borrow from query state
|
||||
pull_requests: [15396]
|
||||
pull_requests: [15396, 19720]
|
||||
---
|
||||
|
||||
The `QueryData::Item` and `WorldQuery::Fetch` associated types and the `QueryItem` and `ROQueryItem` type aliases now have an additional lifetime parameter corresponding to the `'s` lifetime in `Query`.
|
||||
The `QueryData::Item` associated type and the `QueryItem` and `ROQueryItem` type aliases now have an additional lifetime parameter corresponding to the `'s` lifetime in `Query`.
|
||||
The `QueryData::fetch()` and `QueryFilter::filter_fetch()` methods have a new parameter taking a `&'s WorldQuery::State`.
|
||||
Manual implementations of `WorldQuery` and `QueryData` will need to update the method signatures to include the new lifetimes.
|
||||
Other uses of the types will need to be updated to include a lifetime parameter, although it can usually be passed as `'_`.
|
||||
In particular, `ROQueryItem` is used when implementing `RenderCommand`.
|
||||
|
Loading…
Reference in New Issue
Block a user