Curves: FromReflect boogaloo part 2 (#15714)

# Objective

Allow curve adaptors to be reliably `Reflect` even if the curves they
hold are not `FromReflect`. This allows them, for example, to be used in
`bevy_animation`. I previously addressed this with the functional
adaptors, but I forgot to address this in the case of fields that hold
other curves and not arbitrary functions.

## Solution

Do the following on every curve adaptor that holds another curve:
```rust
// old:
#[derive(Reflect)]
```

```rust
// new:
#[derive(Reflect, FromReflect)]
#[reflect(from_reflect = false)]
```

This looks inane, but it's necessary because the default
`#[derive(Reflect)]` macro places `FromReflect` bounds on everything. To
avoid this, we opt out of deriving `FromReflect` with that macro by
adding `#[reflect(from_reflect = false)]`, then separately derive
`FromReflect`. (Of course, the latter still has the `FromReflect`
bounds, which is fine.)
This commit is contained in:
Matty 2024-10-07 18:59:17 -04:00 committed by GitHub
parent bef44d7ac2
commit 9b863be2fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 52 additions and 12 deletions

View file

@ -9,7 +9,7 @@ use core::fmt::{self, Debug};
use core::marker::PhantomData; use core::marker::PhantomData;
#[cfg(feature = "bevy_reflect")] #[cfg(feature = "bevy_reflect")]
use bevy_reflect::{utility::GenericTypePathCell, Reflect, TypePath}; use bevy_reflect::{utility::GenericTypePathCell, FromReflect, Reflect, TypePath};
#[cfg(feature = "bevy_reflect")] #[cfg(feature = "bevy_reflect")]
mod paths { mod paths {
@ -368,7 +368,7 @@ where
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "bevy_reflect", feature = "bevy_reflect",
derive(Reflect), derive(Reflect, FromReflect),
reflect(from_reflect = false) reflect(from_reflect = false)
)] )]
pub struct LinearReparamCurve<T, C> { pub struct LinearReparamCurve<T, C> {
@ -401,7 +401,11 @@ where
/// sample times before sampling. Curves of this type are produced by [`Curve::reparametrize_by_curve`]. /// sample times before sampling. Curves of this type are produced by [`Curve::reparametrize_by_curve`].
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))] #[cfg_attr(
feature = "bevy_reflect",
derive(Reflect, FromReflect),
reflect(from_reflect = false)
)]
pub struct CurveReparamCurve<T, C, D> { pub struct CurveReparamCurve<T, C, D> {
pub(crate) base: C, pub(crate) base: C,
pub(crate) reparam_curve: D, pub(crate) reparam_curve: D,
@ -430,7 +434,11 @@ where
/// produced by [`Curve::graph`]. /// produced by [`Curve::graph`].
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))] #[cfg_attr(
feature = "bevy_reflect",
derive(Reflect, FromReflect),
reflect(from_reflect = false)
)]
pub struct GraphCurve<T, C> { pub struct GraphCurve<T, C> {
pub(crate) base: C, pub(crate) base: C,
#[cfg_attr(feature = "bevy_reflect", reflect(ignore))] #[cfg_attr(feature = "bevy_reflect", reflect(ignore))]
@ -456,7 +464,11 @@ where
/// of this type are produced by [`Curve::zip`]. /// of this type are produced by [`Curve::zip`].
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))] #[cfg_attr(
feature = "bevy_reflect",
derive(Reflect, FromReflect),
reflect(from_reflect = false)
)]
pub struct ZipCurve<S, T, C, D> { pub struct ZipCurve<S, T, C, D> {
pub(crate) domain: Interval, pub(crate) domain: Interval,
pub(crate) first: C, pub(crate) first: C,
@ -493,7 +505,11 @@ where
/// Curves of this type are produced by [`Curve::chain`]. /// Curves of this type are produced by [`Curve::chain`].
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))] #[cfg_attr(
feature = "bevy_reflect",
derive(Reflect, FromReflect),
reflect(from_reflect = false)
)]
pub struct ChainCurve<T, C, D> { pub struct ChainCurve<T, C, D> {
pub(crate) first: C, pub(crate) first: C,
pub(crate) second: D, pub(crate) second: D,
@ -539,7 +555,11 @@ where
/// The original curve's domain must be bounded to get a valid [`ReverseCurve`]. /// The original curve's domain must be bounded to get a valid [`ReverseCurve`].
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))] #[cfg_attr(
feature = "bevy_reflect",
derive(Reflect, FromReflect),
reflect(from_reflect = false)
)]
pub struct ReverseCurve<T, C> { pub struct ReverseCurve<T, C> {
pub(crate) curve: C, pub(crate) curve: C,
#[cfg_attr(feature = "bevy_reflect", reflect(ignore))] #[cfg_attr(feature = "bevy_reflect", reflect(ignore))]
@ -576,7 +596,11 @@ where
/// The original curve's domain must be bounded to get a valid [`RepeatCurve`]. /// The original curve's domain must be bounded to get a valid [`RepeatCurve`].
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))] #[cfg_attr(
feature = "bevy_reflect",
derive(Reflect, FromReflect),
reflect(from_reflect = false)
)]
pub struct RepeatCurve<T, C> { pub struct RepeatCurve<T, C> {
pub(crate) domain: Interval, pub(crate) domain: Interval,
pub(crate) curve: C, pub(crate) curve: C,
@ -621,7 +645,11 @@ where
/// The original curve's domain must be bounded to get a valid [`ForeverCurve`]. /// The original curve's domain must be bounded to get a valid [`ForeverCurve`].
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))] #[cfg_attr(
feature = "bevy_reflect",
derive(Reflect, FromReflect),
reflect(from_reflect = false)
)]
pub struct ForeverCurve<T, C> { pub struct ForeverCurve<T, C> {
pub(crate) curve: C, pub(crate) curve: C,
#[cfg_attr(feature = "bevy_reflect", reflect(ignore))] #[cfg_attr(feature = "bevy_reflect", reflect(ignore))]
@ -661,7 +689,11 @@ where
/// The original curve's domain must be right-finite to get a valid [`PingPongCurve`]. /// The original curve's domain must be right-finite to get a valid [`PingPongCurve`].
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))] #[cfg_attr(
feature = "bevy_reflect",
derive(Reflect, FromReflect),
reflect(from_reflect = false)
)]
pub struct PingPongCurve<T, C> { pub struct PingPongCurve<T, C> {
pub(crate) curve: C, pub(crate) curve: C,
#[cfg_attr(feature = "bevy_reflect", reflect(ignore))] #[cfg_attr(feature = "bevy_reflect", reflect(ignore))]
@ -711,7 +743,11 @@ where
/// valid [`ContinuationCurve`]. /// valid [`ContinuationCurve`].
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))] #[cfg_attr(
feature = "bevy_reflect",
derive(Reflect, FromReflect),
reflect(from_reflect = false)
)]
pub struct ContinuationCurve<T, C, D> { pub struct ContinuationCurve<T, C, D> {
pub(crate) first: C, pub(crate) first: C,
pub(crate) second: D, pub(crate) second: D,

View file

@ -31,7 +31,11 @@ impl Easing<f32> for ElasticCurve {}
/// [unit interval]: `Interval::UNIT` /// [unit interval]: `Interval::UNIT`
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))] #[cfg_attr(
feature = "bevy_reflect",
derive(bevy_reflect::Reflect, bevy_reflect::FromReflect),
reflect(from_reflect = false)
)]
pub struct EasingCurve<T, E> pub struct EasingCurve<T, E>
where where
T: VectorSpace, T: VectorSpace,