use std::time::Duration;
use hannibal::prelude::*;
#[derive(Debug)]
struct Child(usize);
impl Actor for Child {
async fn started(&mut self, ctx: &mut Context<Self>) -> hannibal::DynResult<()> {
println!("{self:?} started");
ctx.interval_with(|| (), Duration::from_millis(300 + 300 * self.0 as u64));
Ok(())
}
async fn stopped(&mut self, _: &mut Context<Self>) {
println!("{self:?} stopped");
}
}
#[derive(Clone, Message)]
struct Hello;
impl Handler<Hello> for Child {
async fn handle(&mut self, _: &mut Context<Self>, _: Hello) {
println!("Hello I'm child {}", self.0);
}
}
impl Handler<Hello> for Root {
async fn handle(&mut self, ctx: &mut Context<Self>, msg: Hello) {
println!("Greeting My Children");
ctx.send_to_children(msg);
}
}
impl Handler<()> for Child {
async fn handle(&mut self, _: &mut Context<Self>, _: ()) {
println!("{self:?} {:>width$}!", "x", width = (self.0 + 1) * 10);
}
}
#[derive(Clone, Message)]
struct Gc;
impl Handler<Gc> for Root {
async fn handle(&mut self, ctx: &mut Context<Self>, _: Gc) {
println!("Garbage Collecting");
ctx.gc();
}
}
#[derive(Debug)]
struct Root;
impl Actor for Root {
async fn started(&mut self, ctx: &mut Context<Self>) -> DynResult<()> {
println!("{self:?} started");
ctx.add_child(Child(0).spawn());
ctx.add_child(Child(1).spawn());
ctx.add_child(Child(2).spawn());
ctx.register_child::<Hello>(Child(3).spawn());
ctx.register_child::<Hello>(Child(4).spawn());
ctx.register_child::<Hello>(Child(5).spawn());
ctx.interval_with(|| Hello, Duration::from_millis(500));
ctx.interval(Gc, Duration::from_millis(500));
let mut me = ctx.weak_address();
ctx.delayed_exec(
async move {
me.try_halt().await.unwrap();
println!("shut down root");
},
Duration::from_secs(5),
);
Ok(())
}
async fn stopped(&mut self, _: &mut Context<Self>) {
println!("{self:?} stopped");
}
}
#[hannibal::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
Root.spawn().await?;
Ok(())
}