use crate::{event::Event, reflect::from_reflect_with_fallback, world::World};
use bevy_reflect::{FromReflect, FromType, PartialReflect, Reflect, TypePath, TypeRegistry};
#[derive(Clone)]
pub struct ReflectEvent(ReflectEventFns);
#[derive(Clone)]
pub struct ReflectEventFns {
pub trigger: fn(&mut World, &dyn PartialReflect, &TypeRegistry),
}
impl ReflectEventFns {
pub fn new<'a, T: Event + FromReflect + TypePath>() -> Self
where
T::Trigger<'a>: Default,
{
<ReflectEvent as FromType<T>>::from_type().0
}
}
impl ReflectEvent {
pub fn trigger(&self, world: &mut World, event: &dyn PartialReflect, registry: &TypeRegistry) {
(self.0.trigger)(world, event, registry);
}
pub fn new(fns: ReflectEventFns) -> Self {
ReflectEvent(fns)
}
pub fn fn_pointers(&self) -> &ReflectEventFns {
&self.0
}
}
impl<'a, E: Event + Reflect + TypePath> FromType<E> for ReflectEvent
where
<E as Event>::Trigger<'a>: Default,
{
fn from_type() -> Self {
ReflectEvent(ReflectEventFns {
trigger: |world, reflected_event, registry| {
let event = from_reflect_with_fallback::<E>(reflected_event, world, registry);
world.trigger(event);
},
})
}
}