use std::{mem, slice};
pub trait PushConstant {
fn size(&self) -> usize;
fn name(&self) -> &str;
fn bytes(&self) -> Vec<u32>;
}
#[repr(C)]
struct TypedPushConstant<T> {
value: T,
name: String,
}
impl<T> TypedPushConstant<T> {
fn new(value: T, name: String) -> Self {
Self { value, name }
}
}
impl<T> PushConstant for TypedPushConstant<T> {
fn size(&self) -> usize {
std::mem::size_of_val(&self.value)
}
fn name(&self) -> &str {
&self.name
}
fn bytes(&self) -> Vec<u32> {
let mut bytes = Vec::new();
let vp: *const T = &self.value;
let bp: *const u32 = vp as *const _;
let bs: &[u32] =
unsafe { slice::from_raw_parts(bp, mem::size_of::<T>() / mem::size_of::<u32>()) };
bytes.extend_from_slice(&bs);
bytes
}
}
pub fn load_push_constants_from_json(data: &json::JsonValue) -> Vec<Box<dyn PushConstant>> {
let mut uniforms: Vec<Box<dyn PushConstant>> = Vec::new();
let uniforms_json = &data["push constants"];
if !uniforms_json.is_null() {
let entries = uniforms_json.entries();
for entry in entries {
let name = entry.0;
let mut array_itr = entry.1.members();
let type_str = array_itr.next().unwrap().as_str().unwrap();
let value = array_itr.next().unwrap();
if type_str == "f32" {
uniforms.push(Box::new(TypedPushConstant::new(
value.as_f32().unwrap(),
String::from(name),
)));
} else if type_str == "f64" {
uniforms.push(Box::new(TypedPushConstant::new(
value.as_f64().unwrap(),
String::from(name),
)));
} else if type_str == "u32" {
uniforms.push(Box::new(TypedPushConstant::new(
value.as_u32().unwrap(),
String::from(name),
)));
} else if type_str == "u64" {
uniforms.push(Box::new(TypedPushConstant::new(
value.as_u64().unwrap(),
String::from(name),
)));
} else if type_str == "i32" {
uniforms.push(Box::new(TypedPushConstant::new(
value.as_i32().unwrap(),
String::from(name),
)));
} else if type_str == "i64" {
uniforms.push(Box::new(TypedPushConstant::new(
value.as_i64().unwrap(),
String::from(name),
)));
} else if type_str == "bool" {
uniforms.push(Box::new(TypedPushConstant::new(
value.as_bool().unwrap() as u32,
String::from(name),
)));
}
}
}
uniforms
}