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}