Path: blob/main/crates/bevy_ecs/macros/src/world_query.rs
6600 views
use proc_macro2::Ident;1use quote::quote;2use syn::{Attribute, Fields, ImplGenerics, TypeGenerics, Visibility, WhereClause};34pub(crate) fn item_struct(5path: &syn::Path,6fields: &Fields,7derive_macro_call: &proc_macro2::TokenStream,8struct_name: &Ident,9visibility: &Visibility,10item_struct_name: &Ident,11field_types: &Vec<proc_macro2::TokenStream>,12user_impl_generics_with_world_and_state: &ImplGenerics,13field_attrs: &Vec<Vec<Attribute>>,14field_visibilities: &Vec<Visibility>,15field_idents: &Vec<proc_macro2::TokenStream>,16user_ty_generics: &TypeGenerics,17user_ty_generics_with_world_and_state: &TypeGenerics,18user_where_clauses_with_world_and_state: Option<&WhereClause>,19) -> proc_macro2::TokenStream {20let item_attrs = quote! {21#[doc = concat!(22"Automatically generated [`WorldQuery`](",23stringify!(#path),24"::query::WorldQuery) item type for [`",25stringify!(#struct_name),26"`], returned when iterating over query results."27)]28#[automatically_derived]29};3031match fields {32Fields::Named(_) => quote! {33#derive_macro_call34#item_attrs35#visibility struct #item_struct_name #user_impl_generics_with_world_and_state #user_where_clauses_with_world_and_state {36#(#(#field_attrs)* #field_visibilities #field_idents: <#field_types as #path::query::QueryData>::Item<'__w, '__s>,)*37}38},39Fields::Unnamed(_) => quote! {40#derive_macro_call41#item_attrs42#visibility struct #item_struct_name #user_impl_generics_with_world_and_state #user_where_clauses_with_world_and_state(43#( #field_visibilities <#field_types as #path::query::QueryData>::Item<'__w, '__s>, )*44);45},46Fields::Unit => quote! {47#item_attrs48#visibility type #item_struct_name #user_ty_generics_with_world_and_state = #struct_name #user_ty_generics;49},50}51}5253pub(crate) fn world_query_impl(54path: &syn::Path,55struct_name: &Ident,56visibility: &Visibility,57fetch_struct_name: &Ident,58field_types: &Vec<proc_macro2::TokenStream>,59user_impl_generics: &ImplGenerics,60user_impl_generics_with_world: &ImplGenerics,61user_ty_generics: &TypeGenerics,62user_ty_generics_with_world: &TypeGenerics,63named_field_idents: &Vec<Ident>,64marker_name: &Ident,65state_struct_name: &Ident,66user_where_clauses: Option<&WhereClause>,67user_where_clauses_with_world: Option<&WhereClause>,68) -> proc_macro2::TokenStream {69quote! {70#[doc(hidden)]71#[doc = concat!(72"Automatically generated internal [`WorldQuery`](",73stringify!(#path),74"::query::WorldQuery) fetch type for [`",75stringify!(#struct_name),76"`], used to define the world data accessed by this query."77)]78#[automatically_derived]79#visibility struct #fetch_struct_name #user_impl_generics_with_world #user_where_clauses_with_world {80#(#named_field_idents: <#field_types as #path::query::WorldQuery>::Fetch<'__w>,)*81#marker_name: &'__w(),82}8384impl #user_impl_generics_with_world Clone for #fetch_struct_name #user_ty_generics_with_world85#user_where_clauses_with_world {86fn clone(&self) -> Self {87Self {88#(#named_field_idents: self.#named_field_idents.clone(),)*89#marker_name: &(),90}91}92}9394// SAFETY: `update_component_access` is called on every field95unsafe impl #user_impl_generics #path::query::WorldQuery96for #struct_name #user_ty_generics #user_where_clauses {9798type Fetch<'__w> = #fetch_struct_name #user_ty_generics_with_world;99type State = #state_struct_name #user_ty_generics;100101fn shrink_fetch<'__wlong: '__wshort, '__wshort>(102fetch: <#struct_name #user_ty_generics as #path::query::WorldQuery>::Fetch<'__wlong>103) -> <#struct_name #user_ty_generics as #path::query::WorldQuery>::Fetch<'__wshort> {104#fetch_struct_name {105#(106#named_field_idents: <#field_types>::shrink_fetch(fetch.#named_field_idents),107)*108#marker_name: &(),109}110}111112unsafe fn init_fetch<'__w, '__s>(113_world: #path::world::unsafe_world_cell::UnsafeWorldCell<'__w>,114state: &'__s Self::State,115_last_run: #path::component::Tick,116_this_run: #path::component::Tick,117) -> <Self as #path::query::WorldQuery>::Fetch<'__w> {118#fetch_struct_name {119#(#named_field_idents:120<#field_types>::init_fetch(121_world,122&state.#named_field_idents,123_last_run,124_this_run,125),126)*127#marker_name: &(),128}129}130131const IS_DENSE: bool = true #(&& <#field_types>::IS_DENSE)*;132133/// SAFETY: we call `set_archetype` for each member that implements `Fetch`134#[inline]135unsafe fn set_archetype<'__w, '__s>(136_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,137_state: &'__s Self::State,138_archetype: &'__w #path::archetype::Archetype,139_table: &'__w #path::storage::Table140) {141#(<#field_types>::set_archetype(&mut _fetch.#named_field_idents, &_state.#named_field_idents, _archetype, _table);)*142}143144/// SAFETY: we call `set_table` for each member that implements `Fetch`145#[inline]146unsafe fn set_table<'__w, '__s>(147_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,148_state: &'__s Self::State,149_table: &'__w #path::storage::Table150) {151#(<#field_types>::set_table(&mut _fetch.#named_field_idents, &_state.#named_field_idents, _table);)*152}153154fn update_component_access(state: &Self::State, _access: &mut #path::query::FilteredAccess) {155#( <#field_types>::update_component_access(&state.#named_field_idents, _access); )*156}157158fn init_state(world: &mut #path::world::World) -> #state_struct_name #user_ty_generics {159#state_struct_name {160#(#named_field_idents: <#field_types>::init_state(world),)*161}162}163164fn get_state(components: &#path::component::Components) -> Option<#state_struct_name #user_ty_generics> {165Some(#state_struct_name {166#(#named_field_idents: <#field_types>::get_state(components)?,)*167})168}169170fn matches_component_set(state: &Self::State, _set_contains_id: &impl Fn(#path::component::ComponentId) -> bool) -> bool {171true #(&& <#field_types>::matches_component_set(&state.#named_field_idents, _set_contains_id))*172}173}174}175}176177178