debounced_delay.rs

 1use std::time::Duration;
 2
 3use futures::{channel::oneshot, FutureExt};
 4use gpui::{Task, ViewContext};
 5
 6use crate::Editor;
 7
 8#[derive(Debug)]
 9pub struct DebouncedDelay {
10    task: Option<Task<()>>,
11    cancel_channel: Option<oneshot::Sender<()>>,
12}
13
14impl DebouncedDelay {
15    pub fn new() -> DebouncedDelay {
16        DebouncedDelay {
17            task: None,
18            cancel_channel: None,
19        }
20    }
21
22    pub fn fire_new<F>(&mut self, delay: Duration, cx: &mut ViewContext<Editor>, func: F)
23    where
24        F: 'static + Send + FnOnce(&mut Editor, &mut ViewContext<Editor>) -> Task<()>,
25    {
26        if let Some(channel) = self.cancel_channel.take() {
27            _ = channel.send(());
28        }
29
30        let (sender, mut receiver) = oneshot::channel::<()>();
31        self.cancel_channel = Some(sender);
32
33        drop(self.task.take());
34        self.task = Some(cx.spawn(move |model, mut cx| async move {
35            let mut timer = cx.background_executor().timer(delay).fuse();
36            futures::select_biased! {
37                _ = receiver => return,
38                _ = timer => {}
39            }
40
41            if let Ok(task) = model.update(&mut cx, |project, cx| (func)(project, cx)) {
42                task.await;
43            }
44        }));
45    }
46}