/// Defines frames per tick. pub struct Ticks(pub f64); impl Ticks { /// Iterate over ticks between start and end. pub fn between_frames (&self, start: usize, end: usize) -> TicksIterator { TicksIterator(self.0, start, start, end) } } /// Iterator that emits subsequent ticks within a range. pub struct TicksIterator(f64, usize, usize, usize); impl Iterator for TicksIterator { type Item = (usize, usize); fn next (&mut self) -> Option { loop { if self.1 > self.3 { return None } let fpt = self.0; let frame = self.1 as f64; let start = self.2; let end = self.3; self.1 = self.1 + 1; //println!("{fpt} {frame} {start} {end}"); let jitter = frame.rem_euclid(fpt); // ramps let next_jitter = (frame + 1.0).rem_euclid(fpt); if jitter > next_jitter { // at crossing: let time = (frame as usize) % (end as usize-start as usize); let tick = (frame / fpt) as usize; return Some((time, tick)) } } } } #[cfg(test)] mod test { use super::*; #[test] fn test_frames_to_ticks () { let ticks = Ticks(12.3).between_frames(0, 100).collect::>(); println!("{ticks:?}"); } }