nativeshell_core/util/
future.rs

1use std::{cell::RefCell, rc::Rc, task::Poll};
2
3use futures::Future;
4
5//
6// Single threaded completable future
7//
8
9struct State<T> {
10    waker: Option<std::task::Waker>,
11    data: Option<T>,
12}
13
14pub struct FutureCompleter<T> {
15    state: Rc<RefCell<State<T>>>,
16}
17
18impl<T> FutureCompleter<T> {
19    pub fn new() -> (CompletableFuture<T>, FutureCompleter<T>) {
20        let state = Rc::new(RefCell::new(State {
21            waker: None,
22            data: None,
23        }));
24        (
25            CompletableFuture {
26                state: state.clone(),
27            },
28            FutureCompleter { state },
29        )
30    }
31
32    pub fn complete(self, data: T) {
33        let waker = {
34            let mut state = self.state.borrow_mut();
35            state.data.replace(data);
36            state.waker.take()
37        };
38        if let Some(waker) = waker {
39            waker.wake();
40        }
41    }
42}
43
44pub struct CompletableFuture<T> {
45    state: Rc<RefCell<State<T>>>,
46}
47
48impl<T> Future for CompletableFuture<T> {
49    type Output = T;
50
51    fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
52        let mut state = self.state.borrow_mut();
53        let data = state.data.take();
54        match data {
55            Some(data) => Poll::Ready(data),
56            None => {
57                state.waker.get_or_insert_with(|| cx.waker().clone());
58                Poll::Pending
59            }
60        }
61    }
62}