use crate::{ import::*, ActorBuilder, ActorInfo, ChanSender, StrongCount, WeakAddr, addr_inner::*, error::* };
pub struct Addr< A: Actor >
{
inner: AddrInner<A> ,
}
impl< A: Actor > Clone for Addr<A>
{
fn clone( &self ) -> Self
{
let _s = self.info().span().entered();
trace!( "CREATE (clone) Addr id:{}", self.info().id() );
self.inner.strong.lock().expect( "Mutex<StrongCount> poisoned" ).increment();
Self
{
inner: self.inner.clone() ,
}
}
}
impl< A: Actor > PartialEq for Addr<A>
{
fn eq( &self, other: &Self ) -> bool
{
self.inner == other.inner
}
}
impl< A: Actor > Eq for Addr<A>{}
impl<A: Actor> fmt::Debug for Addr<A>
{
fn fmt( &self, f: &mut fmt::Formatter<'_> ) -> fmt::Result
{
let name = match self.name().is_empty()
{
true => String::new(),
false => format!( ", {}", self.name() )
};
write!
(
f ,
"Addr<{}> ~ {}{}" ,
std::any::type_name::<A>() ,
&self.id() ,
name ,
)
}
}
impl<A: Actor> fmt::Display for Addr<A>
{
fn fmt( &self, f: &mut fmt::Formatter<'_> ) -> fmt::Result
{
match self.name().is_empty()
{
true => write!( f, "{} ({})" , self.inner.type_name(), self.id() ) ,
false => write!( f, "{} ({}, {})", self.inner.type_name(), self.id(), self.name() ) ,
}
}
}
impl<A> Addr<A> where A: Actor
{
pub(crate) fn new( tx: ChanSender<A>, info: Arc<ActorInfo>, strong: Arc<Mutex<StrongCount>> ) -> Self
{
strong.lock().expect( "Mutex<StrongCount> poisoned" ).increment();
let inner = AddrInner::new( tx, info, strong );
let _s = inner.span().entered();
trace!( "CREATE Addr id:{}", inner.id() );
Self{ inner }
}
pub fn builder( name: impl AsRef<str> ) -> ActorBuilder<A>
{
ActorBuilder::new( name )
}
pub fn weak( &self ) -> WeakAddr<A>
{
WeakAddr::from( self.inner.clone() )
}
pub fn info( &self ) -> Arc<ActorInfo>
{
self.inner.info.clone()
}
}
impl<A: Actor> Drop for Addr<A>
{
fn drop( &mut self )
{
let _s = self.info().span().entered();
trace!( "DROP Addr id:{}", self.info().id() );
self.inner.strong.lock().expect( "Mutex<StrongCount> poisoned" ).decrement();
}
}
impl<A, M> Address<M> for Addr<A>
where A: Actor + Handler<M> ,
M: Message ,
{
fn call( &mut self, msg: M ) -> Return<'_, ThesRes< <M as Message>::Return >>
{
self.inner.call( msg )
}
fn clone_box( &self ) -> BoxAddress<M, ThesErr>
{
Box::new( self.clone() )
}
}
impl<A> Identify for Addr<A>
where A: Actor,
{
fn id( &self ) -> usize
{
self.inner.id()
}
fn name( &self ) -> Arc<str>
{
self.inner.name()
}
}
impl<A, M> Sink<M> for Addr<A>
where A: Actor + Handler<M> ,
M: Message ,
{
type Error = ThesErr;
fn poll_ready( mut self: Pin<&mut Self>, cx: &mut TaskContext<'_> ) -> Poll<Result<(), Self::Error>>
{
Pin::new( &mut self.inner ).poll_ready( cx )
}
fn start_send( mut self: Pin<&mut Self>, msg: M ) -> Result<(), Self::Error>
{
Pin::new( &mut self.inner ).start_send( msg )
}
fn poll_flush( mut self: Pin<&mut Self>, cx: &mut TaskContext<'_> ) -> Poll<Result<(), Self::Error>>
{
Pin::new( &mut self.inner ).poll_flush( cx )
}
fn poll_close( mut self: Pin<&mut Self>, cx: &mut TaskContext<'_> ) -> Poll<Result<(), Self::Error>>
{
Pin::new( &mut self.inner ).poll_flush( cx )
}
}
impl<A: Actor> TryFrom< AddrInner<A> > for Addr<A>
{
type Error = ThesErr;
fn try_from( inner: AddrInner<A> ) -> Result< Self, ThesErr >
{
let strong = inner.strong.lock().expect( "Mutex<StrongCount> poisoned" );
if strong.count() == 0
{
Err( ThesErr::MailboxClosed{ info: inner.info, src: None } )
}
else
{
strong.increment();
drop(strong);
Ok( Self{ inner } )
}
}
}