use core::pin::Pin;
use std::future::Future;
use std::sync::{Arc, Mutex};
use std::task::{Context, Poll, Waker};
#[derive(Debug, Clone)]
pub struct BtlePlugFutureState<T> {
reply_msg: Option<T>,
waker: Option<Waker>,
}
impl<T> Default for BtlePlugFutureState<T> {
fn default() -> Self {
BtlePlugFutureState::<T> {
reply_msg: None,
waker: None,
}
}
}
impl<T> BtlePlugFutureState<T> {
pub fn set_reply(&mut self, reply: T) {
if self.reply_msg.is_some() {
panic!("set_reply_msg called multiple times on the same future.");
}
self.reply_msg = Some(reply);
if self.waker.is_some() {
self.waker.take().unwrap().wake();
}
}
}
pub type BtlePlugFutureStateShared<T> = Arc<Mutex<BtlePlugFutureState<T>>>;
#[derive(Debug)]
pub struct BtlePlugFuture<T> {
waker_state: BtlePlugFutureStateShared<T>,
}
impl<T> Default for BtlePlugFuture<T> {
fn default() -> Self {
BtlePlugFuture::<T> {
waker_state: BtlePlugFutureStateShared::<T>::default(),
}
}
}
impl<T> BtlePlugFuture<T> {
pub fn get_state_clone(&self) -> BtlePlugFutureStateShared<T> {
self.waker_state.clone()
}
}
impl<T> Future for BtlePlugFuture<T> {
type Output = T;
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
let mut waker_state = self.waker_state.lock().unwrap();
if waker_state.reply_msg.is_some() {
let msg = waker_state.reply_msg.take().unwrap();
Poll::Ready(msg)
} else {
waker_state.waker = Some(cx.waker().clone());
Poll::Pending
}
}
}