use super::{Timespec, Deltatime};
use std::iter::Iterator;
use std::thread;
use std::time;
use std::cmp;
pub struct Every {
step: Deltatime,
next: Timespec,
until: Option<Timespec>,
}
impl Every {
pub fn new(step: Deltatime) -> Every {
Every {
step: step,
next: Timespec::now(),
until: None,
}
}
pub fn until(step: Deltatime, until: Timespec) -> Every {
Every {
step: step,
next: Timespec::now(),
until: Some(until),
}
}
}
impl Iterator for Every {
type Item = Timespec;
fn next(&mut self) -> Option<Self::Item> {
let now = Timespec::now();
if let Some(t) = self.until {
if now >= t {
return None;
}
}
if now >= self.next {
self.next = now + self.step;
return Some(now);
}
let wait = self.next - now;
let sec = wait.as_seconds();
let nano = wait.as_nanoseconds() - sec * 1_000_000_000;
let dur = time::Duration::new(sec as u64, nano as u32);
thread::sleep(dur);
let now = Timespec::now();
self.next = now + self.step;
Some(now)
}
}
pub struct Range {
step: Deltatime,
next: Timespec,
until: Option<Timespec>,
cont: cmp::Ordering,
}
impl Range {
pub fn new(start: Timespec, end: Timespec, step: Deltatime) -> Range {
Range {
step: step,
next: start,
until: Some(end),
cont: if step > Deltatime::nanoseconds(0) {
cmp::Ordering::Less
} else {
cmp::Ordering::Greater
},
}
}
pub fn from(start: Timespec, step: Deltatime) -> Range {
Range {
step: step,
next: start,
until: None,
cont: cmp::Ordering::Equal, }
}
}
impl Iterator for Range {
type Item = Timespec;
fn next(&mut self) -> Option<Self::Item> {
let next = self.next;
self.next = self.next + self.step;
match self.until {
None => Some(next),
Some(until) => {
if next.cmp(&until) == self.cont {
Some(next)
} else {
None
}
}
}
}
}
#[cfg(test)]
mod test {
use super::super::{Timespec, Deltatime};
use super::Range;
#[test]
fn test_range() {
let t0 = Timespec::unix(1456000227, 0).unwrap();
let t1 = Timespec::unix(1456000228, 0).unwrap();
let t2 = Timespec::unix(1456000229, 0).unwrap();
let t3 = Timespec::unix(1456000230, 0).unwrap();
let mut r = Range::new(t0, t1, Deltatime::seconds(1));
assert_eq!(r.next(), Some(t0));
assert_eq!(r.next(), None);
let mut r = Range::new(t0, t3, Deltatime::seconds(2));
assert_eq!(r.next(), Some(t0));
assert_eq!(r.next(), Some(t2));
assert_eq!(r.next(), None);
let mut r = Range::new(t1, t0, Deltatime::seconds(1));
assert_eq!(r.next(), None);
let mut r = Range::new(t1, t0, -Deltatime::seconds(1));
assert_eq!(r.next(), Some(t1));
assert_eq!(r.next(), None);
let mut r = Range::new(t3, t0, -Deltatime::seconds(2));
assert_eq!(r.next(), Some(t3));
assert_eq!(r.next(), Some(t1));
assert_eq!(r.next(), None);
let mut r = Range::new(t0, t1, -Deltatime::seconds(1));
assert_eq!(r.next(), None);
}
#[test]
fn test_range_unbounded() {
let t0 = Timespec::unix(1456000227, 0).unwrap();
let t1 = Timespec::unix(1456009999, 0).unwrap();
let unbounded = Range::from(t0, Deltatime::seconds(1));
let bounded = Range::new(t0, t1, Deltatime::seconds(1));
for (tu, tb) in unbounded.zip(bounded) {
assert_eq!(tu, tb);
}
let unbounded = Range::from(t1, -Deltatime::seconds(1));
let bounded = Range::new(t1, t0, -Deltatime::seconds(1));
for (tu, tb) in unbounded.zip(bounded) {
assert_eq!(tu, tb);
}
}
}