add uniform field attribute
This commit is contained in:
		
							parent
							
								
									c1bac8869e
								
							
						
					
					
						commit
						4a12d16307
					
				| @ -13,5 +13,6 @@ proc-macro = true | |||||||
| syn = "1.0" | syn = "1.0" | ||||||
| quote = "1.0" | quote = "1.0" | ||||||
| Inflector = { version = "0.11.4", default-features = false } | Inflector = { version = "0.11.4", default-features = false } | ||||||
|  | darling = "0.10.2" | ||||||
| 
 | 
 | ||||||
| [dev-dependencies] | [dev-dependencies] | ||||||
| @ -1,9 +1,10 @@ | |||||||
| extern crate proc_macro; | extern crate proc_macro; | ||||||
| 
 | 
 | ||||||
|  | use darling::FromMeta; | ||||||
| use inflector::Inflector; | use inflector::Inflector; | ||||||
| use proc_macro::TokenStream; | use proc_macro::TokenStream; | ||||||
| use quote::{format_ident, quote}; | use quote::{format_ident, quote}; | ||||||
| use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Fields}; | use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Field, Fields}; | ||||||
| 
 | 
 | ||||||
| #[proc_macro_derive(EntityArchetype)] | #[proc_macro_derive(EntityArchetype)] | ||||||
| pub fn derive_entity_archetype(input: TokenStream) -> TokenStream { | pub fn derive_entity_archetype(input: TokenStream) -> TokenStream { | ||||||
| @ -29,10 +30,19 @@ pub fn derive_entity_archetype(input: TokenStream) -> TokenStream { | |||||||
|         } |         } | ||||||
|     }) |     }) | ||||||
| } | } | ||||||
|  | #[derive(FromMeta, Debug, Default)] | ||||||
|  | struct UniformAttributeArgs { | ||||||
|  |     #[darling(default)] | ||||||
|  |     pub ignore: Option<bool>, | ||||||
|  |     #[darling(default)] | ||||||
|  |     pub shader_def: Option<String>, | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| #[proc_macro_derive(Uniforms)] | #[proc_macro_derive(Uniforms, attributes(uniform))] | ||||||
| pub fn derive_uniforms(input: TokenStream) -> TokenStream { | pub fn derive_uniforms(input: TokenStream) -> TokenStream { | ||||||
|  |     const UNIFORM_ATTRIBUTE_NAME: &'static str = "uniform"; | ||||||
|     let ast = parse_macro_input!(input as DeriveInput); |     let ast = parse_macro_input!(input as DeriveInput); | ||||||
|  | 
 | ||||||
|     let fields = match &ast.data { |     let fields = match &ast.data { | ||||||
|         Data::Struct(DataStruct { |         Data::Struct(DataStruct { | ||||||
|             fields: Fields::Named(fields), |             fields: Fields::Named(fields), | ||||||
| @ -41,19 +51,67 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream { | |||||||
|         _ => panic!("expected a struct with named fields"), |         _ => panic!("expected a struct with named fields"), | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     let uniform_fields = fields | ||||||
|  |         .iter() | ||||||
|  |         .map(|f| { | ||||||
|  |             ( | ||||||
|  |                 f, | ||||||
|  |                 f.attrs | ||||||
|  |                     .iter() | ||||||
|  |                     .find(|a| { | ||||||
|  |                         a.path.get_ident().as_ref().unwrap().to_string() == UNIFORM_ATTRIBUTE_NAME | ||||||
|  |                     }) | ||||||
|  |                     .map(|a| { | ||||||
|  |                         UniformAttributeArgs::from_meta(&a.parse_meta().unwrap()) | ||||||
|  |                             .unwrap_or_else(|_err| UniformAttributeArgs::default()) | ||||||
|  |                     }), | ||||||
|  |             ) | ||||||
|  |         }) | ||||||
|  |         .collect::<Vec<(&Field, Option<UniformAttributeArgs>)>>(); | ||||||
|  | 
 | ||||||
|  |     let active_uniform_fields = uniform_fields | ||||||
|  |         .iter() | ||||||
|  |         .filter(|(_field, attrs)| { | ||||||
|  |             attrs.is_none() | ||||||
|  |                 || match attrs.as_ref().unwrap().ignore { | ||||||
|  |                     Some(ignore) => !ignore, | ||||||
|  |                     None => true, | ||||||
|  |                 } | ||||||
|  |         }) | ||||||
|  |         .map(|(f, _attr)| *f) | ||||||
|  |         .collect::<Vec<&Field>>(); | ||||||
|  | 
 | ||||||
|  |     let shader_defs = uniform_fields | ||||||
|  |         .iter() | ||||||
|  |         .filter(|(_f, attrs)| match attrs { | ||||||
|  |             Some(attrs) => attrs.shader_def.is_some(), | ||||||
|  |             None => false, | ||||||
|  |         }) | ||||||
|  |         .map(|(f, attrs)| { | ||||||
|  |             // attrs is guaranteed to be set because we checked in filter
 | ||||||
|  |             let shader_def = attrs.as_ref().unwrap().shader_def.as_ref().unwrap(); | ||||||
|  |             if shader_def.len() == 0 { | ||||||
|  |                 f.ident.as_ref().unwrap().to_string() | ||||||
|  |             } else { | ||||||
|  |                 shader_def.to_string() | ||||||
|  |             } | ||||||
|  |         }) | ||||||
|  |         .collect::<Vec<String>>(); | ||||||
|  | 
 | ||||||
|     let struct_name = &ast.ident; |     let struct_name = &ast.ident; | ||||||
|     let struct_name_screaming_snake = struct_name.to_string().to_screaming_snake_case(); |     let struct_name_screaming_snake = struct_name.to_string().to_screaming_snake_case(); | ||||||
|     let info_ident = format_ident!("{}_UNIFORM_INFO", struct_name_screaming_snake); |     let info_ident = format_ident!("{}_UNIFORM_INFO", struct_name_screaming_snake); | ||||||
|     let layout_ident = format_ident!("{}_UNIFORM_LAYOUTS", struct_name_screaming_snake); |     let layout_ident = format_ident!("{}_UNIFORM_LAYOUTS", struct_name_screaming_snake); | ||||||
|     let layout_arrays = (0..fields.len()).map(|_| quote!(&[])); |     let layout_arrays = (0..active_uniform_fields.len()).map(|_| quote!(&[])); | ||||||
|     let uniform_name_uniform_info = fields |     let uniform_name_uniform_info = active_uniform_fields | ||||||
|         .iter() |         .iter() | ||||||
|         .map(|field| format!("{}_{}", struct_name, field.ident.as_ref().unwrap())) |         .map(|field| format!("{}_{}", struct_name, field.ident.as_ref().unwrap())) | ||||||
|         .collect::<Vec<String>>(); |         .collect::<Vec<String>>(); | ||||||
|     let get_uniform_bytes_field_name = fields.iter().map(|field| &field.ident); |     let get_uniform_bytes_field_name = active_uniform_fields.iter().map(|field| &field.ident); | ||||||
|     let get_uniform_bytes_uniform_name = uniform_name_uniform_info.clone(); |     let get_uniform_bytes_uniform_name = uniform_name_uniform_info.clone(); | ||||||
|     let get_uniform_info_uniform_name = uniform_name_uniform_info.clone(); |     let get_uniform_info_uniform_name = uniform_name_uniform_info.clone(); | ||||||
|     let get_uniform_info_array_refs = (0..fields.len()).map(|i| quote!(&#info_ident[#i])); |     let get_uniform_info_array_refs = | ||||||
|  |         (0..active_uniform_fields.len()).map(|i| quote!(&#info_ident[#i])); | ||||||
| 
 | 
 | ||||||
|     TokenStream::from(quote! { |     TokenStream::from(quote! { | ||||||
|         const #info_ident: &[UniformInfo] = &[ |         const #info_ident: &[UniformInfo] = &[ | ||||||
| @ -92,6 +150,12 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream { | |||||||
|                     _ => None, |                     _ => None, | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|  |             fn get_shader_defs(&self) -> Vec<&'static str> { | ||||||
|  |                 vec![ | ||||||
|  |                     #(#shader_defs,)* | ||||||
|  |                 ] | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     }) |     }) | ||||||
| } | } | ||||||
|  | |||||||
| @ -1377,7 +1377,7 @@ pub struct ComponentResourceSet { | |||||||
| 
 | 
 | ||||||
| impl ComponentResourceSet { | impl ComponentResourceSet { | ||||||
|     /// Gets the version of the component slice.
 |     /// Gets the version of the component slice.
 | ||||||
|     pub fn version(&self) -> u64 { unsafe { (*self.version.get()) } } |     pub fn version(&self) -> u64 { unsafe { *self.version.get() } } | ||||||
| 
 | 
 | ||||||
|     /// Gets a raw pointer to the start of the component slice.
 |     /// Gets a raw pointer to the start of the component slice.
 | ||||||
|     ///
 |     ///
 | ||||||
|  | |||||||
| @ -305,6 +305,7 @@ impl WgpuRenderer { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // TODO: remove me
 |     // TODO: remove me
 | ||||||
|  |     #[allow(dead_code)] | ||||||
|     fn setup_dynamic_entity_shader_uniforms( |     fn setup_dynamic_entity_shader_uniforms( | ||||||
|         &mut self, |         &mut self, | ||||||
|         world: &World, |         world: &World, | ||||||
|  | |||||||
| @ -41,6 +41,7 @@ pub trait AsUniforms { | |||||||
|     fn get_uniform_info(&self, name: &str) -> Option<&UniformInfo>; |     fn get_uniform_info(&self, name: &str) -> Option<&UniformInfo>; | ||||||
|     fn get_uniform_layouts(&self) -> &[&[UniformPropertyType]]; |     fn get_uniform_layouts(&self) -> &[&[UniformPropertyType]]; | ||||||
|     fn get_uniform_bytes(&self, name: &str) -> Option<Vec<u8>>; |     fn get_uniform_bytes(&self, name: &str) -> Option<Vec<u8>>; | ||||||
|  |     fn get_shader_defs(&self) -> Vec<&'static str>; | ||||||
|     // TODO: support zero-copy uniforms
 |     // TODO: support zero-copy uniforms
 | ||||||
|     // fn get_uniform_bytes_ref(&self, name: &str) -> Option<&[u8]>;
 |     // fn get_uniform_bytes_ref(&self, name: &str) -> Option<&[u8]>;
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -40,4 +40,8 @@ impl AsUniforms for bevy_transform::prelude::LocalToWorld { | |||||||
|             _ => None, |             _ => None, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     fn get_shader_defs(&self) -> std::vec::Vec<&'static str> { | ||||||
|  |         Vec::new() | ||||||
|  |     } | ||||||
| } | } | ||||||
| @ -11,4 +11,6 @@ use bevy_derive::Uniforms; | |||||||
| #[derive(Uniforms)] | #[derive(Uniforms)] | ||||||
| pub struct StandardMaterial { | pub struct StandardMaterial { | ||||||
|     pub albedo: Vec4, |     pub albedo: Vec4, | ||||||
|  |     // #[uniform(ignore,shader_def="Hi")]
 | ||||||
|  |     // pub enable_thing: bool,
 | ||||||
| } | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Carter Anderson
						Carter Anderson