use std::time::Duration;
use async_trait::async_trait;
use dactor::actor::{Actor, ActorContext, ActorRef, Handler};
use dactor::message::Message;
use dactor::TestRuntime;
struct Increment(u64);
impl Message for Increment {
type Reply = ();
}
struct GetCount;
impl Message for GetCount {
type Reply = u64;
}
struct Reset;
impl Message for Reset {
type Reply = u64;
}
struct Counter {
count: u64,
}
impl Actor for Counter {
type Args = Self;
type Deps = ();
fn create(args: Self, _deps: ()) -> Self {
args
}
}
#[async_trait]
impl Handler<Increment> for Counter {
async fn handle(&mut self, msg: Increment, _ctx: &mut ActorContext) {
self.count += msg.0;
println!(
" [Counter] incremented by {} → count = {}",
msg.0, self.count
);
}
}
#[async_trait]
impl Handler<GetCount> for Counter {
async fn handle(&mut self, _msg: GetCount, _ctx: &mut ActorContext) -> u64 {
self.count
}
}
#[async_trait]
impl Handler<Reset> for Counter {
async fn handle(&mut self, _msg: Reset, _ctx: &mut ActorContext) -> u64 {
let old = self.count;
self.count = 0;
println!(" [Counter] reset (old value = {})", old);
old
}
}
#[tokio::main]
async fn main() {
println!("=== Basic Counter Example ===\n");
let runtime = TestRuntime::new();
let counter = runtime.spawn::<Counter>("counter", Counter { count: 0 }).await.unwrap();
println!("Spawned actor '{}'", counter.name());
println!("\nSending tell(Increment) messages...");
counter.tell(Increment(5)).unwrap();
counter.tell(Increment(3)).unwrap();
counter.tell(Increment(2)).unwrap();
tokio::time::sleep(Duration::from_millis(50)).await;
let count = counter.ask(GetCount, None).unwrap().await.unwrap();
println!("\nask(GetCount) → {}", count);
let old = counter.ask(Reset, None).unwrap().await.unwrap();
println!("ask(Reset) → old value was {}", old);
let count = counter.ask(GetCount, None).unwrap().await.unwrap();
println!("ask(GetCount) → {} (after reset)", count);
counter.stop();
tokio::time::sleep(Duration::from_millis(50)).await;
println!("\nActor alive? {}", counter.is_alive());
println!("\n=== Done ===");
}