Skip to main content

bevy_animation/
animation_curves.rs

1//! The [`AnimationCurve`] trait and adaptors that allow curves to implement it.
2//!
3//! # Overview
4//!
5//! The flow of curves into the animation system generally begins with something that
6//! implements the [`Curve`] trait. Let's imagine, for example, that we have some
7//! `Curve<Vec3>` that we want to use to animate something. That could be defined in
8//! a number of different ways, but let's imagine that we've defined it [using a function]:
9//!
10//!     # use bevy_math::curve::{Curve, Interval, FunctionCurve};
11//!     # use bevy_math::vec3;
12//!     let wobble_curve = FunctionCurve::new(
13//!         Interval::UNIT,
14//!         |t| { vec3(t.cos(), 0.0, 0.0) },
15//!     );
16//!
17//! Okay, so we have a curve, but the animation system also needs to know, in some way,
18//! how the values from this curve should actually be used. That is, it needs to know what
19//! to animate! That's what [`AnimationCurve`] is for. In particular, what we need to do
20//! is take our curve and turn it into an `AnimationCurve` which will be usable by the
21//! animation system.
22//!
23//! For instance, let's imagine that we want to use the `Vec3` output
24//! from our curve to animate the [translation component of a `Transform`]. For this, there is
25//! the adaptor [`AnimatableCurve`], which wraps any [`Curve`] and [`AnimatableProperty`] and turns it into an
26//! [`AnimationCurve`] that will use the given curve to animate the entity's property:
27//!
28//!     # use bevy_math::curve::{Curve, Interval, FunctionCurve};
29//!     # use bevy_math::vec3;
30//!     # use bevy_transform::components::Transform;
31//!     # use bevy_animation::{animated_field, animation_curves::*};
32//!     # let wobble_curve = FunctionCurve::new(
33//!     #     Interval::UNIT,
34//!     #     |t| vec3(t.cos(), 0.0, 0.0)
35//!     # );
36//!     let wobble_animation = AnimatableCurve::new(animated_field!(Transform::translation), wobble_curve);
37//!
38//! And finally, this [`AnimationCurve`] needs to be added to an [`AnimationClip`] in order to
39//! actually animate something. This is what that looks like:
40//!
41//!     # use bevy_math::curve::{Curve, Interval, FunctionCurve};
42//!     # use bevy_animation::{AnimationClip, AnimationTargetId, animated_field, animation_curves::*};
43//!     # use bevy_transform::components::Transform;
44//!     # use bevy_ecs::name::Name;
45//!     # use bevy_math::vec3;
46//!     # let wobble_curve = FunctionCurve::new(
47//!     #     Interval::UNIT,
48//!     #     |t| { vec3(t.cos(), 0.0, 0.0) },
49//!     # );
50//!     # let wobble_animation = AnimatableCurve::new(animated_field!(Transform::translation), wobble_curve);
51//!     # let animation_target_id = AnimationTargetId::from(&Name::new("Test"));
52//!     let mut animation_clip = AnimationClip::default();
53//!     animation_clip.add_curve_to_target(
54//!         animation_target_id,
55//!         wobble_animation,
56//!     );
57//!
58//! # Making animation curves
59//!
60//! The overview showed one example, but in general there are a few different ways of going from
61//! a [`Curve`], which produces time-related data of some kind, to an [`AnimationCurve`], which
62//! knows how to apply that data to an entity.
63//!
64//! ## Animated Fields
65//!
66//! The [`animated_field`] macro (which returns an [`AnimatedField`]), in combination with [`AnimatableCurve`]
67//! is the easiest way to make an animation curve (see the example above).
68//!
69//! This will select a field on a component and pass it to a [`Curve`] with a type that matches the field.
70//!
71//! ## Animatable Properties
72//!
73//! Animation of arbitrary aspects of entities can be accomplished using [`AnimatableProperty`] in
74//! conjunction with [`AnimatableCurve`]. See the documentation [there] for details.
75//!
76//! ## Custom [`AnimationCurve`] and [`AnimationCurveEvaluator`]
77//!
78//! This is the lowest-level option with the most control, but it is also the most complicated.
79//!
80//! [using a function]: bevy_math::curve::FunctionCurve
81//! [translation component of a `Transform`]: bevy_transform::prelude::Transform::translation
82//! [`AnimationClip`]: crate::AnimationClip
83//! [there]: AnimatableProperty
84//! [`animated_field`]: crate::animated_field
85
86use core::{
87    any::{Any, TypeId},
88    fmt::{self, Debug, Formatter},
89    marker::PhantomData,
90};
91
92#[cfg(feature = "bevy_mesh")]
93pub use crate::morph::*;
94use crate::{
95    graph::AnimationNodeIndex,
96    prelude::{Animatable, BlendInput},
97    AnimationEntityMut, AnimationEvaluationError,
98};
99use bevy_ecs::component::{Component, Mutable};
100use bevy_math::curve::{
101    cores::{UnevenCore, UnevenCoreError},
102    Curve, Interval,
103};
104use bevy_platform::hash::Hashed;
105use bevy_reflect::{FromReflect, Reflect, Reflectable, TypeInfo, Typed};
106use downcast_rs::{impl_downcast, Downcast};
107
108/// A trait for exposing a value in an entity so that it can be animated.
109///
110/// `AnimatableProperty` allows any value contained in an entity to be animated
111/// as long as it can be obtained by mutable reference. This makes it more
112/// flexible than [`animated_field`].
113///
114/// [`animated_field`]: crate::animated_field
115///
116/// Here, `AnimatableProperty` is used to animate a value inside an `Option`,
117/// returning an error if the option is `None`.
118///
119///     # use bevy_animation::{prelude::AnimatableProperty, AnimationEntityMut, AnimationEvaluationError, animation_curves::EvaluatorId};
120///     # use bevy_ecs::component::Component;
121///     # use std::any::TypeId;
122///     #[derive(Component)]
123///     struct ExampleComponent {
124///         power_level: Option<f32>
125///     }
126///
127///     #[derive(Clone)]
128///     struct PowerLevelProperty;
129///
130///     impl AnimatableProperty for PowerLevelProperty {
131///         type Property = f32;
132///         fn get_mut<'a>(
133///             &self,
134///             entity: &'a mut AnimationEntityMut
135///         ) -> Result<&'a mut Self::Property, AnimationEvaluationError> {
136///             let component = entity
137///                 .get_mut::<ExampleComponent>()
138///                 .ok_or(AnimationEvaluationError::ComponentNotPresent(
139///                   TypeId::of::<ExampleComponent>()
140///                 ))?
141///                 .into_inner();
142///             component.power_level.as_mut().ok_or(AnimationEvaluationError::PropertyNotPresent(
143///                 TypeId::of::<Option<f32>>()
144///             ))
145///         }
146///
147///         fn evaluator_id(&self) -> EvaluatorId {
148///             EvaluatorId::Type(TypeId::of::<Self>())
149///         }
150///     }
151///
152///
153/// You can then create an [`AnimatableCurve`] to animate this property like so:
154///
155///     # use bevy_animation::{VariableCurve, AnimationEntityMut, AnimationEvaluationError, animation_curves::EvaluatorId};
156///     # use bevy_animation::prelude::{AnimatableProperty, AnimatableKeyframeCurve, AnimatableCurve};
157///     # use bevy_ecs::{name::Name, component::Component};
158///     # use std::any::TypeId;
159///     # #[derive(Component)]
160///     # struct ExampleComponent { power_level: Option<f32> }
161///     # #[derive(Clone)]
162///     # struct PowerLevelProperty;
163///     # impl AnimatableProperty for PowerLevelProperty {
164///     #     type Property = f32;
165///     #     fn get_mut<'a>(
166///     #         &self,
167///     #         entity: &'a mut AnimationEntityMut
168///     #     ) -> Result<&'a mut Self::Property, AnimationEvaluationError> {
169///     #         let component = entity
170///     #             .get_mut::<ExampleComponent>()
171///     #             .ok_or(AnimationEvaluationError::ComponentNotPresent(
172///     #               TypeId::of::<ExampleComponent>()
173///     #             ))?
174///     #             .into_inner();
175///     #         component.power_level.as_mut().ok_or(AnimationEvaluationError::PropertyNotPresent(
176///     #             TypeId::of::<Option<f32>>()
177///     #         ))
178///     #     }
179///     #     fn evaluator_id(&self) -> EvaluatorId {
180///     #         EvaluatorId::Type(TypeId::of::<Self>())
181///     #     }
182///     # }
183///     AnimatableCurve::new(
184///         PowerLevelProperty,
185///         AnimatableKeyframeCurve::new([
186///             (0.0, 0.0),
187///             (1.0, 9001.0),
188///         ]).expect("Failed to create power level curve")
189///     );
190pub trait AnimatableProperty: Send + Sync + 'static {
191    /// The animated property type.
192    type Property: Animatable;
193
194    /// Retrieves the property from the given `entity`.
195    fn get_mut<'a>(
196        &self,
197        entity: &'a mut AnimationEntityMut,
198    ) -> Result<&'a mut Self::Property, AnimationEvaluationError>;
199
200    /// The [`EvaluatorId`] used to look up the [`AnimationCurveEvaluator`] for this [`AnimatableProperty`].
201    /// For a given animated property, this ID should always be the same to allow things like animation blending to occur.
202    fn evaluator_id(&self) -> EvaluatorId<'_>;
203}
204
205/// A [`Component`] field that can be animated, defined by a function that reads the component and returns
206/// the accessed field / property.
207///
208/// The best way to create an instance of this type is via the [`animated_field`] macro.
209///
210/// `C` is the component being animated, `A` is the type of the [`Animatable`] field on the component, and `F` is an accessor
211/// function that accepts a reference to `C` and retrieves the field `A`.
212///
213/// [`animated_field`]: crate::animated_field
214#[derive(#[automatically_derived]
impl<C: ::core::clone::Clone, A: ::core::clone::Clone,
    F: ::core::clone::Clone + Fn(&mut C) -> &mut A> ::core::clone::Clone for
    AnimatedField<C, A, F> {
    #[inline]
    fn clone(&self) -> AnimatedField<C, A, F> {
        AnimatedField {
            func: ::core::clone::Clone::clone(&self.func),
            evaluator_id: ::core::clone::Clone::clone(&self.evaluator_id),
            marker: ::core::clone::Clone::clone(&self.marker),
        }
    }
}Clone)]
215pub struct AnimatedField<C, A, F: Fn(&mut C) -> &mut A> {
216    func: F,
217    /// A pre-hashed (component-type-id, reflected-field-index) pair, uniquely identifying a component field
218    evaluator_id: Hashed<(TypeId, usize)>,
219    marker: PhantomData<(C, A)>,
220}
221
222impl<C, A, F> AnimatableProperty for AnimatedField<C, A, F>
223where
224    C: Component<Mutability = Mutable>,
225    A: Animatable + Clone + Sync + Debug,
226    F: Fn(&mut C) -> &mut A + Send + Sync + 'static,
227{
228    type Property = A;
229    fn get_mut<'a>(
230        &self,
231        entity: &'a mut AnimationEntityMut,
232    ) -> Result<&'a mut A, AnimationEvaluationError> {
233        let c = entity
234            .get_mut::<C>()
235            .ok_or_else(|| AnimationEvaluationError::ComponentNotPresent(TypeId::of::<C>()))?;
236        Ok((self.func)(c.into_inner()))
237    }
238
239    fn evaluator_id(&self) -> EvaluatorId<'_> {
240        EvaluatorId::ComponentField(&self.evaluator_id)
241    }
242}
243
244impl<C: Typed, P, F: Fn(&mut C) -> &mut P + 'static> AnimatedField<C, P, F> {
245    /// Creates a new instance of [`AnimatedField`]. This operates under the assumption that
246    /// `C` is a reflect-able struct, and that `field_name` is a valid field on that struct.
247    ///
248    /// # Panics
249    /// If the type of `C` is not a struct or if the `field_name` does not exist.
250    pub fn new_unchecked(field_name: &str, func: F) -> Self {
251        let field_index;
252        if let TypeInfo::Struct(struct_info) = C::type_info() {
253            field_index = struct_info
254                .index_of(field_name)
255                .expect("Field name should exist");
256        } else if let TypeInfo::TupleStruct(struct_info) = C::type_info() {
257            field_index = field_name
258                .parse()
259                .expect("Field name should be a valid tuple index");
260            if field_index >= struct_info.field_len() {
261                {
    ::core::panicking::panic_fmt(format_args!("Field name should be a valid tuple index"));
};panic!("Field name should be a valid tuple index");
262            }
263        } else {
264            {
    ::core::panicking::panic_fmt(format_args!("Only structs are supported in `AnimatedField::new_unchecked`"));
}panic!("Only structs are supported in `AnimatedField::new_unchecked`")
265        }
266
267        Self {
268            func,
269            evaluator_id: Hashed::new((TypeId::of::<C>(), field_index)),
270            marker: PhantomData,
271        }
272    }
273}
274
275/// This trait collects the additional requirements on top of [`Curve<T>`] needed for a
276/// curve to be used as an [`AnimationCurve`].
277pub trait AnimationCompatibleCurve<T>: Curve<T> + Debug + Clone + Reflectable {}
278
279impl<T, C> AnimationCompatibleCurve<T> for C where C: Curve<T> + Debug + Clone + Reflectable {}
280
281/// This type allows the conversion of a [curve] valued in the [property type] of an
282/// [`AnimatableProperty`] into an [`AnimationCurve`] which animates that property.
283///
284/// [curve]: Curve
285/// [property type]: AnimatableProperty::Property
286#[derive(const _: () =
    {
        impl<P, C> bevy_reflect::GetTypeRegistration for AnimatableCurve<P, C>
            where AnimatableCurve<P, C>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            P: bevy_reflect::TypePath, C: bevy_reflect::TypePath,
            P: bevy_reflect::PartialReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            C: bevy_reflect::PartialReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <P as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
                <C as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl<P, C> bevy_reflect::Typed for AnimatableCurve<P, C> where
            AnimatableCurve<P, C>: ::core::any::Any + ::core::marker::Send +
            ::core::marker::Sync, P: bevy_reflect::TypePath,
            C: bevy_reflect::TypePath, P: bevy_reflect::PartialReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            C: bevy_reflect::PartialReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::GenericTypeInfoCell =
                    bevy_reflect::utility::GenericTypeInfoCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<P>("property"),
                                                    bevy_reflect::NamedField::new::<C>("curve")]).with_generics(bevy_reflect::Generics::from_iter([bevy_reflect::GenericInfo::Type(bevy_reflect::TypeParamInfo::new::<P>(bevy_reflect::__macro_exports::alloc_utils::Cow::Borrowed("P"))),
                                                bevy_reflect::GenericInfo::Type(bevy_reflect::TypeParamInfo::new::<C>(bevy_reflect::__macro_exports::alloc_utils::Cow::Borrowed("C")))])))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl<P, C> bevy_reflect::TypePath for AnimatableCurve<P, C> where
            AnimatableCurve<P, C>: ::core::any::Any + ::core::marker::Send +
            ::core::marker::Sync, P: bevy_reflect::TypePath,
            C: bevy_reflect::TypePath {
            fn type_path() -> &'static str {
                static CELL: bevy_reflect::utility::GenericTypePathCell =
                    bevy_reflect::utility::GenericTypePathCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            ::core::ops::Add::<&str>::add(::core::ops::Add::<&str>::add(bevy_reflect::__macro_exports::alloc_utils::ToString::to_string("bevy_animation::animation_curves::AnimatableCurve<"),
                                    &::core::ops::Add::<&str>::add(::core::ops::Add::<&str>::add(bevy_reflect::__macro_exports::alloc_utils::ToString::to_string(<P
                                                            as bevy_reflect::TypePath>::type_path()), ", "),
                                            <C as bevy_reflect::TypePath>::type_path())), ">")
                        })
            }
            fn short_type_path() -> &'static str {
                static CELL: bevy_reflect::utility::GenericTypePathCell =
                    bevy_reflect::utility::GenericTypePathCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            ::core::ops::Add::<&str>::add(::core::ops::Add::<&str>::add(bevy_reflect::__macro_exports::alloc_utils::ToString::to_string("AnimatableCurve<"),
                                    &::core::ops::Add::<&str>::add(::core::ops::Add::<&str>::add(bevy_reflect::__macro_exports::alloc_utils::ToString::to_string(<P
                                                            as bevy_reflect::TypePath>::short_type_path()), ", "),
                                            <C as bevy_reflect::TypePath>::short_type_path())), ">")
                        })
            }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("AnimatableCurve")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_animation::animation_curves".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_animation::animation_curves")
            }
        }
        impl<P, C> bevy_reflect::Reflect for AnimatableCurve<P, C> where
            AnimatableCurve<P, C>: ::core::any::Any + ::core::marker::Send +
            ::core::marker::Sync, P: bevy_reflect::TypePath,
            C: bevy_reflect::TypePath, P: bevy_reflect::PartialReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            C: bevy_reflect::PartialReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        impl<P, C> bevy_reflect::structs::Struct for AnimatableCurve<P, C>
            where AnimatableCurve<P, C>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            P: bevy_reflect::TypePath, C: bevy_reflect::TypePath,
            P: bevy_reflect::PartialReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            C: bevy_reflect::PartialReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "property" => ::core::option::Option::Some(&self.property),
                    "curve" => ::core::option::Option::Some(&self.curve),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "property" =>
                        ::core::option::Option::Some(&mut self.property),
                    "curve" => ::core::option::Option::Some(&mut self.curve),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.property),
                    1usize => ::core::option::Option::Some(&self.curve),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.property),
                    1usize => ::core::option::Option::Some(&mut self.curve),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("property"),
                    1usize => ::core::option::Option::Some("curve"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "property" => ::core::option::Option::Some(0usize),
                    "curve" => ::core::option::Option::Some(1usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 2usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                -> bevy_reflect::structs::DynamicStruct {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("property",
                    bevy_reflect::PartialReflect::to_dynamic(&self.property));
                dynamic.insert_boxed("curve",
                    bevy_reflect::PartialReflect::to_dynamic(&self.curve));
                dynamic
            }
        }
        impl<P, C> bevy_reflect::PartialReflect for AnimatableCurve<P, C>
            where AnimatableCurve<P, C>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            P: bevy_reflect::TypePath, C: bevy_reflect::TypePath,
            P: bevy_reflect::PartialReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            C: bevy_reflect::PartialReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(Self {
                            property: <P as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.property)?,
                            curve: <C as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.curve)?,
                        }))
            }
        }
    };Reflect, const _: () =
    {
        impl<P, C> bevy_reflect::FromReflect for AnimatableCurve<P, C> where
            AnimatableCurve<P, C>: ::core::any::Any + ::core::marker::Send +
            ::core::marker::Sync, P: bevy_reflect::TypePath,
            C: bevy_reflect::TypePath, P: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            C: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            property: <P as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "property")?)?,
                            curve: <C as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "curve")?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };FromReflect)]
287#[reflect(from_reflect = false)]
288pub struct AnimatableCurve<P, C> {
289    /// The property selector, which defines what component to access and how to access
290    /// a property on that component.
291    pub property: P,
292
293    /// The inner [curve] whose values are used to animate the property.
294    ///
295    /// [curve]: Curve
296    pub curve: C,
297}
298
299/// An [`AnimatableCurveEvaluator`] for [`AnimatableProperty`] instances.
300///
301/// You shouldn't ordinarily need to instantiate one of these manually. Bevy
302/// will automatically do so when you use an [`AnimatableCurve`] instance.
303#[derive(const _: () =
    {
        impl<A: Animatable> bevy_reflect::GetTypeRegistration for
            AnimatableCurveEvaluator<A> where
            AnimatableCurveEvaluator<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            A: bevy_reflect::TypePath,
            BasicAnimationCurveEvaluator<A>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            Box<dyn AnimatableProperty<Property =
            A>>: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <BasicAnimationCurveEvaluator<A> as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
                <Box<dyn AnimatableProperty<Property = A>> as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl<A: Animatable> bevy_reflect::Typed for
            AnimatableCurveEvaluator<A> where
            AnimatableCurveEvaluator<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            A: bevy_reflect::TypePath,
            BasicAnimationCurveEvaluator<A>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            Box<dyn AnimatableProperty<Property =
            A>>: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::GenericTypeInfoCell =
                    bevy_reflect::utility::GenericTypeInfoCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<BasicAnimationCurveEvaluator<A>>("evaluator"),
                                                    bevy_reflect::NamedField::new::<Box<dyn AnimatableProperty<Property
                                                            =
                                                            A>>>("property")]).with_generics(bevy_reflect::Generics::from_iter([bevy_reflect::GenericInfo::Type(bevy_reflect::TypeParamInfo::new::<A>(bevy_reflect::__macro_exports::alloc_utils::Cow::Borrowed("A")))])))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl<A: Animatable> bevy_reflect::TypePath for
            AnimatableCurveEvaluator<A> where
            AnimatableCurveEvaluator<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            A: bevy_reflect::TypePath {
            fn type_path() -> &'static str {
                static CELL: bevy_reflect::utility::GenericTypePathCell =
                    bevy_reflect::utility::GenericTypePathCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            ::core::ops::Add::<&str>::add(::core::ops::Add::<&str>::add(bevy_reflect::__macro_exports::alloc_utils::ToString::to_string("bevy_animation::animation_curves::AnimatableCurveEvaluator<"),
                                    <A as bevy_reflect::TypePath>::type_path()), ">")
                        })
            }
            fn short_type_path() -> &'static str {
                static CELL: bevy_reflect::utility::GenericTypePathCell =
                    bevy_reflect::utility::GenericTypePathCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            ::core::ops::Add::<&str>::add(::core::ops::Add::<&str>::add(bevy_reflect::__macro_exports::alloc_utils::ToString::to_string("AnimatableCurveEvaluator<"),
                                    <A as bevy_reflect::TypePath>::short_type_path()), ">")
                        })
            }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("AnimatableCurveEvaluator")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_animation::animation_curves".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_animation::animation_curves")
            }
        }
        impl<A: Animatable> bevy_reflect::Reflect for
            AnimatableCurveEvaluator<A> where
            AnimatableCurveEvaluator<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            A: bevy_reflect::TypePath,
            BasicAnimationCurveEvaluator<A>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            Box<dyn AnimatableProperty<Property =
            A>>: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        impl<A: Animatable> bevy_reflect::structs::Struct for
            AnimatableCurveEvaluator<A> where
            AnimatableCurveEvaluator<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            A: bevy_reflect::TypePath,
            BasicAnimationCurveEvaluator<A>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            Box<dyn AnimatableProperty<Property =
            A>>: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "evaluator" =>
                        ::core::option::Option::Some(&self.evaluator),
                    "property" => ::core::option::Option::Some(&self.property),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "evaluator" =>
                        ::core::option::Option::Some(&mut self.evaluator),
                    "property" =>
                        ::core::option::Option::Some(&mut self.property),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.evaluator),
                    1usize => ::core::option::Option::Some(&self.property),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.evaluator),
                    1usize => ::core::option::Option::Some(&mut self.property),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("evaluator"),
                    1usize => ::core::option::Option::Some("property"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "evaluator" => ::core::option::Option::Some(0usize),
                    "property" => ::core::option::Option::Some(1usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 2usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                -> bevy_reflect::structs::DynamicStruct {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("evaluator",
                    bevy_reflect::PartialReflect::to_dynamic(&self.evaluator));
                dynamic.insert_boxed("property",
                    bevy_reflect::PartialReflect::to_dynamic(&self.property));
                dynamic
            }
        }
        impl<A: Animatable> bevy_reflect::PartialReflect for
            AnimatableCurveEvaluator<A> where
            AnimatableCurveEvaluator<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            A: bevy_reflect::TypePath,
            BasicAnimationCurveEvaluator<A>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            Box<dyn AnimatableProperty<Property =
            A>>: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(Self {
                            evaluator: <BasicAnimationCurveEvaluator<A> as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.evaluator)?,
                            property: <Box<dyn AnimatableProperty<Property = A>> as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.property)?,
                        }))
            }
        }
        impl<A: Animatable> bevy_reflect::FromReflect for
            AnimatableCurveEvaluator<A> where
            AnimatableCurveEvaluator<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            A: bevy_reflect::TypePath,
            BasicAnimationCurveEvaluator<A>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            Box<dyn AnimatableProperty<Property =
            A>>: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            evaluator: <BasicAnimationCurveEvaluator<A> as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "evaluator")?)?,
                            property: <Box<dyn AnimatableProperty<Property = A>> as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "property")?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect)]
304pub struct AnimatableCurveEvaluator<A: Animatable> {
305    evaluator: BasicAnimationCurveEvaluator<A>,
306    property: Box<dyn AnimatableProperty<Property = A>>,
307}
308
309impl<P, C> AnimatableCurve<P, C>
310where
311    P: AnimatableProperty,
312    C: AnimationCompatibleCurve<P::Property>,
313{
314    /// Create an [`AnimatableCurve`] (and thus an [`AnimationCurve`]) from a curve
315    /// valued in an [animatable property].
316    ///
317    /// [animatable property]: AnimatableProperty::Property
318    pub fn new(property: P, curve: C) -> Self {
319        Self { property, curve }
320    }
321}
322
323impl<P, C> Clone for AnimatableCurve<P, C>
324where
325    C: Clone,
326    P: Clone,
327{
328    fn clone(&self) -> Self {
329        Self {
330            curve: self.curve.clone(),
331            property: self.property.clone(),
332        }
333    }
334}
335
336impl<P, C> Debug for AnimatableCurve<P, C>
337where
338    C: Debug,
339{
340    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
341        f.debug_struct("AnimatableCurve")
342            .field("curve", &self.curve)
343            .finish()
344    }
345}
346
347impl<P: Send + Sync + 'static, C> AnimationCurve for AnimatableCurve<P, C>
348where
349    P: AnimatableProperty + Clone,
350    C: AnimationCompatibleCurve<P::Property> + Clone,
351{
352    fn clone_value(&self) -> Box<dyn AnimationCurve> {
353        Box::new(self.clone())
354    }
355
356    fn domain(&self) -> Interval {
357        self.curve.domain()
358    }
359
360    fn evaluator_id(&self) -> EvaluatorId<'_> {
361        self.property.evaluator_id()
362    }
363
364    fn create_evaluator(&self) -> Box<dyn AnimationCurveEvaluator> {
365        Box::new(AnimatableCurveEvaluator::<P::Property> {
366            evaluator: BasicAnimationCurveEvaluator::default(),
367            property: Box::new(self.property.clone()),
368        })
369    }
370
371    fn apply(
372        &self,
373        curve_evaluator: &mut dyn AnimationCurveEvaluator,
374        t: f32,
375        weight: f32,
376        graph_node: AnimationNodeIndex,
377    ) -> Result<(), AnimationEvaluationError> {
378        let curve_evaluator = curve_evaluator
379            .downcast_mut::<AnimatableCurveEvaluator<P::Property>>()
380            .unwrap();
381        let value = self.curve.sample_clamped(t);
382        curve_evaluator
383            .evaluator
384            .stack
385            .push(BasicAnimationCurveEvaluatorStackElement {
386                value,
387                weight,
388                graph_node,
389            });
390        Ok(())
391    }
392
393    fn sample_clamped(&self, t: f32) -> Box<dyn Any> {
394        let value = self.curve.sample_clamped(t);
395        Box::new(value)
396    }
397}
398
399impl<A: Animatable> AnimationCurveEvaluator for AnimatableCurveEvaluator<A> {
400    fn blend(&mut self, graph_node: AnimationNodeIndex) -> Result<(), AnimationEvaluationError> {
401        self.evaluator.combine(graph_node, /*additive=*/ false)
402    }
403
404    fn add(&mut self, graph_node: AnimationNodeIndex) -> Result<(), AnimationEvaluationError> {
405        self.evaluator.combine(graph_node, /*additive=*/ true)
406    }
407
408    fn push_blend_register(
409        &mut self,
410        weight: f32,
411        graph_node: AnimationNodeIndex,
412    ) -> Result<(), AnimationEvaluationError> {
413        self.evaluator.push_blend_register(weight, graph_node)
414    }
415
416    fn commit(&mut self, mut entity: AnimationEntityMut) -> Result<(), AnimationEvaluationError> {
417        let property = self.property.get_mut(&mut entity)?;
418        *property = self
419            .evaluator
420            .stack
421            .pop()
422            .ok_or_else(inconsistent::<AnimatableCurveEvaluator<A>>)?
423            .value;
424        self.evaluator.stack.clear();
425        Ok(())
426    }
427}
428
429#[derive(const _: () =
    {
        impl<A> bevy_reflect::GetTypeRegistration for
            BasicAnimationCurveEvaluator<A> where
            BasicAnimationCurveEvaluator<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync, A: Animatable,
            A: bevy_reflect::TypePath,
            Vec<BasicAnimationCurveEvaluatorStackElement<A>>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            Option<(A, f32)>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <Vec<BasicAnimationCurveEvaluatorStackElement<A>> as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
                <Option<(A, f32)> as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl<A> bevy_reflect::Typed for BasicAnimationCurveEvaluator<A> where
            BasicAnimationCurveEvaluator<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync, A: Animatable,
            A: bevy_reflect::TypePath,
            Vec<BasicAnimationCurveEvaluatorStackElement<A>>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            Option<(A, f32)>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::GenericTypeInfoCell =
                    bevy_reflect::utility::GenericTypeInfoCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<Vec<BasicAnimationCurveEvaluatorStackElement<A>>>("stack"),
                                                    bevy_reflect::NamedField::new::<Option<(A,
                                                            f32)>>("blend_register")]).with_generics(bevy_reflect::Generics::from_iter([bevy_reflect::GenericInfo::Type(bevy_reflect::TypeParamInfo::new::<A>(bevy_reflect::__macro_exports::alloc_utils::Cow::Borrowed("A")))])))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl<A> bevy_reflect::TypePath for BasicAnimationCurveEvaluator<A>
            where BasicAnimationCurveEvaluator<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync, A: Animatable,
            A: bevy_reflect::TypePath {
            fn type_path() -> &'static str {
                static CELL: bevy_reflect::utility::GenericTypePathCell =
                    bevy_reflect::utility::GenericTypePathCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            ::core::ops::Add::<&str>::add(::core::ops::Add::<&str>::add(bevy_reflect::__macro_exports::alloc_utils::ToString::to_string("bevy_animation::animation_curves::BasicAnimationCurveEvaluator<"),
                                    <A as bevy_reflect::TypePath>::type_path()), ">")
                        })
            }
            fn short_type_path() -> &'static str {
                static CELL: bevy_reflect::utility::GenericTypePathCell =
                    bevy_reflect::utility::GenericTypePathCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            ::core::ops::Add::<&str>::add(::core::ops::Add::<&str>::add(bevy_reflect::__macro_exports::alloc_utils::ToString::to_string("BasicAnimationCurveEvaluator<"),
                                    <A as bevy_reflect::TypePath>::short_type_path()), ">")
                        })
            }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("BasicAnimationCurveEvaluator")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_animation::animation_curves".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_animation::animation_curves")
            }
        }
        impl<A> bevy_reflect::Reflect for BasicAnimationCurveEvaluator<A>
            where BasicAnimationCurveEvaluator<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync, A: Animatable,
            A: bevy_reflect::TypePath,
            Vec<BasicAnimationCurveEvaluatorStackElement<A>>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            Option<(A, f32)>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        impl<A> bevy_reflect::structs::Struct for
            BasicAnimationCurveEvaluator<A> where
            BasicAnimationCurveEvaluator<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync, A: Animatable,
            A: bevy_reflect::TypePath,
            Vec<BasicAnimationCurveEvaluatorStackElement<A>>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            Option<(A, f32)>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "stack" => ::core::option::Option::Some(&self.stack),
                    "blend_register" =>
                        ::core::option::Option::Some(&self.blend_register),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "stack" => ::core::option::Option::Some(&mut self.stack),
                    "blend_register" =>
                        ::core::option::Option::Some(&mut self.blend_register),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.stack),
                    1usize =>
                        ::core::option::Option::Some(&self.blend_register),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.stack),
                    1usize =>
                        ::core::option::Option::Some(&mut self.blend_register),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("stack"),
                    1usize => ::core::option::Option::Some("blend_register"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "stack" => ::core::option::Option::Some(0usize),
                    "blend_register" => ::core::option::Option::Some(1usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 2usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                -> bevy_reflect::structs::DynamicStruct {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("stack",
                    bevy_reflect::PartialReflect::to_dynamic(&self.stack));
                dynamic.insert_boxed("blend_register",
                    bevy_reflect::PartialReflect::to_dynamic(&self.blend_register));
                dynamic
            }
        }
        impl<A> bevy_reflect::PartialReflect for
            BasicAnimationCurveEvaluator<A> where
            BasicAnimationCurveEvaluator<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync, A: Animatable,
            A: bevy_reflect::TypePath,
            Vec<BasicAnimationCurveEvaluatorStackElement<A>>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            Option<(A, f32)>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(Self {
                            stack: <Vec<BasicAnimationCurveEvaluatorStackElement<A>> as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.stack)?,
                            blend_register: <Option<(A, f32)> as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.blend_register)?,
                        }))
            }
        }
        impl<A> bevy_reflect::FromReflect for BasicAnimationCurveEvaluator<A>
            where BasicAnimationCurveEvaluator<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync, A: Animatable,
            A: bevy_reflect::TypePath,
            Vec<BasicAnimationCurveEvaluatorStackElement<A>>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            Option<(A, f32)>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            stack: <Vec<BasicAnimationCurveEvaluatorStackElement<A>> as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "stack")?)?,
                            blend_register: <Option<(A, f32)> as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "blend_register")?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect)]
430struct BasicAnimationCurveEvaluator<A>
431where
432    A: Animatable,
433{
434    stack: Vec<BasicAnimationCurveEvaluatorStackElement<A>>,
435    blend_register: Option<(A, f32)>,
436}
437
438#[derive(const _: () =
    {
        impl<A> bevy_reflect::GetTypeRegistration for
            BasicAnimationCurveEvaluatorStackElement<A> where
            BasicAnimationCurveEvaluatorStackElement<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync, A: Animatable,
            A: bevy_reflect::TypePath, A: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <A as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
                <f32 as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
                <AnimationNodeIndex as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl<A> bevy_reflect::Typed for
            BasicAnimationCurveEvaluatorStackElement<A> where
            BasicAnimationCurveEvaluatorStackElement<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync, A: Animatable,
            A: bevy_reflect::TypePath, A: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::GenericTypeInfoCell =
                    bevy_reflect::utility::GenericTypeInfoCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<A>("value"),
                                                    bevy_reflect::NamedField::new::<f32>("weight"),
                                                    bevy_reflect::NamedField::new::<AnimationNodeIndex>("graph_node")]).with_generics(bevy_reflect::Generics::from_iter([bevy_reflect::GenericInfo::Type(bevy_reflect::TypeParamInfo::new::<A>(bevy_reflect::__macro_exports::alloc_utils::Cow::Borrowed("A")))])))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl<A> bevy_reflect::TypePath for
            BasicAnimationCurveEvaluatorStackElement<A> where
            BasicAnimationCurveEvaluatorStackElement<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync, A: Animatable,
            A: bevy_reflect::TypePath {
            fn type_path() -> &'static str {
                static CELL: bevy_reflect::utility::GenericTypePathCell =
                    bevy_reflect::utility::GenericTypePathCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            ::core::ops::Add::<&str>::add(::core::ops::Add::<&str>::add(bevy_reflect::__macro_exports::alloc_utils::ToString::to_string("bevy_animation::animation_curves::BasicAnimationCurveEvaluatorStackElement<"),
                                    <A as bevy_reflect::TypePath>::type_path()), ">")
                        })
            }
            fn short_type_path() -> &'static str {
                static CELL: bevy_reflect::utility::GenericTypePathCell =
                    bevy_reflect::utility::GenericTypePathCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            ::core::ops::Add::<&str>::add(::core::ops::Add::<&str>::add(bevy_reflect::__macro_exports::alloc_utils::ToString::to_string("BasicAnimationCurveEvaluatorStackElement<"),
                                    <A as bevy_reflect::TypePath>::short_type_path()), ">")
                        })
            }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("BasicAnimationCurveEvaluatorStackElement")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_animation::animation_curves".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_animation::animation_curves")
            }
        }
        impl<A> bevy_reflect::Reflect for
            BasicAnimationCurveEvaluatorStackElement<A> where
            BasicAnimationCurveEvaluatorStackElement<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync, A: Animatable,
            A: bevy_reflect::TypePath, A: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        impl<A> bevy_reflect::structs::Struct for
            BasicAnimationCurveEvaluatorStackElement<A> where
            BasicAnimationCurveEvaluatorStackElement<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync, A: Animatable,
            A: bevy_reflect::TypePath, A: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "value" => ::core::option::Option::Some(&self.value),
                    "weight" => ::core::option::Option::Some(&self.weight),
                    "graph_node" =>
                        ::core::option::Option::Some(&self.graph_node),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "value" => ::core::option::Option::Some(&mut self.value),
                    "weight" => ::core::option::Option::Some(&mut self.weight),
                    "graph_node" =>
                        ::core::option::Option::Some(&mut self.graph_node),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.value),
                    1usize => ::core::option::Option::Some(&self.weight),
                    2usize => ::core::option::Option::Some(&self.graph_node),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.value),
                    1usize => ::core::option::Option::Some(&mut self.weight),
                    2usize =>
                        ::core::option::Option::Some(&mut self.graph_node),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("value"),
                    1usize => ::core::option::Option::Some("weight"),
                    2usize => ::core::option::Option::Some("graph_node"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "value" => ::core::option::Option::Some(0usize),
                    "weight" => ::core::option::Option::Some(1usize),
                    "graph_node" => ::core::option::Option::Some(2usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 3usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                -> bevy_reflect::structs::DynamicStruct {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("value",
                    bevy_reflect::PartialReflect::to_dynamic(&self.value));
                dynamic.insert_boxed("weight",
                    bevy_reflect::PartialReflect::to_dynamic(&self.weight));
                dynamic.insert_boxed("graph_node",
                    bevy_reflect::PartialReflect::to_dynamic(&self.graph_node));
                dynamic
            }
        }
        impl<A> bevy_reflect::PartialReflect for
            BasicAnimationCurveEvaluatorStackElement<A> where
            BasicAnimationCurveEvaluatorStackElement<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync, A: Animatable,
            A: bevy_reflect::TypePath, A: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(Self {
                            value: <A as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.value)?,
                            weight: <f32 as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.weight)?,
                            graph_node: <AnimationNodeIndex as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.graph_node)?,
                        }))
            }
        }
        impl<A> bevy_reflect::FromReflect for
            BasicAnimationCurveEvaluatorStackElement<A> where
            BasicAnimationCurveEvaluatorStackElement<A>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync, A: Animatable,
            A: bevy_reflect::TypePath, A: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            value: <A as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "value")?)?,
                            weight: <f32 as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "weight")?)?,
                            graph_node: <AnimationNodeIndex as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "graph_node")?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect)]
439struct BasicAnimationCurveEvaluatorStackElement<A>
440where
441    A: Animatable,
442{
443    value: A,
444    weight: f32,
445    graph_node: AnimationNodeIndex,
446}
447
448impl<A> Default for BasicAnimationCurveEvaluator<A>
449where
450    A: Animatable,
451{
452    fn default() -> Self {
453        BasicAnimationCurveEvaluator {
454            stack: ::alloc::vec::Vec::new()vec![],
455            blend_register: None,
456        }
457    }
458}
459
460impl<A> BasicAnimationCurveEvaluator<A>
461where
462    A: Animatable,
463{
464    fn combine(
465        &mut self,
466        graph_node: AnimationNodeIndex,
467        additive: bool,
468    ) -> Result<(), AnimationEvaluationError> {
469        let Some(top) = self.stack.last() else {
470            return Ok(());
471        };
472        if top.graph_node != graph_node {
473            return Ok(());
474        }
475
476        let BasicAnimationCurveEvaluatorStackElement {
477            value: value_to_blend,
478            weight: weight_to_blend,
479            graph_node: _,
480        } = self.stack.pop().unwrap();
481
482        match self.blend_register.take() {
483            None => {
484                self.initialize_blend_register(value_to_blend, weight_to_blend, additive);
485            }
486            Some((mut current_value, mut current_weight)) => {
487                current_weight += weight_to_blend;
488
489                if additive {
490                    current_value = A::blend(
491                        [
492                            BlendInput {
493                                weight: 1.0,
494                                value: current_value,
495                                additive: true,
496                            },
497                            BlendInput {
498                                weight: weight_to_blend,
499                                value: value_to_blend,
500                                additive: true,
501                            },
502                        ]
503                        .into_iter(),
504                    );
505                } else {
506                    current_value = A::interpolate(
507                        &current_value,
508                        &value_to_blend,
509                        weight_to_blend / current_weight,
510                    );
511                }
512
513                self.blend_register = Some((current_value, current_weight));
514            }
515        }
516
517        Ok(())
518    }
519
520    fn initialize_blend_register(&mut self, value: A, weight: f32, additive: bool) {
521        if additive {
522            let scaled_value = A::blend(
523                [BlendInput {
524                    weight,
525                    value,
526                    additive: true,
527                }]
528                .into_iter(),
529            );
530            self.blend_register = Some((scaled_value, weight));
531        } else {
532            self.blend_register = Some((value, weight));
533        }
534    }
535
536    fn push_blend_register(
537        &mut self,
538        weight: f32,
539        graph_node: AnimationNodeIndex,
540    ) -> Result<(), AnimationEvaluationError> {
541        if let Some((value, _)) = self.blend_register.take() {
542            self.stack.push(BasicAnimationCurveEvaluatorStackElement {
543                value,
544                weight,
545                graph_node,
546            });
547        }
548        Ok(())
549    }
550}
551
552/// A low-level trait that provides control over how curves are actually applied
553/// to entities by the animation system.
554///
555/// Typically, this will not need to be implemented manually, since it is
556/// automatically implemented by [`AnimatableCurve`] and other curves used by
557/// the animation system (e.g. those that animate parts of transforms or morph
558/// weights). However, this can be implemented manually when `AnimatableCurve`
559/// is not sufficiently expressive.
560///
561/// In many respects, this behaves like a type-erased form of [`Curve`], where
562/// the output type of the curve is remembered only in the components that are
563/// mutated in the implementation of [`apply`].
564///
565/// [`apply`]: AnimationCurve::apply
566pub trait AnimationCurve: Debug + Send + Sync + 'static {
567    /// Returns a boxed clone of this value.
568    fn clone_value(&self) -> Box<dyn AnimationCurve>;
569
570    /// The range of times for which this animation is defined.
571    fn domain(&self) -> Interval;
572
573    /// Returns the type ID of the [`AnimationCurveEvaluator`].
574    ///
575    /// This must match the type returned by [`Self::create_evaluator`]. It must
576    /// be a single type that doesn't depend on the type of the curve.
577    fn evaluator_id(&self) -> EvaluatorId<'_>;
578
579    /// Returns a newly-instantiated [`AnimationCurveEvaluator`] for use with
580    /// this curve.
581    ///
582    /// All curve types must return the same type of
583    /// [`AnimationCurveEvaluator`]. The returned value must match the type
584    /// returned by [`Self::evaluator_id`].
585    fn create_evaluator(&self) -> Box<dyn AnimationCurveEvaluator>;
586
587    /// Samples the curve at the given time `t`, and pushes the sampled value
588    /// onto the evaluation stack of the `curve_evaluator`.
589    ///
590    /// The `curve_evaluator` parameter points to the value returned by
591    /// [`Self::create_evaluator`], upcast to an `&mut dyn
592    /// AnimationCurveEvaluator`. Typically, implementations of [`Self::apply`]
593    /// will want to downcast the `curve_evaluator` parameter to the concrete
594    /// type [`Self::evaluator_id`] in order to push values of the appropriate
595    /// type onto its evaluation stack.
596    ///
597    /// Be sure not to confuse the `t` and `weight` values. The former
598    /// determines the position at which the *curve* is sampled, while `weight`
599    /// ultimately determines how much the *stack values* will be blended
600    /// together (see the definition of [`AnimationCurveEvaluator::blend`]).
601    fn apply(
602        &self,
603        curve_evaluator: &mut dyn AnimationCurveEvaluator,
604        t: f32,
605        weight: f32,
606        graph_node: AnimationNodeIndex,
607    ) -> Result<(), AnimationEvaluationError>;
608
609    /// Samples the curve at the given time `t` and returns a Boxed value.
610    fn sample_clamped(&self, t: f32) -> Box<dyn Any>;
611}
612
613/// The [`EvaluatorId`] is used to look up the [`AnimationCurveEvaluator`] for an [`AnimatableProperty`].
614/// For a given animated property, this ID should always be the same to allow things like animation blending to occur.
615#[derive(#[automatically_derived]
impl<'a> ::core::clone::Clone for EvaluatorId<'a> {
    #[inline]
    fn clone(&self) -> EvaluatorId<'a> {
        match self {
            EvaluatorId::ComponentField(__self_0) =>
                EvaluatorId::ComponentField(::core::clone::Clone::clone(__self_0)),
            EvaluatorId::Type(__self_0) =>
                EvaluatorId::Type(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone, #[automatically_derived]
impl<'a> ::core::cmp::PartialEq for EvaluatorId<'a> {
    #[inline]
    fn eq(&self, other: &EvaluatorId<'a>) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (EvaluatorId::ComponentField(__self_0),
                    EvaluatorId::ComponentField(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (EvaluatorId::Type(__self_0), EvaluatorId::Type(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl<'a> ::core::cmp::Eq for EvaluatorId<'a> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<&'a Hashed<(TypeId, usize)>>;
        let _: ::core::cmp::AssertParamIsEq<TypeId>;
    }
}Eq)]
616pub enum EvaluatorId<'a> {
617    /// Corresponds to a specific field on a specific component type.
618    /// The `TypeId` should correspond to the component type, and the `usize`
619    /// should correspond to the Reflect-ed field index of the field.
620    //
621    // IMPLEMENTATION NOTE: The Hashed<(TypeId, usize) is intentionally cheap to clone, as it will be cloned per frame by the evaluator
622    // Switching the field index `usize` for something like a field name `String` would probably be too expensive to justify
623    ComponentField(&'a Hashed<(TypeId, usize)>),
624    /// Corresponds to a custom property of a given type. This should be the [`TypeId`]
625    /// of the custom [`AnimatableProperty`].
626    Type(TypeId),
627}
628
629/// A low-level trait for use in [`VariableCurve`](`crate::VariableCurve`) that provides fine
630/// control over how animations are evaluated.
631///
632/// You can implement this trait when the generic [`AnimatableCurveEvaluator`]
633/// isn't sufficiently-expressive for your needs. For example, `MorphWeights`
634/// implements this trait instead of using [`AnimatableCurveEvaluator`] because
635/// it needs to animate arbitrarily many weights at once, which can't be done
636/// with [`Animatable`] as that works on fixed-size values only.
637///
638/// If you implement this trait, you should also implement [`AnimationCurve`] on
639/// your curve type, as that trait allows creating instances of this one.
640///
641/// Implementations of [`AnimatableCurveEvaluator`] should maintain a *stack* of
642/// (value, weight, node index) triples, as well as a *blend register*, which is
643/// either a (value, weight) pair or empty. *Value* here refers to an instance
644/// of the value being animated: for example, [`Vec3`] in the case of
645/// translation keyframes.  The stack stores intermediate values generated while
646/// evaluating the [`AnimationGraph`](`crate::graph::AnimationGraph`), while the blend register
647/// stores the result of a blend operation.
648///
649/// [`Vec3`]: bevy_math::Vec3
650pub trait AnimationCurveEvaluator: Downcast + Send + Sync + 'static {
651    /// Blends the top element of the stack with the blend register.
652    ///
653    /// The semantics of this method are as follows:
654    ///
655    /// 1. Pop the top element of the stack. Call its value vₘ and its weight
656    ///    wₘ. If the stack was empty, return success.
657    ///
658    /// 2. If the blend register is empty, set the blend register value to vₘ
659    ///    and the blend register weight to wₘ; then, return success.
660    ///
661    /// 3. If the blend register is nonempty, call its current value vₙ and its
662    ///    current weight wₙ. Then, set the value of the blend register to
663    ///    `interpolate(vₙ, vₘ, wₘ / (wₘ + wₙ))`, and set the weight of the blend
664    ///    register to wₘ + wₙ.
665    ///
666    /// 4. Return success.
667    fn blend(&mut self, graph_node: AnimationNodeIndex) -> Result<(), AnimationEvaluationError>;
668
669    /// Additively blends the top element of the stack with the blend register.
670    ///
671    /// The semantics of this method are as follows:
672    ///
673    /// 1. Pop the top element of the stack. Call its value vₘ and its weight
674    ///    wₘ. If the stack was empty, return success.
675    ///
676    /// 2. If the blend register is empty, set the blend register value to vₘ
677    ///    and the blend register weight to wₘ; then, return success.
678    ///
679    /// 3. If the blend register is nonempty, call its current value vₙ.
680    ///    Then, set the value of the blend register to vₙ + vₘwₘ.
681    ///
682    /// 4. Return success.
683    fn add(&mut self, graph_node: AnimationNodeIndex) -> Result<(), AnimationEvaluationError>;
684
685    /// Pushes the current value of the blend register onto the stack.
686    ///
687    /// If the blend register is empty, this method does nothing successfully.
688    /// Otherwise, this method pushes the current value of the blend register
689    /// onto the stack, alongside the weight and graph node supplied to this
690    /// function. The weight present in the blend register is discarded; only
691    /// the weight parameter to this function is pushed onto the stack. The
692    /// blend register is emptied after this process.
693    fn push_blend_register(
694        &mut self,
695        weight: f32,
696        graph_node: AnimationNodeIndex,
697    ) -> Result<(), AnimationEvaluationError>;
698
699    /// Pops the top value off the stack and writes it into the appropriate
700    /// component.
701    ///
702    /// If the stack is empty, this method does nothing successfully. Otherwise,
703    /// it pops the top value off the stack, fetches the associated component
704    /// from either the `transform` or `entity` values as appropriate, and
705    /// updates the appropriate property with the value popped from the stack.
706    /// The weight and node index associated with the popped stack element are
707    /// discarded. After doing this, the stack is emptied.
708    ///
709    /// The property on the component must be overwritten with the value from
710    /// the stack, not blended with it.
711    fn commit(&mut self, entity: AnimationEntityMut) -> Result<(), AnimationEvaluationError>;
712}
713
714impl dyn AnimationCurveEvaluator<> {
    /// Returns true if the trait object wraps an object of type `__T`.
    #[inline]
    pub fn is<__T: AnimationCurveEvaluator<>>(&self) -> bool {
        ::downcast_rs::Downcast::as_any(self).is::<__T>()
    }
    /// Returns a boxed object from a boxed trait object if the underlying object is of type
    /// `__T`. Returns the original boxed trait if it isn't.
    #[inline]
    pub fn downcast<__T: AnimationCurveEvaluator<>>(self:
            ::downcast_rs::__alloc::boxed::Box<Self>)
        ->
            ::downcast_rs::__std::result::Result<::downcast_rs::__alloc::boxed::Box<__T>,
            ::downcast_rs::__alloc::boxed::Box<Self>> {
        if self.is::<__T>() {
            Ok(::downcast_rs::Downcast::into_any(self).downcast::<__T>().unwrap())
        } else { Err(self) }
    }
    /// Returns an `Rc`-ed object from an `Rc`-ed trait object if the underlying object is of
    /// type `__T`. Returns the original `Rc`-ed trait if it isn't.
    #[inline]
    pub fn downcast_rc<__T: AnimationCurveEvaluator<>>(self:
            ::downcast_rs::__alloc::rc::Rc<Self>)
        ->
            ::downcast_rs::__std::result::Result<::downcast_rs::__alloc::rc::Rc<__T>,
            ::downcast_rs::__alloc::rc::Rc<Self>> {
        if self.is::<__T>() {
            Ok(::downcast_rs::Downcast::into_any_rc(self).downcast::<__T>().unwrap())
        } else { Err(self) }
    }
    /// Returns a reference to the object within the trait object if it is of type `__T`, or
    /// `None` if it isn't.
    #[inline]
    pub fn downcast_ref<__T: AnimationCurveEvaluator<>>(&self)
        -> ::downcast_rs::__std::option::Option<&__T> {
        ::downcast_rs::Downcast::as_any(self).downcast_ref::<__T>()
    }
    /// Returns a mutable reference to the object within the trait object if it is of type
    /// `__T`, or `None` if it isn't.
    #[inline]
    pub fn downcast_mut<__T: AnimationCurveEvaluator<>>(&mut self)
        -> ::downcast_rs::__std::option::Option<&mut __T> {
        ::downcast_rs::Downcast::as_any_mut(self).downcast_mut::<__T>()
    }
}impl_downcast!(AnimationCurveEvaluator);
715
716/// A [curve] defined by keyframes with values in an [animatable] type.
717///
718/// The keyframes are interpolated using the type's [`Animatable::interpolate`] implementation.
719///
720/// [curve]: Curve
721/// [animatable]: Animatable
722#[derive(#[automatically_derived]
impl<T: ::core::fmt::Debug> ::core::fmt::Debug for AnimatableKeyframeCurve<T>
    {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f,
            "AnimatableKeyframeCurve", "core", &&self.core)
    }
}Debug, #[automatically_derived]
impl<T: ::core::clone::Clone> ::core::clone::Clone for
    AnimatableKeyframeCurve<T> {
    #[inline]
    fn clone(&self) -> AnimatableKeyframeCurve<T> {
        AnimatableKeyframeCurve {
            core: ::core::clone::Clone::clone(&self.core),
        }
    }
}Clone, const _: () =
    {
        impl<T> bevy_reflect::GetTypeRegistration for
            AnimatableKeyframeCurve<T> where
            AnimatableKeyframeCurve<T>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            T: bevy_reflect::TypePath,
            UnevenCore<T>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <UnevenCore<T> as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl<T> bevy_reflect::Typed for AnimatableKeyframeCurve<T> where
            AnimatableKeyframeCurve<T>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            T: bevy_reflect::TypePath,
            UnevenCore<T>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::GenericTypeInfoCell =
                    bevy_reflect::utility::GenericTypeInfoCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<UnevenCore<T>>("core")]).with_generics(bevy_reflect::Generics::from_iter([bevy_reflect::GenericInfo::Type(bevy_reflect::TypeParamInfo::new::<T>(bevy_reflect::__macro_exports::alloc_utils::Cow::Borrowed("T")))])))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl<T> bevy_reflect::TypePath for AnimatableKeyframeCurve<T> where
            AnimatableKeyframeCurve<T>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            T: bevy_reflect::TypePath {
            fn type_path() -> &'static str {
                static CELL: bevy_reflect::utility::GenericTypePathCell =
                    bevy_reflect::utility::GenericTypePathCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            ::core::ops::Add::<&str>::add(::core::ops::Add::<&str>::add(bevy_reflect::__macro_exports::alloc_utils::ToString::to_string("bevy_animation::animation_curves::AnimatableKeyframeCurve<"),
                                    <T as bevy_reflect::TypePath>::type_path()), ">")
                        })
            }
            fn short_type_path() -> &'static str {
                static CELL: bevy_reflect::utility::GenericTypePathCell =
                    bevy_reflect::utility::GenericTypePathCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            ::core::ops::Add::<&str>::add(::core::ops::Add::<&str>::add(bevy_reflect::__macro_exports::alloc_utils::ToString::to_string("AnimatableKeyframeCurve<"),
                                    <T as bevy_reflect::TypePath>::short_type_path()), ">")
                        })
            }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("AnimatableKeyframeCurve")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_animation::animation_curves".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_animation::animation_curves")
            }
        }
        impl<T> bevy_reflect::Reflect for AnimatableKeyframeCurve<T> where
            AnimatableKeyframeCurve<T>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            T: bevy_reflect::TypePath,
            UnevenCore<T>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        impl<T> bevy_reflect::structs::Struct for AnimatableKeyframeCurve<T>
            where AnimatableKeyframeCurve<T>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            T: bevy_reflect::TypePath,
            UnevenCore<T>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "core" => ::core::option::Option::Some(&self.core),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "core" => ::core::option::Option::Some(&mut self.core),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.core),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.core),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("core"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "core" => ::core::option::Option::Some(0usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 1usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                -> bevy_reflect::structs::DynamicStruct {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("core",
                    bevy_reflect::PartialReflect::to_dynamic(&self.core));
                dynamic
            }
        }
        impl<T> bevy_reflect::PartialReflect for AnimatableKeyframeCurve<T>
            where AnimatableKeyframeCurve<T>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            T: bevy_reflect::TypePath,
            UnevenCore<T>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(Self {
                            core: <UnevenCore<T> as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.core)?,
                        }))
            }
        }
        impl<T> bevy_reflect::FromReflect for AnimatableKeyframeCurve<T> where
            AnimatableKeyframeCurve<T>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            T: bevy_reflect::TypePath,
            UnevenCore<T>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            core: <UnevenCore<T> as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "core")?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect)]
723pub struct AnimatableKeyframeCurve<T> {
724    core: UnevenCore<T>,
725}
726
727impl<T> Curve<T> for AnimatableKeyframeCurve<T>
728where
729    T: Animatable + Clone,
730{
731    #[inline]
732    fn domain(&self) -> Interval {
733        self.core.domain()
734    }
735
736    #[inline]
737    fn sample_clamped(&self, t: f32) -> T {
738        // `UnevenCore::sample_with` is implicitly clamped.
739        self.core.sample_with(t, <T as Animatable>::interpolate)
740    }
741
742    #[inline]
743    fn sample_unchecked(&self, t: f32) -> T {
744        self.sample_clamped(t)
745    }
746}
747
748impl<T> AnimatableKeyframeCurve<T>
749where
750    T: Animatable,
751{
752    /// Create a new [`AnimatableKeyframeCurve`] from the given `keyframes`. The values of this
753    /// curve are interpolated from the keyframes using the output type's implementation of
754    /// [`Animatable::interpolate`].
755    ///
756    /// There must be at least two samples in order for this method to succeed.
757    pub fn new(keyframes: impl IntoIterator<Item = (f32, T)>) -> Result<Self, UnevenCoreError> {
758        Ok(Self {
759            core: UnevenCore::new(keyframes)?,
760        })
761    }
762}
763
764fn inconsistent<P>() -> AnimationEvaluationError
765where
766    P: 'static + ?Sized,
767{
768    AnimationEvaluationError::InconsistentEvaluatorImplementation(TypeId::of::<P>())
769}
770
771/// Returns an [`AnimatedField`] with a given `$component` and `$field`.
772///
773/// This can be used in the following way:
774///
775/// ```
776/// # use bevy_animation::{animation_curves::AnimatedField, animated_field};
777/// # use bevy_color::Srgba;
778/// # use bevy_ecs::component::Component;
779/// # use bevy_math::Vec3;
780/// # use bevy_reflect::Reflect;
781/// #[derive(Component, Reflect)]
782/// struct Transform {
783///     translation: Vec3,
784/// }
785///
786/// let field = animated_field!(Transform::translation);
787///
788/// #[derive(Component, Reflect)]
789/// struct Color(Srgba);
790///
791/// let tuple_field = animated_field!(Color::0);
792/// ```
793#[macro_export]
794macro_rules! animated_field {
795    ($component:ident::$field:tt) => {
796        AnimatedField::new_unchecked(stringify!($field), |component: &mut $component| {
797            &mut component.$field
798        })
799    };
800}
801
802#[cfg(test)]
803mod tests {
804    use super::*;
805    use crate::VariableCurve;
806    use bevy_math::Vec3;
807    use bevy_transform::components::Transform;
808
809    #[test]
810    fn test_animated_field_tuple_struct_simple_uses() {
811        #[derive(Clone, Debug, Component, Reflect)]
812        struct A(f32);
813        let _ = AnimatedField::new_unchecked("0", |a: &mut A| &mut a.0);
814
815        #[derive(Clone, Debug, Component, Reflect)]
816        struct B(f32, f64, f32);
817        let _ = AnimatedField::new_unchecked("0", |b: &mut B| &mut b.0);
818        let _ = AnimatedField::new_unchecked("1", |b: &mut B| &mut b.1);
819        let _ = AnimatedField::new_unchecked("2", |b: &mut B| &mut b.2);
820    }
821
822    #[test]
823    fn test_sample_animation_curve() {
824        let variable_curve = VariableCurve::new(AnimatableCurve::new(
825            animated_field!(Transform::translation),
826            AnimatableKeyframeCurve::new([
827                (0.0, Vec3::new(0., 0., 1.)),
828                (1.0, Vec3::new(1., 0., 0.)),
829            ])
830            .expect("Failed to create power level curve"),
831        ));
832        let value = variable_curve
833            .0
834            .sample_clamped(0.)
835            .downcast::<Vec3>()
836            .unwrap();
837        assert_eq!(*value, Vec3::new(0., 0., 1.));
838        let value = variable_curve
839            .0
840            .sample_clamped(1.)
841            .downcast::<Vec3>()
842            .unwrap();
843        assert_eq!(*value, Vec3::new(1., 0., 0.));
844    }
845}