use std::{ marker::PhantomData, sync::Arc, };
use tokio::sync::watch as wtc;
use super::{ ArchData, SerializedData, SlxData, };
pub struct ArchSignal;
impl ArchSignal {
pub fn channel<U>() -> (ArchSignalSender<U>,ArchSignalReceiver<U>) where U: SlxData {
let (sender,receiver) = wtc::channel(SerializedData::undefined()); let sender = SerializedDataSignalSender { sender: Arc::new(sender), };
let receiver = SerializedDataSignalReceiver { receiver, };
let phantom = PhantomData;
(ArchSignalSender { sender, phantom, }, ArchSignalReceiver { receiver, phantom, })
}
}
#[derive(Debug)]
pub struct SerializedDataSignalSender {
sender: Arc<wtc::Sender<SerializedData>>,
}
#[derive(Debug)]
pub struct SerializedDataSignalReceiver {
receiver: wtc::Receiver<SerializedData>,
}
pub struct ArchSignalSender<U> {
sender: SerializedDataSignalSender,
phantom: PhantomData<U>,
}
pub struct ArchSignalReceiver<U> {
receiver: SerializedDataSignalReceiver,
phantom: PhantomData<U>
}
impl Clone for SerializedDataSignalSender {
fn clone(&self) -> Self {
let Self { sender, } = self; let sender = sender.clone(); Self { sender, }
}
}
impl Clone for SerializedDataSignalReceiver {
fn clone(&self) -> Self {
let Self { receiver, } = self; let receiver = receiver.clone(); Self { receiver, }
}
}
impl<U> Clone for ArchSignalSender<U> where U: SlxData {
fn clone(&self) -> Self {
let Self { ref sender, phantom } = *self; let sender = sender.clone(); Self { sender, phantom, }
}
}
impl<U> Clone for ArchSignalReceiver<U> where U: SlxData {
fn clone(&self) -> Self {
let Self { ref receiver, phantom } = *self; let receiver = receiver.clone(); Self { receiver, phantom, }
}
}
impl SerializedDataSignalSender {
pub (crate) fn send(&self, value: SerializedData) -> Result<(), wtc::error::SendError<SerializedData>> { self.sender.send(value) }
pub (crate) fn send_replace(&self, value: SerializedData) -> Option<SerializedData> { let av = self.sender.send_replace(value);
if av.is_undefined() { None } else { Some(av) }
}
pub (crate) fn borrow(&self) -> Option<SerializedData> {
let bor = self.sender.borrow();
if bor.is_undefined() { None } else { Some(bor.clone()) }
}
pub (crate) fn is_closed(&self) -> bool { self.sender.is_closed() }
pub (crate) async fn closed(&self) { self.sender.closed().await }
pub (crate) fn subscribe(&self) -> SerializedDataSignalReceiver { let receiver = self.sender.subscribe(); SerializedDataSignalReceiver { receiver, } }
pub (crate) fn receiver_count(&self) -> usize { self.sender.receiver_count() }
}
impl SerializedDataSignalReceiver {
pub (crate) fn borrow(&self) -> Option<SerializedData> {
let bor = self.receiver.borrow();
if bor.is_undefined() { None } else { Some(bor.clone()) }
}
pub (crate) fn borrow_and_update(&mut self) -> Option<SerializedData> {
let bor = self.receiver.borrow_and_update();
if bor.is_undefined() { None } else { Some(bor.clone()) }
}
pub (crate) fn has_changed(&self) -> Result<bool, wtc::error::RecvError> { self.receiver.has_changed() }
pub (crate) async fn changed(&mut self) -> Result<(), wtc::error::RecvError> { self.receiver.changed().await }
}
impl<U> ArchSignalSender<U> where U: SlxData {
pub(crate) fn inner(self) -> SerializedDataSignalSender { self.sender }
pub fn send(&self, value: ArchData<U>) -> Result<(), wtc::error::SendError<ArchData<U>>> {
match self.sender.send(value.bytes) {
Ok(()) => Ok(()),
Err(wtc::error::SendError(bytes)) => Err(wtc::error::SendError(ArchData::from_bytes(bytes))),
}
}
pub fn send_replace(&self, value: ArchData<U>) -> Option<ArchData<U>> {
match self.sender.send_replace(value.bytes) {
None => None, Some(data) => Some(ArchData::from_bytes(data)),
}
}
pub fn borrow(&self) -> Option<ArchData<U>> {
match self.sender.borrow() {
None => None, Some(data) => Some(unsafe { std::mem::transmute(data) }),
}
}
pub fn is_closed(&self) -> bool { self.sender.is_closed() }
pub async fn closed(&self) { self.sender.closed().await }
pub fn subscribe(&self) -> ArchSignalReceiver<U> { let receiver = self.sender.subscribe(); ArchSignalReceiver { receiver, phantom: PhantomData, } }
pub fn receiver_count(&self) -> usize { self.sender.receiver_count() }
}
impl<U> ArchSignalReceiver<U> where U: SlxData {
pub(crate) fn inner(self) -> SerializedDataSignalReceiver { self.receiver }
pub fn borrow(&self) -> Option<ArchData<U>> {
match self.receiver.borrow() {
None => None, Some(data) => Some(unsafe { std::mem::transmute(data) }),
}
}
pub fn borrow_and_update(&mut self) -> Option<ArchData<U>> {
match self.receiver.borrow_and_update() {
None => None, Some(data) => Some(unsafe { std::mem::transmute(data) }),
}
}
pub fn has_changed(&self) -> Result<bool, wtc::error::RecvError> { self.receiver.has_changed() }
pub async fn changed(&mut self) -> Result<(), wtc::error::RecvError> { self.receiver.changed().await }
}