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