debounced_delay.rs

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