Fixing Curve trait not being object safe. (#14939)
# Objective
- `Curve<T>` was meant to be object safe, but one of the latest commits
made it not object safe.
- When trying to use `Curve<T>` as `&dyn Curve<T>` this compile error is
raised:
```
error[E0038]: the trait `curve::Curve` cannot be made into an object
    --> crates/bevy_math/src/curve/mod.rs:1025:20
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
    --> crates/bevy_math/src/curve/mod.rs:60:8
     |
23   | pub trait Curve<T> {
     |           ----- this trait cannot be made into an object...
...
60   |     fn sample_iter(&self, iter: impl IntoIterator<Item = f32>) -> impl Iterator<Item = Option<T>> {
     |        ^^^^^^^^^^^                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because method `sample_iter` references an `impl Trait` type in its return type
     |        |
     |        ...because method `sample_iter` has generic type parameters
...
```
## Solution
- Making `Curve<T>` object safe again by adding `Self: Sized` to newly
added methods.
## Testing
- Added new test that ensures the `Curve<T>` trait can be made into an
objet.
			
			
This commit is contained in:
		
							parent
							
								
									e320fa0738
								
							
						
					
					
						commit
						1690b28e9f
					
				| @ -57,7 +57,10 @@ pub trait Curve<T> { | |||||||
|     /// The samples are returned in the same order as the parameter values `t_n` were provided and
 |     /// The samples are returned in the same order as the parameter values `t_n` were provided and
 | ||||||
|     /// will include all results. This leaves the responsibility for things like filtering and
 |     /// will include all results. This leaves the responsibility for things like filtering and
 | ||||||
|     /// sorting to the user for maximum flexibility.
 |     /// sorting to the user for maximum flexibility.
 | ||||||
|     fn sample_iter(&self, iter: impl IntoIterator<Item = f32>) -> impl Iterator<Item = Option<T>> { |     fn sample_iter(&self, iter: impl IntoIterator<Item = f32>) -> impl Iterator<Item = Option<T>> | ||||||
|  |     where | ||||||
|  |         Self: Sized, | ||||||
|  |     { | ||||||
|         iter.into_iter().map(|t| self.sample(t)) |         iter.into_iter().map(|t| self.sample(t)) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -72,10 +75,10 @@ pub trait Curve<T> { | |||||||
|     /// The samples are returned in the same order as the parameter values `t_n` were provided and
 |     /// The samples are returned in the same order as the parameter values `t_n` were provided and
 | ||||||
|     /// will include all results. This leaves the responsibility for things like filtering and
 |     /// will include all results. This leaves the responsibility for things like filtering and
 | ||||||
|     /// sorting to the user for maximum flexibility.
 |     /// sorting to the user for maximum flexibility.
 | ||||||
|     fn sample_iter_unchecked( |     fn sample_iter_unchecked(&self, iter: impl IntoIterator<Item = f32>) -> impl Iterator<Item = T> | ||||||
|         &self, |     where | ||||||
|         iter: impl IntoIterator<Item = f32>, |         Self: Sized, | ||||||
|     ) -> impl Iterator<Item = T> { |     { | ||||||
|         iter.into_iter().map(|t| self.sample_unchecked(t)) |         iter.into_iter().map(|t| self.sample_unchecked(t)) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -85,7 +88,10 @@ pub trait Curve<T> { | |||||||
|     /// The samples are returned in the same order as the parameter values `t_n` were provided and
 |     /// The samples are returned in the same order as the parameter values `t_n` were provided and
 | ||||||
|     /// will include all results. This leaves the responsibility for things like filtering and
 |     /// will include all results. This leaves the responsibility for things like filtering and
 | ||||||
|     /// sorting to the user for maximum flexibility.
 |     /// sorting to the user for maximum flexibility.
 | ||||||
|     fn sample_iter_clamped(&self, iter: impl IntoIterator<Item = f32>) -> impl Iterator<Item = T> { |     fn sample_iter_clamped(&self, iter: impl IntoIterator<Item = f32>) -> impl Iterator<Item = T> | ||||||
|  |     where | ||||||
|  |         Self: Sized, | ||||||
|  |     { | ||||||
|         iter.into_iter().map(|t| self.sample_clamped(t)) |         iter.into_iter().map(|t| self.sample_clamped(t)) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -760,6 +766,9 @@ where | |||||||
| /// must be left-finite.
 | /// must be left-finite.
 | ||||||
| ///
 | ///
 | ||||||
| /// Curves of this type are produced by [`Curve::chain`].
 | /// Curves of this type are produced by [`Curve::chain`].
 | ||||||
|  | #[derive(Clone, Debug)] | ||||||
|  | #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] | ||||||
|  | #[cfg_attr(feature = "bevy_reflect", derive(Reflect))] | ||||||
| pub struct ChainCurve<T, C, D> { | pub struct ChainCurve<T, C, D> { | ||||||
|     first: C, |     first: C, | ||||||
|     second: D, |     second: D, | ||||||
| @ -1013,6 +1022,15 @@ mod tests { | |||||||
|     use approx::{assert_abs_diff_eq, AbsDiffEq}; |     use approx::{assert_abs_diff_eq, AbsDiffEq}; | ||||||
|     use std::f32::consts::TAU; |     use std::f32::consts::TAU; | ||||||
| 
 | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn curve_can_be_made_into_an_object() { | ||||||
|  |         let curve = constant_curve(Interval::UNIT, 42.0); | ||||||
|  |         let curve: &dyn Curve<f64> = &curve; | ||||||
|  | 
 | ||||||
|  |         assert_eq!(curve.sample(1.0), Some(42.0)); | ||||||
|  |         assert_eq!(curve.sample(2.0), None); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     #[test] |     #[test] | ||||||
|     fn constant_curves() { |     fn constant_curves() { | ||||||
|         let curve = constant_curve(Interval::EVERYWHERE, 5.0); |         let curve = constant_curve(Interval::EVERYWHERE, 5.0); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Erick Z
						Erick Z