use std::ops::{ Deref, DerefMut, };
macro_rules! primitive {
{ $name:ident [ $ty:ty ; $len:literal ] => $align:literal } => {
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
#[repr(align($align))]
pub struct $name([$ty; $len]);
impl $name {
pub const BYTES: usize = size_of::<$ty>() * $len;
}
impl $crate::shaderprimitive::MewShaderPrimitive for $name {
type Bytes = [u8; Self::BYTES];
type Inner = [$ty; $len];
fn from_inner(inner: Self::Inner) -> Self {
Self(inner)
}
fn from_bytes(bytes: Self::Bytes) -> Self {
unsafe { Self(::std::mem::transmute::<[u8; Self::BYTES], [$ty; $len]>(bytes)) }
}
fn zeroed() -> Self {
unsafe { Self(::std::mem::zeroed()) }
}
}
impl From<[u8; Self::BYTES]> for $name {
fn from(bytes: [u8; Self::BYTES]) -> Self {
Self::from_bytes(bytes)
}
}
impl From<[$ty; $len]> for $name {
fn from(inner: [$ty; $len]) -> Self {
Self::from_inner(inner)
}
}
impl Deref for $name {
type Target = [$ty; $len];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for $name {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl AsRef<[u8; Self::BYTES]> for $name {
fn as_ref(&self) -> &[u8; Self::BYTES] {
unsafe { &*(&raw const self.0).cast() }
}
}
impl AsMut<[u8; Self::BYTES]> for $name {
fn as_mut(&mut self) -> &mut [u8; Self::BYTES] {
unsafe { &mut *(&raw mut self.0).cast() }
}
}
impl Default for $name {
fn default() -> Self {
Self::zeroed()
}
}
};
}
primitive! { I32 [i32; 1] => 4 }
primitive! { U32 [u32; 1] => 4 }
primitive! { F32 [f32; 1] => 4 }
primitive! { Vec2i [i32; 2] => 8 }
primitive! { Vec2u [u32; 2] => 8 }
primitive! { Vec2f [f32; 2] => 8 }
primitive! { Vec3i [i32; 3] => 16 }
primitive! { Vec3u [u32; 3] => 16 }
primitive! { Vec3f [f32; 3] => 16 }
primitive! { Vec4i [i32; 4] => 16 }
primitive! { Vec4u [u32; 4] => 16 }
primitive! { Vec4f [f32; 4] => 16 }
primitive! { Mat2x2i [[i32; 2]; 2] => 16 }
primitive! { Mat2x2u [[u32; 2]; 2] => 16 }
primitive! { Mat2x2f [[f32; 2]; 2] => 16 }
primitive! { Mat3x2i [[i32; 2]; 3] => 32 }
primitive! { Mat3x2u [[u32; 2]; 3] => 32 }
primitive! { Mat3x2f [[f32; 2]; 3] => 32 }
primitive! { Mat4x2i [[i32; 2]; 4] => 32 }
primitive! { Mat4x2u [[u32; 2]; 4] => 32 }
primitive! { Mat4x2f [[f32; 2]; 4] => 32 }
primitive! { Mat2x3i [[i32; 3]; 2] => 32 }
primitive! { Mat2x3u [[u32; 3]; 2] => 32 }
primitive! { Mat2x3f [[f32; 3]; 2] => 32 }
primitive! { Mat3x3i [[i32; 3]; 3] => 64 }
primitive! { Mat3x3u [[u32; 3]; 3] => 64 }
primitive! { Mat3x3f [[f32; 3]; 3] => 64 }
primitive! { Mat4x3i [[i32; 3]; 4] => 64 }
primitive! { Mat4x3u [[u32; 3]; 4] => 64 }
primitive! { Mat4x3f [[f32; 3]; 4] => 64 }
primitive! { Mat2x4i [[i32; 4]; 2] => 32 }
primitive! { Mat2x4u [[u32; 4]; 2] => 32 }
primitive! { Mat2x4f [[f32; 4]; 2] => 32 }
primitive! { Mat3x4i [[i32; 4]; 3] => 64 }
primitive! { Mat3x4u [[u32; 4]; 3] => 64 }
primitive! { Mat3x4f [[f32; 4]; 3] => 64 }
primitive! { Mat4x4i [[i32; 4]; 4] => 64 }
primitive! { Mat4x4u [[u32; 4]; 4] => 64 }
primitive! { Mat4x4f [[f32; 4]; 4] => 64 }
pub trait MewShaderPrimitive {
type Bytes;
type Inner;
fn from_inner(inner: Self::Inner) -> Self;
fn from_bytes(bytes: Self::Bytes) -> Self;
fn zeroed() -> Self;
}