use super::{*, loom::{Arc, atomic::AtomicU64}};
use std::sync::atomic::Ordering;
#[derive(Default)]
pub struct Sink<T> where T: Clone + Sync + Send + Default {
signal: Arc<Signal<T>>,
last_id: AtomicU64
}
impl<T> Sink<T> where T: Clone + Sync + Send + Default {
pub fn from(source: &Source<T>) -> Self {
Sink { signal: source.signal(), last_id: AtomicU64::from(0) }
}
pub fn receive(&self) -> T {
self.last_id.store(self.signal.box_id(), Ordering::Release);
self.signal.value().0
}
pub fn process(&self, closure: &mut dyn FnMut(&T)) {
self.last_id.store(self.signal.box_id(), Ordering::Release);
self.signal.process(closure);
}
pub fn is_connected(&self) -> bool {
Arc::strong_count(&self.signal) > 1
}
pub fn changed(&self) -> bool {
self.signal.box_id() != self.last_id.load(Ordering::Acquire)
}
}
impl<T> Clone for Sink<T> where T: Clone + Sync + Send + Default {
fn clone(&self) -> Self {
Sink { signal: self.signal.clone(), last_id: AtomicU64::default()}
}
}