///|
/// Timestamp-based debounce. Integrates with the polling loop.
/// Feed events as they arrive; flush() returns the pending event
/// once `delay` ms have elapsed since the last feed.
struct Debouncer {
delay : Int
mut last_event_at : UInt64?
mut pending : @chokidar.Event?
}
///|
fn Debouncer::new(delay : Int) -> Debouncer {
{ delay, last_event_at: None, pending: None }
}
///| Record a file event; resets the debounce timer.
fn Debouncer::feed(
self : Debouncer,
event : @chokidar.Event,
now : UInt64,
) -> Unit {
self.last_event_at = Some(now)
self.pending = Some(event)
}
///| Return the pending event if `delay` ms have elapsed since the last feed,
/// then reset state. Returns None if still within the debounce window.
fn Debouncer::flush(self : Debouncer, now : UInt64) -> @chokidar.Event? {
match self.last_event_at {
None => None
Some(last) => {
let delay_u64 = self.delay.reinterpret_as_uint().to_uint64()
if now >= last + delay_u64 {
let event = self.pending
self.last_event_at = None
self.pending = None
event
} else {
None
}
}
}
}
///| True if a feed has been recorded but not yet flushed.
fn Debouncer::is_pending(self : Debouncer) -> Bool {
self.pending is Some(_)
}