use std::cell::RefCell;
use std::rc::Rc;
use web_time::{Duration, Instant};
use crate::{Signal, reactive, signal, timer};
#[deprecated(
note = "Debounced entries live on the shared timer queue, which `ReposeRuntime::tick_overlays` already polls via `timer::poll`. Polling here too would advance frame timers twice per redraw. Use `timer::next_deadline` instead."
)]
pub fn next_deadline() -> Option<Instant> {
timer::next_deadline()
}
#[deprecated(
note = "`ReposeRuntime::tick_overlays` already polls the shared queue via `timer::poll`. Calling this too would advance frame timers twice per redraw. Use `timer::poll` instead."
)]
pub fn poll() {
timer::poll();
}
pub fn debounced_signal<T>(source: Signal<T>, delay: Duration) -> Signal<T>
where
T: Clone + PartialEq + 'static,
{
let out = signal(source.get());
let out_clone = out.clone();
let pending: Rc<RefCell<Option<T>>> = Rc::new(RefCell::new(None));
let delay_c = delay;
let slot: Rc<RefCell<Option<timer::TimerHandle>>> = Rc::new(RefCell::new(None));
let obs_id = reactive::new_observer({
let source = source.clone();
let slot = slot.clone();
move || {
let v = source.get();
*pending.borrow_mut() = Some(v.clone());
let out_c = out_clone.clone();
let pending_c = pending.clone();
*slot.borrow_mut() = Some(timer::delay(delay_c, move || {
if let Some(val) = pending_c.borrow_mut().take() {
out_c.set_neq(val);
}
}));
}
});
reactive::run_observer_now(obs_id);
let installed = crate::remember(|| RefCell::new(false));
if !*installed.borrow() {
*installed.borrow_mut() = true;
crate::scoped_effect(move || {
crate::on_unmount(move || {
reactive::remove_observer(obs_id);
*slot.borrow_mut() = None;
})
});
}
out
}
pub fn debounced_signal_with_key<T>(
key: impl Into<String>,
source: Signal<T>,
delay: Duration,
) -> Signal<T>
where
T: Clone + PartialEq + 'static,
{
let key = key.into();
crate::remember_with_key(key, || debounced_signal(source, delay))
.as_ref()
.clone()
}