diff --git a/src/utils.rs b/src/utils.rs index a5c94ee7..fa1fd936 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -17,6 +17,7 @@ pub mod double_click_state; pub mod errorfmt; pub mod event_listener; pub mod fdcloser; +pub mod geometric_decay; pub mod gfx_api_ext; pub mod hash_map_ext; pub mod hex; diff --git a/src/utils/geometric_decay.rs b/src/utils/geometric_decay.rs new file mode 100644 index 00000000..83466724 --- /dev/null +++ b/src/utils/geometric_decay.rs @@ -0,0 +1,41 @@ +use std::cell::Cell; + +pub struct GeometricDecay { + p1: f64, + p2: f64, + v: Cell, +} + +impl GeometricDecay { + #[expect(dead_code)] + pub fn new(mut p1: f64, reset: u64) -> Self { + if p1.is_nan() || p1 < 0.01 { + p1 = 0.01; + } + if p1 > 0.99 { + p1 = 0.99; + } + let p2 = 1.0 - p1; + Self { + p1, + p2, + v: Cell::new(reset as f64 / p1), + } + } + + #[expect(dead_code)] + pub fn reset(&self, v: u64) { + self.v.set(v as f64 / self.p1); + } + + #[expect(dead_code)] + pub fn get(&self) -> u64 { + (self.p1 * self.v.get()) as u64 + } + + #[expect(dead_code)] + pub fn add(&self, n: u64) { + let v = n as f64 + self.p2 * self.v.get(); + self.v.set(v); + } +}