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