qualia_core_db/query/
spawn_decay.rs1pub fn spawn_decay_alpha(
14 now: u64,
15 valid_from: u64,
16 valid_until: Option<u64>,
17 onset_secs: u64,
18 decay_secs: u64,
19) -> f32 {
20 if now < valid_from.saturating_sub(onset_secs) {
21 return 0.0;
22 }
23 if onset_secs > 0 && now < valid_from {
24 let t = (now - valid_from.saturating_sub(onset_secs)) as f64 / onset_secs as f64;
25 return t.clamp(0.0, 1.0) as f32;
26 }
27 if let Some(until) = valid_until {
28 if now > until.saturating_add(decay_secs) {
29 return 0.0;
30 }
31 if decay_secs > 0 && now > until {
32 let t = 1.0 - (now - until) as f64 / decay_secs as f64;
33 return t.clamp(0.0, 1.0) as f32;
34 }
35 }
36 1.0
37}
38
39#[inline]
41pub fn temporally_active(
42 now: u64,
43 valid_from: u64,
44 valid_until: Option<u64>,
45 onset_secs: u64,
46 decay_secs: u64,
47) -> bool {
48 spawn_decay_alpha(now, valid_from, valid_until, onset_secs, decay_secs) > 0.0
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54
55 #[test]
56 fn full_lifecycle_ramps() {
57 let vf = 1000u64;
58 let vu = 2000u64;
59 let onset = 100u64;
60 let decay = 100u64;
61
62 assert_eq!(spawn_decay_alpha(899, vf, Some(vu), onset, decay), 0.0);
63 assert!((spawn_decay_alpha(950, vf, Some(vu), onset, decay) - 0.5).abs() < 0.01);
64 assert_eq!(spawn_decay_alpha(1500, vf, Some(vu), onset, decay), 1.0);
65 assert!((spawn_decay_alpha(2050, vf, Some(vu), onset, decay) - 0.5).abs() < 0.01);
66 assert_eq!(spawn_decay_alpha(2101, vf, Some(vu), onset, decay), 0.0);
67 }
68
69 #[test]
70 fn open_ended_validity() {
71 assert_eq!(spawn_decay_alpha(5000, 1000, None, 0, 0), 1.0);
72 assert_eq!(spawn_decay_alpha(500, 1000, None, 0, 0), 0.0);
73 }
74}