mew/
vertexstruct.rs

1#[macro_export]
2macro_rules! vertex_struct {
3    { $struct:ident [
4        $( $num:tt $field:ident => $attr:ident ),* $(,)?
5    ] } => {
6        $crate::vertex_struct! { $struct step Vertex [
7            $( $num $field => $attr , )*
8        ] }
9    };
10    { $struct:ident step $step:ident [
11        $( $num:tt $field:ident => $attr:ident ),* $(,)?
12    ] } => {
13        #[derive(Debug)]
14        #[repr(C, packed(2))]
15        pub struct $struct {
16            $( pub $field: $crate::vertexformat::$attr, )*
17            pub _padding: [u8; Self::PADDING],
18        }
19
20        impl $struct {
21            //pub const SUM_SIZE: usize = ::std::mem::size_of::<( $( $attr, )* )>();
22            //pub const SUM_SIZE: usize = sum_size! { $( $attr )* };
23            pub const SUM_SIZE: usize = {
24                #[repr(C, packed(2))]
25                struct SizeTest {
26                    $( $field: $crate::vertexformat::$attr, )*
27                }
28                ::std::mem::size_of::<SizeTest>()
29            };
30            pub const BYTES: usize = Self::SUM_SIZE.next_multiple_of(4);
31            pub const PADDING: usize = Self::BYTES - Self::SUM_SIZE;
32        }
33
34        impl $crate::vertexstruct::MewVertexStruct for $struct {
35            type Bytes = [u8; Self::BYTES];
36            type Inners = ( $( <$crate::vertexformat::$attr as $crate::vertexformat::MewVertexFormat>::Inner , )* );
37            type InnerRefs<'i> = ( $( &'i <$crate::vertexformat::$attr as $crate::vertexformat::MewVertexFormat>::Inner , )* );
38            type InnerMuts<'i> = ( $( &'i mut <$crate::vertexformat::$attr as $crate::vertexformat::MewVertexFormat>::Inner , )* );
39
40            fn from_inners(inners: Self::Inners) -> Self {
41                use $crate::vertexformat::MewVertexFormat;
42                Self {
43                    $( $field: $crate::vertexformat::$attr::from_inner(inners.$num), )*
44                    _padding: [0; Self::PADDING],
45                }
46            }
47
48            fn from_bytes(bytes: Self::Bytes) -> Self {
49                //unsafe { ::std::mem::transmute(bytes) }
50                todo!()
51            }
52
53            fn zeroed() -> Self {
54                unsafe {
55                    Self {
56                        $( $field: ::std::mem::zeroed(), )*
57                        _padding: [0; Self::PADDING],
58                    }
59                }
60            }
61
62            fn get_refs(&self) -> Self::InnerRefs<'_> {
63                unsafe {
64                    ( $( &*&raw const self.$field, )* )
65                }
66            }
67
68            fn get_muts(&mut self) -> Self::InnerMuts<'_> {
69                unsafe {
70                    ( $( &mut *&raw mut self.$field, )* )
71                }
72            }
73
74            fn vertex_layout() -> $crate::wgpu::VertexBufferLayout<'static> {
75                static ATTRIBUTES: [$crate::wgpu::VertexAttribute; len! { $( $num )* }] = $crate::wgpu::vertex_attr_array![ $( $num => $attr , )* ];
76                $crate::wgpu::VertexBufferLayout {
77                    //array_stride: ::std::mem::size_of::<Self>() as u64,
78                    array_stride: Self::BYTES as u64,
79                    step_mode: $crate::wgpu::VertexStepMode::$step,
80                    attributes: &ATTRIBUTES,
81                }
82            }
83        }
84
85
86        impl From<[u8; Self::BYTES]> for $struct {
87            fn from(bytes: [u8; Self::BYTES]) -> Self {
88                Self::from_bytes(bytes)
89            }
90        }
91        impl From<( $( <$crate::vertexformat::$attr as $crate::vertexformat::MewVertexFormat>::Inner , )* )> for $struct {
92            fn from(inners: ( $( <$crate::vertexformat::$attr as $crate::vertexformat::MewVertexFormat>::Inner , )* )) -> Self {
93                Self::from_inners(inners)
94            }
95        }
96
97        impl AsRef<[u8; Self::BYTES]> for $struct {
98            fn as_ref(&self) -> &[u8; Self::BYTES] {
99                unsafe { ::std::mem::transmute(self) }
100            }
101        }
102        impl AsMut<[u8; Self::BYTES]> for $struct {
103            fn as_mut(&mut self) -> &mut [u8; Self::BYTES] {
104                unsafe { ::std::mem::transmute(self) }
105            }
106        }
107
108        impl Clone for $struct {
109            fn clone(&self) -> Self {
110                unsafe {
111                    Self {
112                        $( $field: *&raw const self.$field, )*
113                        _padding: [0; Self::PADDING],
114                    }
115                }
116            }
117        }
118
119        impl Default for $struct {
120            fn default() -> Self {
121                Self::zeroed()
122            }
123        }
124    }
125}
126pub use vertex_struct;
127
128
129pub trait MewVertexStruct {
130    type Bytes;
131    type Inners;
132    type InnerRefs<'i> where Self: 'i;
133    type InnerMuts<'i> where Self: 'i;
134    fn from_inners(inners: Self::Inners) -> Self;
135    fn from_bytes(bytes: Self::Bytes) -> Self;
136    fn zeroed() -> Self;
137    fn get_refs<'i>(&'i self) -> Self::InnerRefs<'i>;
138    fn get_muts<'i>(&'i mut self) -> Self::InnerMuts<'i>;
139    fn vertex_layout() -> wgpu::VertexBufferLayout<'static>;
140}