use alloc::sync::{Arc, Weak};
use core::fmt;
use crate::Listener;
#[derive(Clone, Default)]
pub struct Gate {
strong: Arc<()>,
}
impl fmt::Debug for Gate {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Gate")
}
}
impl Gate {
pub(super) fn new<L>(listener: L) -> (Gate, GateListener<L>) {
let signaller = Arc::new(());
let weak = Arc::downgrade(&signaller);
(
Gate { strong: signaller },
GateListener {
weak,
target: listener,
},
)
}
}
#[derive(Clone, Debug)]
pub struct GateListener<L> {
weak: Weak<()>,
target: L,
}
impl<M, L> Listener<M> for GateListener<L>
where
L: Listener<M>,
{
fn receive(&self, messages: &[M]) -> bool {
if self.weak.strong_count() > 0 {
self.target.receive(messages)
} else {
false
}
}
}
impl<L: Listener<M>, M> crate::FromListener<GateListener<L>, M> for GateListener<L> {
fn from_listener(listener: GateListener<L>) -> Self {
listener
}
}
impl fmt::Pointer for Gate {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.strong.fmt(f)
}
}
impl<L: fmt::Pointer> fmt::Pointer for GateListener<L> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let Self { weak, target } = self;
write!(
f,
"GateListener {{ gate: {weak:p}, target: {target:p} }}",
weak = weak.as_ptr(),
target = *target, )
}
}