gpui_ce_motion/
completion.rs1use std::{
3 future::Future,
4 pin::Pin,
5 sync::{Arc, Mutex, Weak},
6 task::{Context, Poll, Waker},
7};
8
9#[derive(Clone, Copy, Debug, PartialEq, Eq)]
11pub enum CompletionStatus {
12 Completed,
14 Cancelled,
16}
17
18#[derive(Debug, Default)]
19struct ResultState {
20 result: Option<CompletionStatus>,
21 waker: Option<Waker>,
22}
23
24#[derive(Debug)]
27pub struct Completion(Arc<Mutex<ResultState>>);
28
29impl Future for Completion {
30 type Output = CompletionStatus;
31
32 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
33 let mut state = self.0.lock().unwrap_or_else(|error| error.into_inner());
34
35 if let Some(result) = state.result {
36 return Poll::Ready(result);
37 }
38
39 if !state
40 .waker
41 .as_ref()
42 .is_some_and(|waker| waker.will_wake(cx.waker()))
43 {
44 state.waker = Some(cx.waker().clone());
45 }
46
47 Poll::Pending
48 }
49}
50
51#[derive(Debug, Default)]
52pub(crate) struct CompletionSource {
53 observers: Vec<Weak<Mutex<ResultState>>>,
54}
55
56impl CompletionSource {
57 pub(crate) fn subscribe(&mut self, complete: bool) -> Completion {
58 self.observers
59 .retain(|observer| observer.strong_count() > 0);
60 let result = complete.then_some(CompletionStatus::Completed);
61
62 let state = Arc::new(Mutex::new(ResultState {
63 result,
64 waker: None,
65 }));
66
67 if !complete {
68 self.observers.push(Arc::downgrade(&state));
69 }
70
71 Completion(state)
72 }
73
74 pub(crate) fn resolve(&mut self, result: CompletionStatus) {
75 for observer in self.observers.drain(..) {
76 if let Some(observer) = observer.upgrade() {
77 let waker = {
78 let mut state = observer.lock().unwrap_or_else(|error| error.into_inner());
79
80 state.result = Some(result);
81
82 state.waker.take()
83 };
84
85 if let Some(waker) = waker {
86 waker.wake();
87 }
88 }
89 }
90 }
91}
92
93impl Drop for CompletionSource {
94 fn drop(&mut self) {
95 self.resolve(CompletionStatus::Cancelled);
96 }
97}