glium::implement_uniform_block!
[−]
[src]
macro_rules! implement_uniform_block { (__as_item $i:item) => {$i}; (__impl $struct_name:ident [$($gs:tt)*], $($field_name:ident),+) => ( implement_uniform_block! { __as_item impl<$($gs)*> $crate::uniforms::UniformBlock for $struct_name<$($gs)*> { fn matches(layout: &$crate::program::BlockLayout, base_offset: usize) -> ::std::result::Result<(), $crate::uniforms::LayoutMismatchError> { use std::mem; use $crate::program::BlockLayout; use $crate::uniforms::LayoutMismatchError; if let &BlockLayout::Struct { ref members } = layout { // checking that each member exists in the input struct for &(ref name, _) in members { if $(name != stringify!($field_name) &&)+ true { return Err(LayoutMismatchError::MissingField { name: name.clone(), }); } } fn matches_from_ty<T: $crate::uniforms::UniformBlock + ?Sized>(_: &T, layout: &$crate::program::BlockLayout, base_offset: usize) -> ::std::result::Result<(), $crate::uniforms::LayoutMismatchError> { <T as $crate::uniforms::UniformBlock>::matches(layout, base_offset) } // checking that each field of the input struct is correct in the reflection $( let reflected_ty = members.iter().find(|&&(ref name, _)| { name == stringify!($field_name) }); let reflected_ty = match reflected_ty { Some(t) => &t.1, None => return Err(LayoutMismatchError::MissingField { name: stringify!($field_name).to_owned(), }) }; let input_offset = { let dummy: &$struct_name = unsafe { mem::zeroed() }; let dummy_field: *const _ = &dummy.$field_name; dummy_field as *const () as usize }; let dummy: &$struct_name = unsafe { mem::uninitialized() }; match matches_from_ty(&dummy.$field_name, reflected_ty, input_offset) { Ok(_) => (), Err(e) => return Err(LayoutMismatchError::MemberMismatch { member: stringify!($field_name).to_owned(), err: Box::new(e), }) }; )+ Ok(()) } else { Err(LayoutMismatchError::LayoutMismatch { expected: layout.clone(), obtained: <Self as $crate::uniforms::UniformBlock>::build_layout(base_offset), }) } } fn build_layout(base_offset: usize) -> $crate::program::BlockLayout { use std::mem; use $crate::program::BlockLayout; fn layout_from_ty<T: $crate::uniforms::UniformBlock + ?Sized>(_: &T, base_offset: usize) -> BlockLayout { <T as $crate::uniforms::UniformBlock>::build_layout(base_offset) } let dummy: &$struct_name = unsafe { mem::zeroed() }; BlockLayout::Struct { members: vec![ $( ( stringify!($field_name).to_owned(), { let offset = { let dummy_field: *const _ = &dummy.$field_name; dummy_field as *const () as usize }; layout_from_ty(&dummy.$field_name, offset + base_offset) } ), )+ ], } } } } ); ($struct_name:ident, $($field_name:ident),+,) => ( implement_uniform_block!($struct_name, $($field_name),+); ); ($struct_name:ident, $($field_name:ident),+) => ( implement_uniform_block!(__impl $struct_name [], $($field_name),+); ); ($struct_name:ident<$l:tt>, $($field_name:ident),+) => ( implement_uniform_block!(__impl $struct_name [$l], $($field_name),+); ); }
Implements the glium::uniforms::UniformBlock
trait for the given type.
The parameters must be the name of the struct and the names of its fields.
Example
#[derive(Copy, Clone)] struct Vertex { value1: [f32; 3], value2: [f32; 2], } implement_uniform_block!(Vertex, value1, value2);