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.

Fixed attributes.

+30 -15
+30 -15
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, Type, parse_macro_input}; 11 + use syn::{Data, DataEnum, DataStruct, DeriveInput, Field, Ident, Index, parse_macro_input}; 12 12 13 13 #[proc_macro_derive(StatContainer, attributes(stat, stat_ignore, add_component))] 14 14 #[proc_macro_error] ··· 48 48 method.into() 49 49 } 50 50 51 - #[derive(FromField)] // Todo Implement manually to allow for naked attributes. 52 - #[darling(attributes(stat, stat_ignore))] 53 - struct FieldState { 51 + #[derive(Default)] 52 + struct FieldOptions { 54 53 ident: Option<Ident>, 55 - ty: Type, 56 - #[darling(default, rename = "stat")] 54 + stat_type: bool, 57 55 include: bool, 58 - #[darling(default, rename = "stat")] 59 56 exclude: bool, 60 57 } 61 58 59 + impl FromField for FieldOptions { 60 + fn from_field(field: &Field) -> darling::Result<Self> { 61 + let mut options = FieldOptions { 62 + ident: field.ident.clone(), 63 + ..Self::default() 64 + }; 65 + 66 + options.stat_type = field.ty.to_token_stream().to_string().contains("Stat"); 67 + 68 + for attribute in &field.attrs { 69 + if let Some(ident) = attribute.path().get_ident() { 70 + match ident.to_string().as_str() { 71 + // Todo Warn about double tags. 72 + "stat" => options.include = true, 73 + "stat_ignore" => options.exclude = true, 74 + _ => continue, 75 + } 76 + } 77 + } 78 + 79 + Ok(options) 80 + } 81 + } 82 + 62 83 fn struct_fields(s: DataStruct) -> darling::Result<TokenStream> { 63 84 let mut tokens = TokenStream::new(); 64 85 for (index, field) in s.fields.iter().enumerate() { 65 - let field_state = FieldState::from_field(&field)?; 66 - 67 - let is_stat_type = field_state 68 - .ty 69 - .to_token_stream() 70 - .to_string() 71 - .contains("Stat"); 86 + let field_state = FieldOptions::from_field(&field)?; 72 87 73 - if (field_state.include || is_stat_type) && !field_state.exclude { 88 + if (field_state.include || field_state.stat_type) && !field_state.exclude { 74 89 if let Some(ident) = field_state.ident { 75 90 tokens.extend(quote! { 76 91 self.#ident.reset_modifiers();