use std::{
collections::VecDeque,
sync::{Arc, Mutex},
task::Waker,
};
use crate::ObjectStateSink;
pub(crate) struct ExposeContractShared {
object_state_sink_ready_for_check_out: VecDeque<ObjectStateSink>,
waker: Option<Waker>,
}
impl ExposeContractShared {
pub fn new() -> ExposeContractShared {
ExposeContractShared { object_state_sink_ready_for_check_out: VecDeque::new(), waker: None }
}
fn wake(&mut self) {
if let Some(waker) = self.waker.take() {
waker.wake();
}
}
pub fn poll_next(&mut self, cx: &mut std::task::Context<'_>) -> std::task::Poll<Option<ObjectStateSink>> {
if let Some(object_state_sink) = self.object_state_sink_ready_for_check_out.pop_front() {
std::task::Poll::Ready(Some(object_state_sink))
} else {
self.waker = Some(cx.waker().clone());
std::task::Poll::Pending
}
}
}
#[derive(Clone)]
pub(crate) struct ExposeContractInlet {
shared: Arc<Mutex<ExposeContractShared>>,
}
impl ExposeContractInlet {
pub fn new(shared: Arc<Mutex<ExposeContractShared>>) -> ExposeContractInlet {
ExposeContractInlet { shared }
}
pub fn sink_created(&mut self, object_state_sink: ObjectStateSink) {
let mut shared = self.shared.lock().unwrap();
shared.object_state_sink_ready_for_check_out.push_back(object_state_sink);
shared.wake();
}
}