use crate::core::messages::{ButtplugClientInMessage, ButtplugClientOutMessage};
use async_std::{
future::Future,
task::{Context, Poll, Waker},
};
use core::pin::Pin;
use std::sync::{Arc, Mutex};
#[derive(Debug, Clone)]
pub struct ButtplugFutureState<T> {
reply_msg: Option<T>,
waker: Option<Waker>,
}
impl<T> Default for ButtplugFutureState<T> {
fn default() -> Self {
ButtplugFutureState::<T> {
reply_msg: None,
waker: None,
}
}
}
impl<T> ButtplugFutureState<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 ButtplugFutureStateShared<T> = Arc<Mutex<ButtplugFutureState<T>>>;
#[derive(Debug)]
pub struct ButtplugFuture<T> {
waker_state: ButtplugFutureStateShared<T>,
}
impl<T> Default for ButtplugFuture<T> {
fn default() -> Self {
ButtplugFuture::<T> {
waker_state: ButtplugFutureStateShared::<T>::default(),
}
}
}
impl<T> ButtplugFuture<T> {
pub fn get_state_clone(&self) -> ButtplugFutureStateShared<T> {
self.waker_state.clone()
}
}
impl<T> Future for ButtplugFuture<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 {
debug!("Waker set.");
waker_state.waker = Some(cx.waker().clone());
Poll::Pending
}
}
}
pub type ButtplugMessageState = ButtplugFutureState<ButtplugClientOutMessage>;
pub type ButtplugMessageStateShared = ButtplugFutureStateShared<ButtplugClientOutMessage>;
pub type ButtplugMessageFuture = ButtplugFuture<ButtplugClientOutMessage>;
pub type ButtplugMessageFuturePair = (ButtplugClientInMessage, ButtplugMessageStateShared);