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}