use std::num::NonZeroU64;
use super::{AlignmentValue, BufferMut, BufferRef, Reader, SizeValue, Writer};
const UNIFORM_MIN_ALIGNMENT: AlignmentValue = AlignmentValue::new(16);
pub struct Metadata<E> {
pub alignment: AlignmentValue,
pub has_uniform_min_alignment: bool,
pub min_size: SizeValue,
pub is_pod: bool,
pub extra: E,
}
impl Metadata<()> {
pub const fn from_alignment_and_size(alignment: u64, size: u64) -> Self {
Self {
alignment: AlignmentValue::new(alignment),
has_uniform_min_alignment: false,
min_size: SizeValue::new(size),
is_pod: false,
extra: (),
}
}
}
impl<E> Metadata<E> {
#[inline]
pub const fn alignment(self) -> AlignmentValue {
let value = self.alignment;
core::mem::forget(self);
value
}
#[inline]
pub const fn uniform_min_alignment(self) -> Option<AlignmentValue> {
let value = self.has_uniform_min_alignment;
core::mem::forget(self);
match value {
true => Some(UNIFORM_MIN_ALIGNMENT),
false => None,
}
}
#[inline]
pub const fn min_size(self) -> SizeValue {
let value = self.min_size;
core::mem::forget(self);
value
}
#[inline]
pub const fn is_pod(self) -> bool {
let value = self.is_pod;
core::mem::forget(self);
value
}
#[inline]
pub const fn pod(mut self) -> Self {
self.is_pod = true;
self
}
#[inline]
pub const fn no_pod(mut self) -> Self {
self.is_pod = false;
self
}
}
pub trait ShaderType {
#[doc(hidden)]
type ExtraMetadata;
#[doc(hidden)]
const METADATA: Metadata<Self::ExtraMetadata>;
#[inline]
fn min_size() -> NonZeroU64 {
Self::METADATA.min_size().0
}
#[inline]
fn size(&self) -> NonZeroU64 {
Self::METADATA.min_size().0
}
#[doc(hidden)]
const UNIFORM_COMPAT_ASSERT: fn() = || {};
#[inline]
fn assert_uniform_compat() {
Self::UNIFORM_COMPAT_ASSERT();
}
}
pub trait ShaderSize: ShaderType {
const SHADER_SIZE: NonZeroU64 = Self::METADATA.min_size().0;
}
pub trait CalculateSizeFor {
fn calculate_size_for(nr_of_el: u64) -> NonZeroU64;
}
#[allow(clippy::len_without_is_empty)]
pub trait RuntimeSizedArray {
fn len(&self) -> usize;
}
pub trait WriteInto {
fn write_into<B>(&self, writer: &mut Writer<B>)
where
B: BufferMut;
}
pub trait ReadFrom {
fn read_from<B>(&mut self, reader: &mut Reader<B>)
where
B: BufferRef;
}
pub trait CreateFrom: Sized {
fn create_from<B>(reader: &mut Reader<B>) -> Self
where
B: BufferRef;
}