Count number of times a repeating Timer wraps around in a tick (#1112)
Added just_finished_count() function
This commit is contained in:
		
							parent
							
								
									1e8060a5a2
								
							
						
					
					
						commit
						ac7d2de67c
					
				| @ -13,8 +13,8 @@ pub struct Timer { | |||||||
|     elapsed: f32, |     elapsed: f32, | ||||||
|     duration: f32, |     duration: f32, | ||||||
|     finished: bool, |     finished: bool, | ||||||
|     /// Will only be true on the tick `duration` is reached or exceeded.
 |     /// Will only be non-zero on the tick `duration` is reached or exceeded.
 | ||||||
|     just_finished: bool, |     just_finished_count: u32, | ||||||
|     paused: bool, |     paused: bool, | ||||||
|     repeating: bool, |     repeating: bool, | ||||||
| } | } | ||||||
| @ -51,7 +51,8 @@ impl Timer { | |||||||
|         self.paused |         self.paused | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Returns the time elapsed on the timer. Guaranteed to be between 0.0 and `duration`, inclusive.
 |     /// Returns the time elapsed on the timer. Guaranteed to be between 0.0 and `duration`.
 | ||||||
|  |     /// Will only equal `duration` when the timer is finished and non repeating.
 | ||||||
|     #[inline] |     #[inline] | ||||||
|     pub fn elapsed(&self) -> f32 { |     pub fn elapsed(&self) -> f32 { | ||||||
|         self.elapsed |         self.elapsed | ||||||
| @ -74,8 +75,9 @@ impl Timer { | |||||||
| 
 | 
 | ||||||
|     /// Returns the finished state of the timer.
 |     /// Returns the finished state of the timer.
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// Non repeating timers will stop tracking and stay in the finished state until reset.
 |     /// Non-repeating timers will stop tracking and stay in the finished state until reset.
 | ||||||
|     /// Repeating timers will only be in the finished state on each tick `duration` is reached or exceeded, and can still be reset at any given point.
 |     /// Repeating timers will only be in the finished state on each tick `duration` is reached or exceeded, so in that case
 | ||||||
|  |     /// this function is equivalent to `just_finished`.
 | ||||||
|     #[inline] |     #[inline] | ||||||
|     pub fn finished(&self) -> bool { |     pub fn finished(&self) -> bool { | ||||||
|         self.finished |         self.finished | ||||||
| @ -84,7 +86,16 @@ impl Timer { | |||||||
|     /// Will only be true on the tick the timer's duration is reached or exceeded.
 |     /// Will only be true on the tick the timer's duration is reached or exceeded.
 | ||||||
|     #[inline] |     #[inline] | ||||||
|     pub fn just_finished(&self) -> bool { |     pub fn just_finished(&self) -> bool { | ||||||
|         self.just_finished |         self.just_finished_count > 0 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /// Returns the total number of times the timer finished during this tick.
 | ||||||
|  |     ///
 | ||||||
|  |     /// This value can be used to ensure no completions of a repeating timer are skipped over due to a tick with an unexpectedly
 | ||||||
|  |     /// long delta time. For non repeating timers, the value will only ever be 0 or 1.
 | ||||||
|  |     #[inline] | ||||||
|  |     pub fn just_finished_count(&self) -> u32 { | ||||||
|  |         self.just_finished_count | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     #[inline] |     #[inline] | ||||||
| @ -92,8 +103,11 @@ impl Timer { | |||||||
|         self.repeating |         self.repeating | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     #[inline] |  | ||||||
|     pub fn set_repeating(&mut self, repeating: bool) { |     pub fn set_repeating(&mut self, repeating: bool) { | ||||||
|  |         if !self.repeating && repeating && self.finished { | ||||||
|  |             self.elapsed = 0.0; | ||||||
|  |             self.finished = self.just_finished(); | ||||||
|  |         } | ||||||
|         self.repeating = repeating |         self.repeating = repeating | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -102,20 +116,24 @@ impl Timer { | |||||||
|         if self.paused { |         if self.paused { | ||||||
|             return self; |             return self; | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|         let prev_finished = self.finished; |         let prev_finished = self.finished; | ||||||
|         self.elapsed += delta; |         self.elapsed += delta; | ||||||
| 
 |  | ||||||
|         self.finished = self.elapsed >= self.duration; |         self.finished = self.elapsed >= self.duration; | ||||||
|         self.just_finished = !prev_finished && self.finished; |  | ||||||
| 
 | 
 | ||||||
|         if self.finished { |         if self.finished { | ||||||
|             if self.repeating { |             if self.repeating { | ||||||
|  |                 // Count the number of times the timer will wrap around from this tick
 | ||||||
|  |                 self.just_finished_count = (self.elapsed / self.duration) as u32; | ||||||
|                 // Repeating timers wrap around
 |                 // Repeating timers wrap around
 | ||||||
|                 self.elapsed %= self.duration; |                 self.elapsed %= self.duration; | ||||||
|             } else { |             } else { | ||||||
|  |                 self.just_finished_count = if prev_finished { 0 } else { 1 }; | ||||||
|                 // Non-repeating timers clamp to duration
 |                 // Non-repeating timers clamp to duration
 | ||||||
|                 self.elapsed = self.duration; |                 self.elapsed = self.duration; | ||||||
|             } |             } | ||||||
|  |         } else { | ||||||
|  |             self.just_finished_count = 0; | ||||||
|         } |         } | ||||||
|         self |         self | ||||||
|     } |     } | ||||||
| @ -123,7 +141,7 @@ impl Timer { | |||||||
|     #[inline] |     #[inline] | ||||||
|     pub fn reset(&mut self) { |     pub fn reset(&mut self) { | ||||||
|         self.finished = false; |         self.finished = false; | ||||||
|         self.just_finished = false; |         self.just_finished_count = 0; | ||||||
|         self.elapsed = 0.0; |         self.elapsed = 0.0; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -151,6 +169,7 @@ mod tests { | |||||||
|         assert_eq!(t.duration(), 10.0); |         assert_eq!(t.duration(), 10.0); | ||||||
|         assert_eq!(t.finished(), false); |         assert_eq!(t.finished(), false); | ||||||
|         assert_eq!(t.just_finished(), false); |         assert_eq!(t.just_finished(), false); | ||||||
|  |         assert_eq!(t.just_finished_count(), 0); | ||||||
|         assert_eq!(t.repeating(), false); |         assert_eq!(t.repeating(), false); | ||||||
|         assert_eq!(t.percent(), 0.025); |         assert_eq!(t.percent(), 0.025); | ||||||
|         assert_eq!(t.percent_left(), 0.975); |         assert_eq!(t.percent_left(), 0.975); | ||||||
| @ -161,6 +180,7 @@ mod tests { | |||||||
|         assert_eq!(t.duration(), 10.0); |         assert_eq!(t.duration(), 10.0); | ||||||
|         assert_eq!(t.finished(), false); |         assert_eq!(t.finished(), false); | ||||||
|         assert_eq!(t.just_finished(), false); |         assert_eq!(t.just_finished(), false); | ||||||
|  |         assert_eq!(t.just_finished_count(), 0); | ||||||
|         assert_eq!(t.repeating(), false); |         assert_eq!(t.repeating(), false); | ||||||
|         assert_eq!(t.percent(), 0.025); |         assert_eq!(t.percent(), 0.025); | ||||||
|         assert_eq!(t.percent_left(), 0.975); |         assert_eq!(t.percent_left(), 0.975); | ||||||
| @ -170,6 +190,7 @@ mod tests { | |||||||
|         assert_eq!(t.elapsed(), 10.0); |         assert_eq!(t.elapsed(), 10.0); | ||||||
|         assert_eq!(t.finished(), true); |         assert_eq!(t.finished(), true); | ||||||
|         assert_eq!(t.just_finished(), true); |         assert_eq!(t.just_finished(), true); | ||||||
|  |         assert_eq!(t.just_finished_count(), 1); | ||||||
|         assert_eq!(t.percent(), 1.0); |         assert_eq!(t.percent(), 1.0); | ||||||
|         assert_eq!(t.percent_left(), 0.0); |         assert_eq!(t.percent_left(), 0.0); | ||||||
|         // Continuing to tick when finished should only change just_finished
 |         // Continuing to tick when finished should only change just_finished
 | ||||||
| @ -177,6 +198,7 @@ mod tests { | |||||||
|         assert_eq!(t.elapsed(), 10.0); |         assert_eq!(t.elapsed(), 10.0); | ||||||
|         assert_eq!(t.finished(), true); |         assert_eq!(t.finished(), true); | ||||||
|         assert_eq!(t.just_finished(), false); |         assert_eq!(t.just_finished(), false); | ||||||
|  |         assert_eq!(t.just_finished_count(), 0); | ||||||
|         assert_eq!(t.percent(), 1.0); |         assert_eq!(t.percent(), 1.0); | ||||||
|         assert_eq!(t.percent_left(), 0.0); |         assert_eq!(t.percent_left(), 0.0); | ||||||
|     } |     } | ||||||
| @ -190,14 +212,16 @@ mod tests { | |||||||
|         assert_eq!(t.duration(), 2.0); |         assert_eq!(t.duration(), 2.0); | ||||||
|         assert_eq!(t.finished(), false); |         assert_eq!(t.finished(), false); | ||||||
|         assert_eq!(t.just_finished(), false); |         assert_eq!(t.just_finished(), false); | ||||||
|  |         assert_eq!(t.just_finished_count(), 0); | ||||||
|         assert_eq!(t.repeating(), true); |         assert_eq!(t.repeating(), true); | ||||||
|         assert_eq!(t.percent(), 0.375); |         assert_eq!(t.percent(), 0.375); | ||||||
|         assert_eq!(t.percent_left(), 0.625); |         assert_eq!(t.percent_left(), 0.625); | ||||||
|         // Tick past the end and make sure elapsed wraps
 |         // Tick past the end and make sure elapsed wraps
 | ||||||
|         t.tick(1.5); |         t.tick(3.5); | ||||||
|         assert_eq!(t.elapsed(), 0.25); |         assert_eq!(t.elapsed(), 0.25); | ||||||
|         assert_eq!(t.finished(), true); |         assert_eq!(t.finished(), true); | ||||||
|         assert_eq!(t.just_finished(), true); |         assert_eq!(t.just_finished(), true); | ||||||
|  |         assert_eq!(t.just_finished_count(), 2); | ||||||
|         assert_eq!(t.percent(), 0.125); |         assert_eq!(t.percent(), 0.125); | ||||||
|         assert_eq!(t.percent_left(), 0.875); |         assert_eq!(t.percent_left(), 0.875); | ||||||
|         // Continuing to tick should turn off both finished & just_finished for repeating timers
 |         // Continuing to tick should turn off both finished & just_finished for repeating timers
 | ||||||
| @ -205,6 +229,7 @@ mod tests { | |||||||
|         assert_eq!(t.elapsed(), 1.25); |         assert_eq!(t.elapsed(), 1.25); | ||||||
|         assert_eq!(t.finished(), false); |         assert_eq!(t.finished(), false); | ||||||
|         assert_eq!(t.just_finished(), false); |         assert_eq!(t.just_finished(), false); | ||||||
|  |         assert_eq!(t.just_finished_count(), 0); | ||||||
|         assert_eq!(t.percent(), 0.625); |         assert_eq!(t.percent(), 0.625); | ||||||
|         assert_eq!(t.percent_left(), 0.375); |         assert_eq!(t.percent_left(), 0.375); | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 reidbhuntley
						reidbhuntley