1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
use std::ops::AddAssign;

pub struct Tick<F, T> {
    pub function: F,
    pub max_tick: usize,
    pub tick: usize,
    pub state: T,
}

impl<F, T> Tick<F, T> where F: Fn(&mut T) {
    pub fn new(function: F, max_tick: usize, state: T) -> Tick<F, T> {
        Tick {
            function: function,
            tick: 0,
            max_tick: max_tick,
            state: state,
        }
    }
}

impl<F, T> AddAssign<usize> for Tick<F, T> where F: Fn(&mut T) {
    fn add_assign(&mut self, other: usize) {
        self.tick += other;
        while self.tick >= self.max_tick {
            self.tick -= self.max_tick;
            (self.function)(&mut self.state)
        }
    }
}

#[test]
fn tick_append() {
    let list = Vec::new();
    let mut tick = Tick::new(|list| list.push(3), 100, list);
    tick += 100;
    assert_eq!(tick.state, vec![3]);
    tick += 1;
    assert_eq!(tick.state, vec![3]);
    tick += 199;
    assert_eq!(tick.state, vec![3, 3, 3]);
}