Skip to main content

wowlab_engine_domain/pool/
cooldown.rs

1use std::hash::Hash;
2
3use wowlab_types::sim::SimTime;
4
5use super::base::Pool;
6
7#[derive(Clone, Debug)]
8pub struct CooldownPool<K> {
9    state: Pool<K, SimTime>,
10}
11
12impl<K> CooldownPool<K>
13where
14    K: Eq + Hash,
15{
16    #[must_use]
17    pub fn new() -> Self {
18        Self::default()
19    }
20
21    pub fn ready_at(&self, key: &K) -> SimTime {
22        self.state.get(key).copied().unwrap_or(SimTime::ZERO)
23    }
24
25    pub fn is_ready(&self, key: &K, now: SimTime) -> bool {
26        self.ready_at(key) <= now
27    }
28
29    pub fn start(&mut self, key: K, ready_at: SimTime) -> SimTime {
30        self.state.set(key, ready_at);
31
32        ready_at
33    }
34
35    pub fn start_for(&mut self, key: K, now: SimTime, duration: SimTime) -> SimTime {
36        self.start(key, now.saturating_add(duration))
37    }
38
39    pub fn reduce(&mut self, key: K, amount: SimTime, floor: SimTime) -> SimTime {
40        let reduced = self.ready_at(&key).saturating_sub(amount).max(floor);
41
42        self.state.set(key, reduced);
43
44        reduced
45    }
46
47    pub fn reset(&mut self, key: &K) {
48        self.state.remove(key);
49    }
50
51    pub fn clear(&mut self) {
52        self.state.clear();
53    }
54}
55
56impl<K> Default for CooldownPool<K> {
57    fn default() -> Self {
58        Self {
59            state: Pool::default(),
60        }
61    }
62}
63
64#[cfg(test)]
65#[path = "cooldown/tests.rs"]
66mod tests;