use std::sync::{atomic::{AtomicBool, AtomicUsize, Ordering}, Arc, Weak};
use crossbeam::queue::SegQueue;
use crate::{SendResult, SharedDetails};
use delegate::delegate;
use std::fmt::Debug;
pub struct Sender<T, N = ()>
{
shared_details: Arc<SharedDetails<SegQueue<T>, N>>,
sender_count: Arc<()>,
receiver_count: Weak<()>
}
impl<T, N> Sender<T, N>
{
pub fn new(shared_details: &Arc<SharedDetails<SegQueue<T>, N>>, sender_count: Arc<()>, receiver_count: &Arc<()>) -> Self
{
Self
{
shared_details: shared_details.clone(),
sender_count: sender_count.clone(),
receiver_count: Arc::downgrade(receiver_count)
}
}
pub fn send(&self, value: T) -> SendResult<T>
{
if self.receiver_count.strong_count() > 0 {
self.shared_details.queue_ref().push(value);
return Ok(());
}
Err(value)
}
delegate!
{
to self.shared_details
{
pub fn receivers_notifier_ref(&self) -> &N;
}
}
delegate!
{
to self.shared_details.queue_ref()
{
pub fn is_empty(&self) -> bool;
pub fn len(&self) -> usize;
}
}
pub fn sender_strong_count(&self) -> usize
{
Arc::strong_count(&self.sender_count)
}
pub fn sender_weak_count(&self) -> usize
{
Arc::weak_count(&self.sender_count)
}
delegate!
{
to self.receiver_count
{
#[call(strong_count)]
pub fn receiver_strong_count(&self) -> usize;
#[call(weak_count)]
pub fn receiver_weak_count(&self) -> usize;
}
}
}
impl<T, N> Clone for Sender<T, N>
{
fn clone(&self) -> Self
{
Self
{
shared_details: self.shared_details.clone(),
sender_count: self.sender_count.clone(),
receiver_count: self.receiver_count.clone()
}
}
}
impl<T, N> Debug for Sender<T, N>
where T: Debug,
N: Debug
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Sender").field("shared_details", &self.shared_details).field("sender_count", &self.sender_count).field("receiver_count", &self.receiver_count).finish()
}
}