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, | ||||
|     duration: f32, | ||||
|     finished: bool, | ||||
|     /// Will only be true on the tick `duration` is reached or exceeded.
 | ||||
|     just_finished: bool, | ||||
|     /// Will only be non-zero on the tick `duration` is reached or exceeded.
 | ||||
|     just_finished_count: u32, | ||||
|     paused: bool, | ||||
|     repeating: bool, | ||||
| } | ||||
| @ -51,7 +51,8 @@ impl Timer { | ||||
|         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] | ||||
|     pub fn elapsed(&self) -> f32 { | ||||
|         self.elapsed | ||||
| @ -74,8 +75,9 @@ impl Timer { | ||||
| 
 | ||||
|     /// Returns the finished state of the timer.
 | ||||
|     ///
 | ||||
|     /// 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.
 | ||||
|     /// 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, so in that case
 | ||||
|     /// this function is equivalent to `just_finished`.
 | ||||
|     #[inline] | ||||
|     pub fn finished(&self) -> bool { | ||||
|         self.finished | ||||
| @ -84,7 +86,16 @@ impl Timer { | ||||
|     /// Will only be true on the tick the timer's duration is reached or exceeded.
 | ||||
|     #[inline] | ||||
|     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] | ||||
| @ -92,8 +103,11 @@ impl Timer { | ||||
|         self.repeating | ||||
|     } | ||||
| 
 | ||||
|     #[inline] | ||||
|     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 | ||||
|     } | ||||
| 
 | ||||
| @ -102,20 +116,24 @@ impl Timer { | ||||
|         if self.paused { | ||||
|             return self; | ||||
|         } | ||||
| 
 | ||||
|         let prev_finished = self.finished; | ||||
|         self.elapsed += delta; | ||||
| 
 | ||||
|         self.finished = self.elapsed >= self.duration; | ||||
|         self.just_finished = !prev_finished && self.finished; | ||||
| 
 | ||||
|         if self.finished { | ||||
|             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
 | ||||
|                 self.elapsed %= self.duration; | ||||
|             } else { | ||||
|                 self.just_finished_count = if prev_finished { 0 } else { 1 }; | ||||
|                 // Non-repeating timers clamp to duration
 | ||||
|                 self.elapsed = self.duration; | ||||
|             } | ||||
|         } else { | ||||
|             self.just_finished_count = 0; | ||||
|         } | ||||
|         self | ||||
|     } | ||||
| @ -123,7 +141,7 @@ impl Timer { | ||||
|     #[inline] | ||||
|     pub fn reset(&mut self) { | ||||
|         self.finished = false; | ||||
|         self.just_finished = false; | ||||
|         self.just_finished_count = 0; | ||||
|         self.elapsed = 0.0; | ||||
|     } | ||||
| 
 | ||||
| @ -151,6 +169,7 @@ mod tests { | ||||
|         assert_eq!(t.duration(), 10.0); | ||||
|         assert_eq!(t.finished(), false); | ||||
|         assert_eq!(t.just_finished(), false); | ||||
|         assert_eq!(t.just_finished_count(), 0); | ||||
|         assert_eq!(t.repeating(), false); | ||||
|         assert_eq!(t.percent(), 0.025); | ||||
|         assert_eq!(t.percent_left(), 0.975); | ||||
| @ -161,6 +180,7 @@ mod tests { | ||||
|         assert_eq!(t.duration(), 10.0); | ||||
|         assert_eq!(t.finished(), false); | ||||
|         assert_eq!(t.just_finished(), false); | ||||
|         assert_eq!(t.just_finished_count(), 0); | ||||
|         assert_eq!(t.repeating(), false); | ||||
|         assert_eq!(t.percent(), 0.025); | ||||
|         assert_eq!(t.percent_left(), 0.975); | ||||
| @ -170,6 +190,7 @@ mod tests { | ||||
|         assert_eq!(t.elapsed(), 10.0); | ||||
|         assert_eq!(t.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_left(), 0.0); | ||||
|         // 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.finished(), true); | ||||
|         assert_eq!(t.just_finished(), false); | ||||
|         assert_eq!(t.just_finished_count(), 0); | ||||
|         assert_eq!(t.percent(), 1.0); | ||||
|         assert_eq!(t.percent_left(), 0.0); | ||||
|     } | ||||
| @ -190,14 +212,16 @@ mod tests { | ||||
|         assert_eq!(t.duration(), 2.0); | ||||
|         assert_eq!(t.finished(), false); | ||||
|         assert_eq!(t.just_finished(), false); | ||||
|         assert_eq!(t.just_finished_count(), 0); | ||||
|         assert_eq!(t.repeating(), true); | ||||
|         assert_eq!(t.percent(), 0.375); | ||||
|         assert_eq!(t.percent_left(), 0.625); | ||||
|         // 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.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_left(), 0.875); | ||||
|         // 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.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_left(), 0.375); | ||||
|     } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 reidbhuntley
						reidbhuntley