diff --git a/src/interpolate.rs b/src/interpolate.rs index 1bc0fac..b69a7a6 100644 --- a/src/interpolate.rs +++ b/src/interpolate.rs @@ -105,6 +105,83 @@ pub trait Interpolator: Send + Sync + 'static { fn interpolate(&self, item: &mut Self::Item, value: f32); } +/// Reflect [`Interpolator`] trait +#[allow(clippy::type_complexity)] +pub struct ReflectInterpolator { + get_func: fn(&dyn Reflect) -> Option<&dyn Interpolator>, + get_mut_func: + fn(&mut dyn Reflect) -> Option<&mut dyn Interpolator>, + get_boxed_func: + fn( + Box, + ) + -> Result>, Box>, +} + +impl Clone for ReflectInterpolator { + #[inline] + fn clone(&self) -> ReflectInterpolator { + ReflectInterpolator { + get_func: Clone::clone(&self.get_func), + get_mut_func: Clone::clone(&self.get_mut_func), + get_boxed_func: Clone::clone(&self.get_boxed_func), + } + } +} +impl ReflectInterpolator { + /** Downcast a `&dyn Reflect` type to `&dyn Interpolator`. + + If the type cannot be downcast, `None` is returned.*/ + pub fn get<'a>( + &self, + reflect_value: &'a dyn Reflect, + ) -> Option<&'a dyn Interpolator> { + (self.get_func)(reflect_value) + } + + /** Downcast a `&mut dyn Reflect` type to `&mut dyn Interpolator`. + + If the type cannot be downcast, `None` is returned.*/ + pub fn get_mut<'a>( + &self, + reflect_value: &'a mut dyn Reflect, + ) -> Option<&'a mut dyn Interpolator> { + (self.get_mut_func)(reflect_value) + } + + /** Downcast a `Box` type to `Box`. + + If the type cannot be downcast, this will return `Err(Box)`.*/ + pub fn get_boxed( + &self, + reflect_value: Box, + ) -> Result>, Box> { + (self.get_boxed_func)(reflect_value) + } +} + +impl bevy::reflect::FromType for ReflectInterpolator +where + T: Interpolator + Reflect, +{ + fn from_type() -> Self { + Self { + get_func: |reflect_value| { + ::downcast_ref::(reflect_value) + .map(|value| value as &dyn Interpolator) + }, + get_mut_func: |reflect_value| { + ::downcast_mut::(reflect_value) + .map(|value| value as &mut dyn Interpolator) + }, + get_boxed_func: |reflect_value| { + ::downcast::(reflect_value) + .map(|value| value as Box>) + }, + } + } +} + impl Interpolator for Box where I: Interpolator + ?Sized, @@ -159,15 +236,21 @@ impl Plugin for DefaultInterpolatorsPlugin { .register_type::>() .register_type::>() .register_type::>() - .register_type::>(); + .register_type::>() + .register_type_data::>() + .register_type_data::>() + .register_type_data::>() + .register_type_data::>(); #[cfg(feature = "bevy_sprite")] app.add_tween_systems(tween::component_tween_system::) - .register_type::>(); + .register_type::>() + .register_type_data::>(); #[cfg(all(feature = "bevy_sprite", feature = "bevy_asset",))] app.add_tween_systems(tween::asset_tween_system::) - .register_type::>(); + .register_type::>() + .register_type_data::>(); } } diff --git a/src/interpolation.rs b/src/interpolation.rs index 9ad709b..96a375e 100644 --- a/src/interpolation.rs +++ b/src/interpolation.rs @@ -15,6 +15,7 @@ mod ease_functions; /// A trait for implementing interpolation algorithms. /// Use with [`sample_interpolations_system`] +#[reflect_trait] pub trait Interpolation { /// Sample a value from this algorithm. /// Input should be between 0 to 1 and returns value that should be @@ -37,7 +38,7 @@ impl Plugin for EaseFunctionPlugin { /// Easing functions put into an enum. #[allow(missing_docs)] #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Component, Reflect)] -#[reflect(Component)] +#[reflect(Component, Interpolation)] pub enum EaseFunction { #[default] Linear,