use futures::{future::{self, FutureResult}, prelude::*};
use holly::{Error, prelude::*};
use tokio_threadpool::ThreadPool;
use void::Void;
enum Message {
Add(usize),
Sum(Addr<usize>)
}
struct Calculator(usize);
impl Actor<Message, Error> for Calculator {
type Result = Box<dyn Future<Item = State<Self, Message>, Error = Error> + Send>;
fn process(mut self, _ctx: &mut Context<Message>, msg: Option<Message>) -> Self::Result {
match msg {
Some(Message::Add(n)) => {
self.0 += n;
Box::new(future::ok(State::Ready(self)))
}
Some(Message::Sum(a)) => {
Box::new(a.send(self.0).map(|_| State::Done))
}
None => Box::new(future::ok(State::Done))
}
}
}
struct Printer;
impl Actor<usize, Void> for Printer {
type Result = FutureResult<State<Self, usize>, Void>;
fn process(self, _ctx: &mut Context<usize>, msg: Option<usize>) -> Self::Result {
match msg {
Some(n) => {
println!("result = {}", n);
future::ok(State::Done)
}
None => future::ok(State::Done)
}
}
}
#[test]
fn sum() -> Result<(), Error> {
let pool = ThreadPool::new();
let exec = Scheduler::new(pool.sender().clone());
let mut calc = exec.spawn(Calculator(0))?;
let printer = exec.spawn(Printer)?;
for i in 0 .. 500 {
calc.send_now(Message::Add(i))?
}
calc.send_now(Message::Sum(printer))?;
pool.shutdown_on_idle().wait().unwrap();
Ok(())
}