Game stats that reset every frame, inspired by immediate mode GUI.
gamedev bevy stats
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Simplified field parsing code.

+18 -19
+18 -19
immediate_stats_macros/src/lib.rs
··· 8 8 use proc_macro2::{Span, TokenStream}; 9 9 use quote::{ToTokens, quote}; 10 10 use syn::spanned::Spanned; 11 - use syn::{Data, DataEnum, DataStruct, DeriveInput, Field, Ident, Index, parse_macro_input}; 11 + use syn::{Data, DataEnum, DeriveInput, Field, Fields, Ident, Index, parse_macro_input}; 12 12 13 13 #[proc_macro_derive(StatContainer, attributes(stat, stat_ignore, add_component))] 14 14 #[proc_macro_error] ··· 18 18 let struct_name = &tree.ident; 19 19 20 20 let method_contents = match tree.data.clone() { 21 - Data::Struct(s) => struct_fields(s).unwrap(), 21 + Data::Struct(s) => reset_fields(&s.fields).unwrap(), 22 22 Data::Enum(e) => stat_container_enum(e), 23 23 Data::Union(_) => { 24 24 emit_call_site_error!("This trait cannot be derived from unions."); ··· 80 80 } 81 81 } 82 82 83 - fn struct_fields(s: DataStruct) -> darling::Result<TokenStream> { 84 - let mut tokens = TokenStream::new(); 85 - for (index, field) in s.fields.iter().enumerate() { 86 - let field_state = FieldOptions::from_field(&field)?; 83 + /// Returns the code needed to reset any stat fields. 84 + fn reset_fields(fields: &Fields) -> darling::Result<TokenStream> { 85 + for (index, field) in fields.iter().enumerate() { 86 + let options = FieldOptions::from_field(&field)?; 87 87 88 - if (field_state.include || field_state.stat_type) && !field_state.exclude { 89 - if let Some(ident) = field_state.ident { 90 - tokens.extend(quote! { 91 - self.#ident.reset_modifiers(); 92 - }); 93 - } else { 94 - let index = Index::from(index); 95 - tokens.extend(quote! { 96 - self.#index.reset_modifiers(); 97 - }); 98 - } 88 + if (options.include || options.stat_type) && !options.exclude { 89 + return Ok(match options.ident { 90 + Some(ident) => { 91 + quote! { self.#ident.reset_modifiers(); } 92 + } 93 + None => { 94 + let index = Index::from(index); 95 + quote! { self.#index.reset_modifiers(); } 96 + } 97 + }); 99 98 } 100 99 101 - if field_state.include && field_state.exclude { 100 + if options.include && options.exclude { 102 101 emit_warning!( 103 102 field.span(), 104 103 "`stat` attribute is overruled by `stat_ignore` attribute." ··· 106 105 } 107 106 } 108 107 109 - Ok(tokens) 108 + Ok(TokenStream::new()) 110 109 } 111 110 112 111 fn stat_container_enum(e: DataEnum) -> TokenStream {