pub use bevy_crevice_derive::GlslStruct;
use std::marker::PhantomData;
pub struct Dimension<A, const N: usize> {
_marker: PhantomData<A>,
}
pub struct DimensionNil;
pub unsafe trait DimensionList {
fn push_to_string(s: &mut String);
}
unsafe impl DimensionList for DimensionNil {
fn push_to_string(_: &mut String) {}
}
unsafe impl<A: DimensionList, const N: usize> DimensionList for Dimension<A, N> {
fn push_to_string(s: &mut String) {
use std::fmt::Write;
A::push_to_string(s);
write!(s, "[{}]", N).unwrap();
}
}
pub unsafe trait Glsl {
const NAME: &'static str;
}
pub unsafe trait GlslStruct: Glsl {
fn enumerate_fields(s: &mut String);
fn glsl_definition() -> String {
let mut output = String::new();
output.push_str("struct ");
output.push_str(Self::NAME);
output.push_str(" {\n");
Self::enumerate_fields(&mut output);
output.push_str("};");
output
}
}
pub unsafe trait GlslArray {
const NAME: &'static str;
type ArraySize: DimensionList;
}
unsafe impl<T: Glsl> GlslArray for T {
const NAME: &'static str = <T as Glsl>::NAME;
type ArraySize = DimensionNil;
}
unsafe impl Glsl for f32 {
const NAME: &'static str = "float";
}
unsafe impl Glsl for f64 {
const NAME: &'static str = "double";
}
unsafe impl Glsl for i32 {
const NAME: &'static str = "int";
}
unsafe impl Glsl for u32 {
const NAME: &'static str = "uint";
}
unsafe impl<T: GlslArray, const N: usize> GlslArray for [T; N] {
const NAME: &'static str = T::NAME;
type ArraySize = Dimension<T::ArraySize, N>;
}