@@ -45,60 +45,52 @@ pub struct TweenCompleted {
4545#[ derive( Debug , Default , Clone , Copy ) ]
4646struct AnimClock {
4747 elapsed : Duration ,
48- total : Duration ,
48+ duration : Duration ,
4949 is_looping : bool ,
5050}
5151
5252impl AnimClock {
5353 fn new ( duration : Duration , is_looping : bool ) -> Self {
5454 AnimClock {
5555 elapsed : Duration :: ZERO ,
56- total : duration,
56+ duration,
5757 is_looping,
5858 }
5959 }
6060
61- #[ allow( dead_code) ] // TEMP
62- fn elapsed ( & self ) -> Duration {
63- self . elapsed
64- }
61+ fn tick ( & mut self , duration : Duration ) -> u32 {
62+ self . elapsed = self . elapsed . saturating_add ( duration) ;
6563
66- fn total ( & self ) -> Duration {
67- self . total
68- }
64+ if self . elapsed < self . duration {
65+ 0
66+ } else if self . is_looping {
67+ let elapsed = self . elapsed . as_nanos ( ) ;
68+ let duration = self . duration . as_nanos ( ) ;
6969
70- fn tick ( & mut self , duration : Duration ) -> u32 {
71- let new_elapsed = self . elapsed . saturating_add ( duration) ;
72- let progress = new_elapsed. as_secs_f64 ( ) / self . total . as_secs_f64 ( ) ;
73- let times_completed = progress as u32 ;
74- let progress = if self . is_looping {
75- progress. fract ( )
70+ self . elapsed = Duration :: from_nanos ( ( elapsed % duration) as u64 ) ;
71+ ( elapsed / duration) as u32
7672 } else {
77- progress. min ( 1. )
78- } ;
79- self . elapsed = self . total . mul_f64 ( progress) ;
80- times_completed
73+ self . elapsed = self . duration ;
74+ 1
75+ }
8176 }
8277
83- fn set_progress ( & mut self , progress : f32 ) -> u32 {
84- let progress = progress. max ( 0. ) ;
85- let times_completed = progress as u32 ;
78+ fn set_progress ( & mut self , progress : f32 ) {
8679 let progress = if self . is_looping {
87- progress. fract ( )
80+ progress. max ( 0. ) . fract ( )
8881 } else {
89- progress. min ( 1. )
82+ progress. clamp ( 0. , 1. )
9083 } ;
91- self . elapsed = self . total . mul_f32 ( progress ) ;
92- times_completed
84+
85+ self . elapsed = self . duration . mul_f32 ( progress ) ;
9386 }
9487
9588 fn progress ( & self ) -> f32 {
96- //self.elapsed.div_duration_f32(self.total) // TODO: unstable
97- ( self . elapsed . as_secs_f64 ( ) / self . total . as_secs_f64 ( ) ) as f32
89+ self . elapsed . as_secs_f32 ( ) / self . duration . as_secs_f32 ( )
9890 }
9991
10092 fn completed ( & self ) -> bool {
101- self . elapsed >= self . total
93+ self . elapsed >= self . duration
10294 }
10395
10496 fn reset ( & mut self ) {
@@ -408,7 +400,7 @@ impl<T> Tween<T> {
408400
409401impl < T > Tweenable < T > for Tween < T > {
410402 fn duration ( & self ) -> Duration {
411- self . clock . total ( )
403+ self . clock . duration
412404 }
413405
414406 fn is_looping ( & self ) -> bool {
@@ -808,6 +800,36 @@ mod tests {
808800 last_reported_count : u32 ,
809801 }
810802
803+ #[ test]
804+ fn anim_clock_precision ( ) {
805+ let duration = Duration :: from_millis ( 1 ) ;
806+ let mut clock = AnimClock :: new ( duration, true ) ;
807+
808+ let test_ticks = [
809+ Duration :: from_micros ( 123 ) ,
810+ Duration :: from_millis ( 1 ) ,
811+ Duration :: from_secs_f32 ( 1. / 24. ) ,
812+ Duration :: from_secs_f32 ( 1. / 30. ) ,
813+ Duration :: from_secs_f32 ( 1. / 60. ) ,
814+ Duration :: from_secs_f32 ( 1. / 120. ) ,
815+ Duration :: from_secs_f32 ( 1. / 144. ) ,
816+ Duration :: from_secs_f32 ( 1. / 240. ) ,
817+ ] ;
818+
819+ let mut times_completed = 0 ;
820+ let mut total_duration = Duration :: ZERO ;
821+ for i in 0 ..10_000_000 {
822+ let tick = test_ticks[ i % test_ticks. len ( ) ] ;
823+ times_completed += clock. tick ( tick) ;
824+ total_duration += tick;
825+ }
826+
827+ assert_eq ! (
828+ ( total_duration. as_secs_f64( ) / duration. as_secs_f64( ) ) as u32 ,
829+ times_completed
830+ ) ;
831+ }
832+
811833 /// Test ticking of a single tween in isolation.
812834 #[ test]
813835 fn tween_tick ( ) {
0 commit comments