use crate::godot::nodes::SiloVariant;
use bytes;
use godot::obj::GdMut;
use serde::de::Deserialize;
use std::collections::HashMap;
trait VariantHandler {
fn handle(
&self,
world: &crate::godot::nodes::SiloWorld,
s: GdMut<SiloVariant>,
v: &bytes::Bytes,
);
}
struct GenericHandler<T: for<'a> Deserialize<'a> + 'static> {
f: fn(&crate::godot::nodes::SiloWorld, GdMut<SiloVariant>, &T),
}
impl<T: for<'a> Deserialize<'a> + 'static> VariantHandler for GenericHandler<T> {
fn handle(
&self,
world: &crate::godot::nodes::SiloWorld,
s: GdMut<SiloVariant>,
v: &bytes::Bytes,
) {
if let Ok(r) = serde_cbor::from_slice::<T>(v) {
(self.f)(world, s, &r);
}
}
}
static mut VARIANTS: Option<HashMap<String, Box<dyn VariantHandler>>> = None;
pub fn add_variant<T: for<'a> Deserialize<'a> + 'static>(
f: fn(&crate::godot::nodes::SiloWorld, GdMut<SiloVariant>, &T),
) {
unsafe {
let variants_ptr = &raw mut VARIANTS;
if (*variants_ptr).is_none() {
*variants_ptr = Some(HashMap::new());
}
if let Some(variants) = &mut *variants_ptr {
variants.insert(
std::any::type_name::<T>().to_string(),
Box::new(GenericHandler { f }),
);
}
}
}
pub fn set_variant(
world: &crate::godot::nodes::SiloWorld,
s: GdMut<SiloVariant>,
t: &String,
v: &bytes::Bytes,
) {
unsafe {
let variants_ptr = &raw mut VARIANTS;
if let Some(variants) = &(*variants_ptr) {
if let Some(f) = variants.get(t) {
f.handle(world, s, v);
}
}
}
}