Fixes Timer Precision Error Causing Panic (#2362)

# Objective

Fixes #2361 

## Solution

Uses integer division instead of floating-point which prevents precision errors, I think.
This commit is contained in:
Jacob Gardner 2021-06-26 19:49:34 +00:00
parent b8f3d9c365
commit 52e8a19a39

View file

@ -217,7 +217,8 @@ impl Timer {
if self.finished() { if self.finished() {
if self.repeating() { if self.repeating() {
self.times_finished = self.percent().floor() as u32; self.times_finished =
(self.elapsed().as_nanos() / self.duration().as_nanos()) as u32;
// Duration does not have a modulo // Duration does not have a modulo
self.set_elapsed(self.elapsed() - self.duration() * self.times_finished); self.set_elapsed(self.elapsed() - self.duration() * self.times_finished);
} else { } else {
@ -464,4 +465,20 @@ mod tests {
t.tick(Duration::from_secs_f32(0.5)); t.tick(Duration::from_secs_f32(0.5));
assert_eq!(t.times_finished(), 0); assert_eq!(t.times_finished(), 0);
} }
#[test]
fn times_finished_precise() {
let mut t = Timer::from_seconds(0.01, true);
let duration = Duration::from_secs_f64(1.0 / 3.0);
t.tick(duration);
assert_eq!(t.times_finished(), 33);
t.tick(duration);
assert_eq!(t.times_finished(), 33);
t.tick(duration);
assert_eq!(t.times_finished(), 33);
// It has one additional tick this time to compensate for missing 100th tick
t.tick(duration);
assert_eq!(t.times_finished(), 34);
}
} }