#[allow(unused_imports)]
use crate::shaderprimitive;
#[macro_export]
macro_rules! shader_struct {
{ $struct:ident [
$( $num:tt $field:ident => $ty:ident ),* $(,)?
] } => {
#[derive(Clone, Debug, PartialEq, PartialOrd)]
#[repr(C)]
pub struct $struct {
$( pub $field: $crate::shaderprimitive::$ty, )*
_padding: [u8; Self::PADDING],
}
impl $struct {
const SUM_SIZE: usize = {
#[repr(C)]
struct SizeTest {
$( $field: $crate::shaderprimitive::$ty, )*
}
::std::mem::size_of::<SizeTest>()
};
const MAX_SIZE: usize = $crate::max_size! { $( $crate::shaderprimitive::$ty )* };
pub const BYTES: usize = Self::SUM_SIZE.next_multiple_of(Self::MAX_SIZE);
pub const PADDING: usize = Self::BYTES - Self::SUM_SIZE;
}
impl $crate::shaderstruct::MewShaderStruct for $struct {
type Bytes = [u8; Self::BYTES];
type Inners = ( $( <$crate::shaderprimitive::$ty as $crate::shaderprimitive::MewShaderPrimitive>::Inner , )* );
fn from_inners(inners: Self::Inners) -> Self {
#[allow(unused_imports)]
use $crate::shaderprimitive::MewShaderPrimitive;
Self {
$( $field: $crate::shaderprimitive::$ty::from_inner(inners.$num), )*
_padding: [0; Self::PADDING],
}
}
fn from_bytes(bytes: Self::Bytes) -> Self {
unsafe { ::std::mem::transmute(bytes) }
}
fn zeroed() -> Self {
unsafe {
Self {
$( $field: ::std::mem::zeroed(), )*
_padding: [0; Self::PADDING],
}
}
}
}
impl From<[u8; Self::BYTES]> for $struct {
fn from(bytes: [u8; Self::BYTES]) -> Self {
use $crate::shaderstruct::MewShaderStruct;
Self::from_bytes(bytes)
}
}
impl From<( $( <$crate::shaderprimitive::$ty as $crate::shaderprimitive::MewShaderPrimitive>::Inner , )* )> for $struct {
fn from(inners: ( $( <$crate::shaderprimitive::$ty as $crate::shaderprimitive::MewShaderPrimitive>::Inner , )* )) -> Self {
use $crate::shaderstruct::MewShaderStruct;
Self::from_inners(inners)
}
}
impl AsRef<[u8; Self::BYTES]> for $struct {
fn as_ref(&self) -> &[u8; Self::BYTES] {
unsafe { &*::std::ptr::from_ref(self).cast() }
}
}
impl AsMut<[u8; Self::BYTES]> for $struct {
fn as_mut(&mut self) -> &mut [u8; Self::BYTES] {
unsafe { &mut *::std::ptr::from_mut(self).cast() }
}
}
impl Default for $struct {
fn default() -> Self {
use $crate::shaderstruct::MewShaderStruct;
Self::zeroed()
}
}
}
}
pub use shader_struct;
pub trait MewShaderStruct {
type Bytes;
type Inners;
fn from_inners(inners: Self::Inners) -> Self;
fn from_bytes(bytes: Self::Bytes) -> Self;
fn zeroed() -> Self;
}
pub trait MewShaderStructByteSlice {
fn as_byte_slice(&self) -> &[u8];
}
impl<S: MewShaderStruct> MewShaderStructByteSlice for [S] {
fn as_byte_slice(&self) -> &[u8] {
unsafe {
std::slice::from_raw_parts(
(&raw const *self).cast(),
size_of_val(self),
)
}
}
}