Skip to content
Snippets Groups Projects
Unverified Commit 4c2f49da authored by Jerome Humbert's avatar Jerome Humbert Committed by GitHub
Browse files

Fix animator speed feature (#63)

Fix the animator speed applying, which got broken as part of the
refactor of #44.

Add a `speed()` getter to both `Animator<T>` and `AssetAnimator<T>`.

Add some simple test for speed, but this is not enough to make sure the
feature doesn't regress, so logged #62 to follow-up with a proper
regression test.

Fixes #61
parent a0c98056
No related branches found
No related tags found
No related merge requests found
...@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ...@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added `RepeatCount` and `RepeatStrategy` for more granular control over animation looping. - Added `RepeatCount` and `RepeatStrategy` for more granular control over animation looping.
- Added `with_repeat_count()` and `with_repeat_strategy()` builder methods to `Tween<T>`. - Added `with_repeat_count()` and `with_repeat_strategy()` builder methods to `Tween<T>`.
- Added a `speed()` getter on `Animator<T>` and `AssetAnimator<T>`.
### Changed ### Changed
...@@ -22,6 +23,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ...@@ -22,6 +23,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Removed `Tweenable::is_looping()`, which was not implemented for most tweenables. - Removed `Tweenable::is_looping()`, which was not implemented for most tweenables.
- Removed `TweeningType` in favor of `RepeatCount` and `RepeatStrategy`. - Removed `TweeningType` in favor of `RepeatCount` and `RepeatStrategy`.
### Fixed
- Fixed the animator speed feature, which got broken in #44.
## [0.5.0] - 2022-08-04 ## [0.5.0] - 2022-08-04
### Added ### Added
......
...@@ -361,6 +361,15 @@ macro_rules! animator_impl { ...@@ -361,6 +361,15 @@ macro_rules! animator_impl {
self.speed = speed; self.speed = speed;
} }
/// Get the animation speed.
///
/// See [`set_speed()`] for a definition of what the animation speed is.
///
/// [`set_speed()`]: Animator::speed
pub fn speed(&self) -> f32 {
self.speed
}
/// Set the top-level tweenable item this animator controls. /// Set the top-level tweenable item this animator controls.
pub fn set_tweenable(&mut self, tween: impl Tweenable<T> + Send + Sync + 'static) { pub fn set_tweenable(&mut self, tween: impl Tweenable<T> + Send + Sync + 'static) {
self.tweenable = Box::new(tween); self.tweenable = Box::new(tween);
...@@ -468,18 +477,23 @@ mod tests { ...@@ -468,18 +477,23 @@ mod tests {
use super::{lens::*, *}; use super::{lens::*, *};
/// Utility to compare floating-point values with a tolerance.
fn abs_diff_eq(a: f32, b: f32, tol: f32) -> bool {
(a - b).abs() < tol
}
struct DummyLens { struct DummyLens {
start: f32, start: f32,
end: f32, end: f32,
} }
#[derive(Component)] #[derive(Debug, Component)]
struct DummyComponent { struct DummyComponent {
value: f32, value: f32,
} }
#[cfg(feature = "bevy_asset")] #[cfg(feature = "bevy_asset")]
#[derive(Reflect, TypeUuid)] #[derive(Debug, Reflect, TypeUuid)]
#[uuid = "a33abc11-264e-4bbb-82e8-b87226bb4383"] #[uuid = "a33abc11-264e-4bbb-82e8-b87226bb4383"]
struct DummyAsset { struct DummyAsset {
value: f32, value: f32,
...@@ -574,6 +588,13 @@ mod tests { ...@@ -574,6 +588,13 @@ mod tests {
); );
let animator = Animator::new(tween).with_state(state); let animator = Animator::new(tween).with_state(state);
assert_eq!(animator.state, state); assert_eq!(animator.state, state);
// impl Debug
let debug_string = format!("{:?}", animator);
assert_eq!(
debug_string,
format!("Animator {{ state: {:?} }}", animator.state)
);
} }
} }
...@@ -614,6 +635,30 @@ mod tests { ...@@ -614,6 +635,30 @@ mod tests {
assert!(animator.tweenable().progress().abs() <= 1e-5); assert!(animator.tweenable().progress().abs() <= 1e-5);
} }
#[test]
fn animator_speed() {
let tween = Tween::<DummyComponent>::new(
EaseFunction::QuadraticInOut,
Duration::from_secs(1),
DummyLens { start: 0., end: 1. },
);
let mut animator = Animator::new(tween);
assert!(abs_diff_eq(animator.speed(), 1., 1e-5)); // default speed
animator.set_speed(2.4);
assert!(abs_diff_eq(animator.speed(), 2.4, 1e-5));
let tween = Tween::<DummyComponent>::new(
EaseFunction::QuadraticInOut,
Duration::from_secs(1),
DummyLens { start: 0., end: 1. },
);
let animator = Animator::new(tween).with_speed(3.5);
assert!(abs_diff_eq(animator.speed(), 3.5, 1e-5));
}
#[cfg(feature = "bevy_asset")] #[cfg(feature = "bevy_asset")]
#[test] #[test]
fn asset_animator_new() { fn asset_animator_new() {
...@@ -641,6 +686,13 @@ mod tests { ...@@ -641,6 +686,13 @@ mod tests {
let animator = let animator =
AssetAnimator::new(Handle::<DummyAsset>::default(), tween).with_state(state); AssetAnimator::new(Handle::<DummyAsset>::default(), tween).with_state(state);
assert_eq!(animator.state, state); assert_eq!(animator.state, state);
// impl Debug
let debug_string = format!("{:?}", animator);
assert_eq!(
debug_string,
format!("AssetAnimator {{ state: {:?} }}", animator.state)
);
} }
} }
...@@ -681,4 +733,29 @@ mod tests { ...@@ -681,4 +733,29 @@ mod tests {
assert_eq!(animator.state, AnimatorState::Paused); assert_eq!(animator.state, AnimatorState::Paused);
assert!(animator.tweenable().progress().abs() <= 1e-5); assert!(animator.tweenable().progress().abs() <= 1e-5);
} }
#[cfg(feature = "bevy_asset")]
#[test]
fn asset_animator_speed() {
let tween = Tween::new(
EaseFunction::QuadraticInOut,
Duration::from_secs(1),
DummyLens { start: 0., end: 1. },
);
let mut animator = AssetAnimator::new(Handle::<DummyAsset>::default(), tween);
assert!(abs_diff_eq(animator.speed(), 1., 1e-5)); // default speed
animator.set_speed(2.4);
assert!(abs_diff_eq(animator.speed(), 2.4, 1e-5));
let tween = Tween::new(
EaseFunction::QuadraticInOut,
Duration::from_secs(1),
DummyLens { start: 0., end: 1. },
);
let animator = AssetAnimator::new(Handle::<DummyAsset>::default(), tween).with_speed(3.5);
assert!(abs_diff_eq(animator.speed(), 3.5, 1e-5));
}
} }
...@@ -75,9 +75,13 @@ pub fn component_animator_system<T: Component>( ...@@ -75,9 +75,13 @@ pub fn component_animator_system<T: Component>(
) { ) {
for (entity, ref mut target, ref mut animator) in query.iter_mut() { for (entity, ref mut target, ref mut animator) in query.iter_mut() {
if animator.state != AnimatorState::Paused { if animator.state != AnimatorState::Paused {
animator let speed = animator.speed();
.tweenable_mut() animator.tweenable_mut().tick(
.tick(time.delta(), target, entity, &mut event_writer); time.delta().mul_f32(speed),
target,
entity,
&mut event_writer,
);
} }
} }
} }
...@@ -97,10 +101,14 @@ pub fn asset_animator_system<T: Asset>( ...@@ -97,10 +101,14 @@ pub fn asset_animator_system<T: Asset>(
) { ) {
for (entity, ref mut animator) in query.iter_mut() { for (entity, ref mut animator) in query.iter_mut() {
if animator.state != AnimatorState::Paused { if animator.state != AnimatorState::Paused {
let speed = animator.speed();
if let Some(target) = assets.get_mut(&animator.handle()) { if let Some(target) = assets.get_mut(&animator.handle()) {
animator animator.tweenable_mut().tick(
.tweenable_mut() time.delta().mul_f32(speed),
.tick(time.delta(), target, entity, &mut event_writer); target,
entity,
&mut event_writer,
);
} }
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment