Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_ecs/macros/src/world_query.rs
6600 views
1
use proc_macro2::Ident;
2
use quote::quote;
3
use syn::{Attribute, Fields, ImplGenerics, TypeGenerics, Visibility, WhereClause};
4
5
pub(crate) fn item_struct(
6
path: &syn::Path,
7
fields: &Fields,
8
derive_macro_call: &proc_macro2::TokenStream,
9
struct_name: &Ident,
10
visibility: &Visibility,
11
item_struct_name: &Ident,
12
field_types: &Vec<proc_macro2::TokenStream>,
13
user_impl_generics_with_world_and_state: &ImplGenerics,
14
field_attrs: &Vec<Vec<Attribute>>,
15
field_visibilities: &Vec<Visibility>,
16
field_idents: &Vec<proc_macro2::TokenStream>,
17
user_ty_generics: &TypeGenerics,
18
user_ty_generics_with_world_and_state: &TypeGenerics,
19
user_where_clauses_with_world_and_state: Option<&WhereClause>,
20
) -> proc_macro2::TokenStream {
21
let item_attrs = quote! {
22
#[doc = concat!(
23
"Automatically generated [`WorldQuery`](",
24
stringify!(#path),
25
"::query::WorldQuery) item type for [`",
26
stringify!(#struct_name),
27
"`], returned when iterating over query results."
28
)]
29
#[automatically_derived]
30
};
31
32
match fields {
33
Fields::Named(_) => quote! {
34
#derive_macro_call
35
#item_attrs
36
#visibility struct #item_struct_name #user_impl_generics_with_world_and_state #user_where_clauses_with_world_and_state {
37
#(#(#field_attrs)* #field_visibilities #field_idents: <#field_types as #path::query::QueryData>::Item<'__w, '__s>,)*
38
}
39
},
40
Fields::Unnamed(_) => quote! {
41
#derive_macro_call
42
#item_attrs
43
#visibility struct #item_struct_name #user_impl_generics_with_world_and_state #user_where_clauses_with_world_and_state(
44
#( #field_visibilities <#field_types as #path::query::QueryData>::Item<'__w, '__s>, )*
45
);
46
},
47
Fields::Unit => quote! {
48
#item_attrs
49
#visibility type #item_struct_name #user_ty_generics_with_world_and_state = #struct_name #user_ty_generics;
50
},
51
}
52
}
53
54
pub(crate) fn world_query_impl(
55
path: &syn::Path,
56
struct_name: &Ident,
57
visibility: &Visibility,
58
fetch_struct_name: &Ident,
59
field_types: &Vec<proc_macro2::TokenStream>,
60
user_impl_generics: &ImplGenerics,
61
user_impl_generics_with_world: &ImplGenerics,
62
user_ty_generics: &TypeGenerics,
63
user_ty_generics_with_world: &TypeGenerics,
64
named_field_idents: &Vec<Ident>,
65
marker_name: &Ident,
66
state_struct_name: &Ident,
67
user_where_clauses: Option<&WhereClause>,
68
user_where_clauses_with_world: Option<&WhereClause>,
69
) -> proc_macro2::TokenStream {
70
quote! {
71
#[doc(hidden)]
72
#[doc = concat!(
73
"Automatically generated internal [`WorldQuery`](",
74
stringify!(#path),
75
"::query::WorldQuery) fetch type for [`",
76
stringify!(#struct_name),
77
"`], used to define the world data accessed by this query."
78
)]
79
#[automatically_derived]
80
#visibility struct #fetch_struct_name #user_impl_generics_with_world #user_where_clauses_with_world {
81
#(#named_field_idents: <#field_types as #path::query::WorldQuery>::Fetch<'__w>,)*
82
#marker_name: &'__w(),
83
}
84
85
impl #user_impl_generics_with_world Clone for #fetch_struct_name #user_ty_generics_with_world
86
#user_where_clauses_with_world {
87
fn clone(&self) -> Self {
88
Self {
89
#(#named_field_idents: self.#named_field_idents.clone(),)*
90
#marker_name: &(),
91
}
92
}
93
}
94
95
// SAFETY: `update_component_access` is called on every field
96
unsafe impl #user_impl_generics #path::query::WorldQuery
97
for #struct_name #user_ty_generics #user_where_clauses {
98
99
type Fetch<'__w> = #fetch_struct_name #user_ty_generics_with_world;
100
type State = #state_struct_name #user_ty_generics;
101
102
fn shrink_fetch<'__wlong: '__wshort, '__wshort>(
103
fetch: <#struct_name #user_ty_generics as #path::query::WorldQuery>::Fetch<'__wlong>
104
) -> <#struct_name #user_ty_generics as #path::query::WorldQuery>::Fetch<'__wshort> {
105
#fetch_struct_name {
106
#(
107
#named_field_idents: <#field_types>::shrink_fetch(fetch.#named_field_idents),
108
)*
109
#marker_name: &(),
110
}
111
}
112
113
unsafe fn init_fetch<'__w, '__s>(
114
_world: #path::world::unsafe_world_cell::UnsafeWorldCell<'__w>,
115
state: &'__s Self::State,
116
_last_run: #path::component::Tick,
117
_this_run: #path::component::Tick,
118
) -> <Self as #path::query::WorldQuery>::Fetch<'__w> {
119
#fetch_struct_name {
120
#(#named_field_idents:
121
<#field_types>::init_fetch(
122
_world,
123
&state.#named_field_idents,
124
_last_run,
125
_this_run,
126
),
127
)*
128
#marker_name: &(),
129
}
130
}
131
132
const IS_DENSE: bool = true #(&& <#field_types>::IS_DENSE)*;
133
134
/// SAFETY: we call `set_archetype` for each member that implements `Fetch`
135
#[inline]
136
unsafe fn set_archetype<'__w, '__s>(
137
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
138
_state: &'__s Self::State,
139
_archetype: &'__w #path::archetype::Archetype,
140
_table: &'__w #path::storage::Table
141
) {
142
#(<#field_types>::set_archetype(&mut _fetch.#named_field_idents, &_state.#named_field_idents, _archetype, _table);)*
143
}
144
145
/// SAFETY: we call `set_table` for each member that implements `Fetch`
146
#[inline]
147
unsafe fn set_table<'__w, '__s>(
148
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
149
_state: &'__s Self::State,
150
_table: &'__w #path::storage::Table
151
) {
152
#(<#field_types>::set_table(&mut _fetch.#named_field_idents, &_state.#named_field_idents, _table);)*
153
}
154
155
fn update_component_access(state: &Self::State, _access: &mut #path::query::FilteredAccess) {
156
#( <#field_types>::update_component_access(&state.#named_field_idents, _access); )*
157
}
158
159
fn init_state(world: &mut #path::world::World) -> #state_struct_name #user_ty_generics {
160
#state_struct_name {
161
#(#named_field_idents: <#field_types>::init_state(world),)*
162
}
163
}
164
165
fn get_state(components: &#path::component::Components) -> Option<#state_struct_name #user_ty_generics> {
166
Some(#state_struct_name {
167
#(#named_field_idents: <#field_types>::get_state(components)?,)*
168
})
169
}
170
171
fn matches_component_set(state: &Self::State, _set_contains_id: &impl Fn(#path::component::ComponentId) -> bool) -> bool {
172
true #(&& <#field_types>::matches_component_set(&state.#named_field_idents, _set_contains_id))*
173
}
174
}
175
}
176
}
177
178