radiant_utils/misc/
periodic.rs

1use prelude::*;
2use math::min;
3
4/// A generic interval.
5#[derive(Copy, Clone)]
6#[cfg_attr(feature = "serialize-serde", derive(Deserialize, Serialize))]
7pub struct Periodic<S = f32, T = S> {
8    interval: T,
9    next: S,
10}
11
12impl<S, T> Periodic<S, T>
13    where
14        S: Copy + PartialOrd + Add<T> + Sub<T> + Sub<S> +
15            From<<S as Add<T>>::Output> +
16            From<<S as Sub<T>>::Output>,
17        T: Copy + PartialOrd + Add<T> +
18            From<<S as Sub<S>>::Output>
19{
20    /// Returns a new Periodic instance.
21    pub fn new(current: S, interval: T) -> Periodic<S, T> {
22        Periodic {
23            interval: interval,
24            next: S::from(current + interval),
25        }
26    }
27    /// Returns true if the interval has elapsed and subtracts the interval
28    /// since then from the next interval.
29    pub fn elapsed(self: &mut Self, current: S) -> bool {
30        if self.next <= current {
31            self.next = S::from(S::from(current + self.interval) - min(T::from(current - self.next), self.interval));
32            true
33        } else {
34            false
35        }
36    }
37    /// Returns true if the interval has elapsed and advances by one interval.
38    /// This function will return true for each interval that has elapsed.
39    pub fn accumulated(self: &mut Self, current: S) -> bool {
40        if self.next <= current {
41            self.next = S::from(self.next + self.interval);
42            true
43        } else {
44            false
45        }
46    }
47    /// Returns true if the interval has elapsed
48    pub fn peek(self: &mut Self, current: S) -> bool {
49        self.next <= current
50    }
51}
52
53impl<S, T> Debug for Periodic<S, T> where S: Debug, T: Debug {
54    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55        write!(f, "Periodic(interval: {:?}, next: {:?})", self.interval, self.next)
56    }
57}