zed/crates/project/src/debounced_delay.rs
Piotr Osiewicz e6c1c51b37
Some checks are pending
CI / Check formatting and spelling (push) Waiting to run
CI / (macOS) Run Clippy and tests (push) Waiting to run
CI / (Linux) Run Clippy and tests (push) Waiting to run
CI / (Windows) Run Clippy and tests (push) Waiting to run
CI / Create a macOS bundle (push) Blocked by required conditions
CI / Create a Linux bundle (push) Blocked by required conditions
CI / Create arm64 Linux bundle (push) Blocked by required conditions
Deploy Docs / Deploy Docs (push) Waiting to run
Docs / Check formatting (push) Waiting to run
chore: Fix several style lints (#17488)
It's not comprehensive enough to start linting on `style` group, but
hey, it's a start.

Release Notes:

- N/A
2024-09-06 11:58:39 +02:00

54 lines
1.5 KiB
Rust

use futures::{channel::oneshot, FutureExt};
use gpui::{ModelContext, Task};
use std::{marker::PhantomData, time::Duration};
pub struct DebouncedDelay<E: 'static> {
task: Option<Task<()>>,
cancel_channel: Option<oneshot::Sender<()>>,
_phantom_data: PhantomData<E>,
}
impl<E: 'static> Default for DebouncedDelay<E> {
fn default() -> Self {
Self::new()
}
}
impl<E: 'static> DebouncedDelay<E> {
pub fn new() -> Self {
Self {
task: None,
cancel_channel: None,
_phantom_data: PhantomData,
}
}
pub fn fire_new<F>(&mut self, delay: Duration, cx: &mut ModelContext<E>, func: F)
where
F: 'static + Send + FnOnce(&mut E, &mut ModelContext<E>) -> Task<()>,
{
if let Some(channel) = self.cancel_channel.take() {
_ = channel.send(());
}
let (sender, mut receiver) = oneshot::channel::<()>();
self.cancel_channel = Some(sender);
let previous_task = self.task.take();
self.task = Some(cx.spawn(move |model, mut cx| async move {
let mut timer = cx.background_executor().timer(delay).fuse();
if let Some(previous_task) = previous_task {
previous_task.await;
}
futures::select_biased! {
_ = receiver => return,
_ = timer => {}
}
if let Ok(task) = model.update(&mut cx, |project, cx| (func)(project, cx)) {
task.await;
}
}));
}
}