use std::time::{Duration, Instant};
#[derive(Debug, Clone)]
pub struct Debouncer {
delay: Duration,
last_event: Option<Instant>,
pending: bool,
}
impl Debouncer {
#[must_use]
pub fn new(delay_ms: u64) -> Self {
Self {
delay: Duration::from_millis(delay_ms),
last_event: None,
pending: false,
}
}
pub fn trigger(&mut self) {
self.last_event = Some(Instant::now());
self.pending = true;
}
pub fn should_execute(&mut self) -> bool {
if !self.pending {
return false;
}
if let Some(last) = self.last_event {
if last.elapsed() >= self.delay {
self.pending = false;
self.last_event = None;
return true;
}
}
false
}
#[must_use]
pub fn time_remaining(&self) -> Option<Duration> {
if !self.pending {
return None;
}
self.last_event.map(|last| {
let elapsed = last.elapsed();
if elapsed >= self.delay {
Duration::from_millis(0)
} else {
self.delay - elapsed
}
})
}
pub fn reset(&mut self) {
self.last_event = None;
self.pending = false;
}
#[must_use]
pub fn is_pending(&self) -> bool {
self.pending
}
}
pub trait DebouncedInput {
fn on_input_changed(&mut self);
fn on_debounced_execute(&mut self);
fn check_debounce(&mut self) -> bool;
}