use bevy::{prelude::*, reflect::FromType};
use bevy_behave::prelude::*;
pub trait HtnOperator: Reflect + Default + Clone + std::fmt::Debug {
fn to_tree(&self) -> Tree<Behave>;
}
#[derive(Clone)]
pub struct ReflectHtnOperator(ReflectHtnOperatorFns);
#[derive(Clone)]
pub struct ReflectHtnOperatorFns {
pub to_tree: fn(&dyn Reflect) -> Tree<Behave>,
}
impl ReflectHtnOperatorFns {
pub fn new<T: HtnOperator + Reflect>() -> Self {
<ReflectHtnOperator as FromType<T>>::from_type().0
}
}
impl ReflectHtnOperator {
pub fn to_tree(&self, event: &dyn Reflect) -> Tree<Behave> {
(self.0.to_tree)(event)
}
pub fn new(fns: ReflectHtnOperatorFns) -> Self {
Self(fns)
}
pub fn fn_pointers(&self) -> &ReflectHtnOperatorFns {
&self.0
}
}
impl<E: HtnOperator + Reflect> FromType<E> for ReflectHtnOperator {
fn from_type() -> Self {
ReflectHtnOperator(ReflectHtnOperatorFns {
to_tree: |op| -> Tree<Behave> {
let Some(ev) = op.downcast_ref::<E>() else {
panic!("Event is not of type {}", std::any::type_name::<E>());
};
ev.to_tree()
},
})
}
}