use crate::common::tsafe::TSafe;
use crate::actors::actor_cell::ActorCell;
use crate::actors::abstract_actor_ref::{ActorRef, AbstractActorRef, AskTimeoutError};
use crate::actors::actor_path::ActorPath;
use crate::actors::actor::Actor;
use crate::actors::abstract_actor_system::AbstractActorSystem;
use crate::actors::props::Props;
use crate::actors::ask_actor::AskActor;
use crate::actors::message::Message;
use crate::futures::future::WrappedFuture;
use crate::futures::promise::Promise;
use crate::futures::completable_promise::CompletablePromise;
use std::hash::{Hash, Hasher};
use std::fmt;
use std::any::Any;
use std::time::Duration;
use std::sync::{Arc, Mutex};
pub struct TestLocalActorRef {
pub cell: TSafe<ActorCell>,
pub path: TSafe<ActorPath>,
pub actor: TSafe<Actor + Send>
}
impl TestLocalActorRef {
pub fn new(cell: TSafe<ActorCell>, path: TSafe<ActorPath>) -> TestLocalActorRef {
let actor = cell.clone().lock().unwrap().actor.clone();
TestLocalActorRef {
cell,
path,
actor
}
}
fn inner_clone(self: &Self) -> Box<TestLocalActorRef> {
Box::new(TestLocalActorRef {
cell: self.cell.clone(),
path: self.path.clone(),
actor: self.actor.clone()
})
}
}
impl AbstractActorRef for TestLocalActorRef {
fn tell(self: &mut Self, msg: Message, rself: Option<&ActorRef>) {
let cell_cloned = self.cell.clone();
let path_cloned = self.path.clone();
let toref = Box::new(TestLocalActorRef::new(cell_cloned, path_cloned));
let mut cell = self.cell.lock().unwrap();
cell.send(&self.cell, msg, rself.map_or(None, |v| Some((*v).clone())), toref);
}
fn ask(&mut self, factory: &mut AbstractActorSystem, msg: Message) -> WrappedFuture<Message, AskTimeoutError> {
self.ask_timeout(factory, Duration::from_millis(500), msg)
}
fn ask_timeout(&mut self, factory: &mut AbstractActorSystem, timeout: Duration, msg: Message) -> WrappedFuture<Message, AskTimeoutError> {
let p: CompletablePromise<Message, AskTimeoutError>
= CompletablePromise::new();
let f = p.future();
let ask_actor = factory.actor_of(Props::new(tsafe!(AskActor::new(p, timeout))), None);
self.tell(msg, Some(&ask_actor));
f
}
fn path(&self) -> ActorPath {
self.path.lock().unwrap().clone()
}
fn cell(self: &mut Self) -> TSafe<ActorCell> {
self.cell.clone()
}
fn clone(self: &Self) -> ActorRef {
self.inner_clone()
}
fn as_any(self: &Self) -> Box<Any> {
Box::new(self.inner_clone())
}
}
impl fmt::Display for TestLocalActorRef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "TestActorRef ({})", self.path.lock().unwrap())
}
}
impl PartialEq for TestLocalActorRef {
fn eq(&self, other: &Self) -> bool {
*self.path.lock().unwrap() == *other.path.lock().unwrap()
}
}
impl Eq for TestLocalActorRef {}
impl Hash for TestLocalActorRef {
fn hash<H: Hasher>(&self, state: &mut H) {
self.path.lock().unwrap().hash(state);
}
}