@@ -20,7 +20,7 @@ use proc_macro::TokenStream;
20
20
use proc_macro2:: Span ;
21
21
use proc_macro_crate:: crate_name;
22
22
use quote:: quote;
23
- use syn:: { parse_macro_input, DeriveInput , Path } ;
23
+ use syn:: { parse_macro_input, DeriveInput , Ident , Index , Lifetime , Path } ;
24
24
25
25
/// Implement `Bundle` for a monomorphic struct
26
26
///
@@ -141,3 +141,76 @@ fn struct_fields(fields: &syn::Fields) -> (Vec<&syn::Type>, Vec<syn::Ident>) {
141
141
syn:: Fields :: Unit => ( Vec :: new ( ) , Vec :: new ( ) ) ,
142
142
}
143
143
}
144
+
145
+ fn get_idents ( fmt_string : fn ( usize ) -> String , count : usize ) -> Vec < Ident > {
146
+ ( 0 ..count)
147
+ . map ( |i| Ident :: new ( & fmt_string ( i) , Span :: call_site ( ) ) )
148
+ . collect :: < Vec < Ident > > ( )
149
+ }
150
+
151
+ fn get_lifetimes ( fmt_string : fn ( usize ) -> String , count : usize ) -> Vec < Lifetime > {
152
+ ( 0 ..count)
153
+ . map ( |i| Lifetime :: new ( & fmt_string ( i) , Span :: call_site ( ) ) )
154
+ . collect :: < Vec < Lifetime > > ( )
155
+ }
156
+
157
+ #[ proc_macro]
158
+ pub fn impl_query_set ( _input : TokenStream ) -> TokenStream {
159
+ let mut tokens = TokenStream :: new ( ) ;
160
+ let max_queries = 4 ;
161
+ let queries = get_idents ( |i| format ! ( "Q{}" , i) , max_queries) ;
162
+ let lifetimes = get_lifetimes ( |i| format ! ( "'q{}" , i) , max_queries) ;
163
+ let mut query_fns = Vec :: new ( ) ;
164
+ let mut query_fn_muts = Vec :: new ( ) ;
165
+ for i in 0 ..max_queries {
166
+ let query = & queries[ i] ;
167
+ let lifetime = & lifetimes[ i] ;
168
+ let fn_name = Ident :: new ( & format ! ( "q{}" , i) , Span :: call_site ( ) ) ;
169
+ let fn_name_mut = Ident :: new ( & format ! ( "q{}_mut" , i) , Span :: call_site ( ) ) ;
170
+ let index = Index :: from ( i) ;
171
+ query_fns. push ( quote ! {
172
+ pub fn #fn_name( & self ) -> & Query <#lifetime, #query> {
173
+ & self . value. #index
174
+ }
175
+ } ) ;
176
+ query_fn_muts. push ( quote ! {
177
+ pub fn #fn_name_mut( & mut self ) -> & mut Query <#lifetime, #query> {
178
+ & mut self . value. #index
179
+ }
180
+ } ) ;
181
+ }
182
+
183
+ for query_count in 1 ..=max_queries {
184
+ let query = & queries[ 0 ..query_count] ;
185
+ let lifetime = & lifetimes[ 0 ..query_count] ;
186
+ let query_fn = & query_fns[ 0 ..query_count] ;
187
+ let query_fn_mut = & query_fn_muts[ 0 ..query_count] ;
188
+ tokens. extend ( TokenStream :: from ( quote ! {
189
+ impl <#( #lifetime, ) * #( #query: HecsQuery , ) * > QueryTuple for ( #( Query <#lifetime, #query>, ) * ) {
190
+ unsafe fn new( world: & World , component_access: & TypeAccess <ArchetypeComponent >) -> Self {
191
+ (
192
+ #(
193
+ Query :: <#query>:: new(
194
+ std:: mem:: transmute( world) ,
195
+ std:: mem:: transmute( component_access) ,
196
+ ) ,
197
+ ) *
198
+ )
199
+ }
200
+
201
+ fn get_accesses( ) -> Vec <QueryAccess > {
202
+ vec![
203
+ #( <#query:: Fetch as Fetch >:: access( ) , ) *
204
+ ]
205
+ }
206
+ }
207
+
208
+ impl <#( #lifetime, ) * #( #query: HecsQuery , ) * > QuerySet <( #( Query <#lifetime, #query>, ) * ) > {
209
+ #( #query_fn) *
210
+ #( #query_fn_mut) *
211
+ }
212
+ } ) ) ;
213
+ }
214
+
215
+ tokens
216
+ }
0 commit comments