use std::{sync::{atomic::{AtomicBool, AtomicUsize, Ordering}, Arc, Weak}, thread::{sleep, sleep_ms, Thread}, time::Duration};
use crossbeam::queue::SegQueue;
use crate::{ReceiveError, ReceiveResult, SharedDetails};
use delegate::delegate;
use std::fmt::Debug;
pub struct Receiver<T, N = ()>
{
shared_details: Arc<SharedDetails<SegQueue<T>, N>>,
sender_count: Weak<()>,
receiver_count: Arc<()>
}
impl<T, N> Receiver<T, N>
{
pub fn new(shared_details: Arc<SharedDetails<SegQueue<T>, N>>, sender_count: Weak<()>, receiver_count: Arc<()>) -> Self
{
Self
{
shared_details, sender_count, receiver_count
}
}
pub fn try_recv(&self) -> ReceiveResult<T>
{
if let Some(res) = self.shared_details.queue_ref().pop()
{
return Ok(res);
}
if self.sender_count.strong_count() == 0
{
return Err(ReceiveError::Closed);
}
Err(ReceiveError::Empty)
}
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;
}
}
delegate!
{
to self.sender_count
{
#[call(strong_count)]
pub fn sender_strong_count(&self) -> usize;
#[call(weak_count)]
pub fn sender_weak_count(&self) -> usize;
}
}
pub fn receiver_strong_count(&self) -> usize
{
Arc::strong_count(&self.receiver_count)
}
pub fn receiver_weak_count(&self) -> usize
{
Arc::weak_count(&self.receiver_count)
}
}
impl<T, N> Clone for Receiver<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 Receiver<T, N>
where T: Debug,
N: Debug
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Receiver").field("shared_details", &self.shared_details).field("sender_count", &self.sender_count).field("receiver_count", &self.receiver_count).finish()
}
}