wowlab_engine_domain/pool/
cooldown.rs1use 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;