use crate::{ActorId, Message, Result}; use std::future::Future; use std::hash::{Hash, Hasher}; use std::pin::Pin; use std::sync::Mutex; pub(crate) type CallerFuture = Pin::Result>> + Send + 'static>>; pub(crate) type CallerFn = Box CallerFuture + Send + 'static>; pub(crate) type SenderFn = Box Result<()> + 'static + Send>; /// Caller of a specific message type /// /// Like `Sender, Caller has a weak reference to the recipient of the message type, and so will not prevent an actor from stopping if all Addr's have been dropped elsewhere. pub struct Caller { pub actor_id: ActorId, pub(crate) caller_fn: Mutex>, } impl Caller { pub fn call(&self, msg: T) -> CallerFuture { (self.caller_fn.lock().unwrap())(msg) } } impl> PartialEq for Caller { fn eq(&self, other: &Self) -> bool { self.actor_id == other.actor_id } } impl> Hash for Caller { fn hash(&self, state: &mut H) { self.actor_id.hash(state) } } /// Sender of a specific message type /// /// Like `Caller, Sender has a weak reference to the recipient of the message type, and so will not prevent an actor from stopping if all Addr's have been dropped elsewhere. /// This allows it to be used in `send_later` `send_interval` actor functions, and not keep the actor alive indefinitely even after all references to it have been dropped (unless `ctx.stop()` is called from within) pub struct Sender { pub actor_id: ActorId, pub(crate) sender_fn: SenderFn, } impl> Sender { pub fn send(&self, msg: T) -> Result<()> { (self.sender_fn)(msg) } } impl> PartialEq for Sender { fn eq(&self, other: &Self) -> bool { self.actor_id == other.actor_id } } impl> Hash for Sender { fn hash(&self, state: &mut H) { self.actor_id.hash(state) } }