use crate::actor::{Actor, ActorError};
use crate::actor_ref::ActorRef;
use tokio::sync::mpsc;
use uuid::Uuid;
pub const DEFAULT_BUFFER_SIZE: usize = 32;
pub fn spawn_actor<A: Actor>(actor: A, buffer: usize) -> ActorRef<A>
where
A::State: PartialEq,
{
let id = Uuid::new_v4().to_string();
let (sender, mut receiver) = mpsc::channel::<A::Event>(buffer);
let actor_ref = ActorRef::new(id.clone(), sender);
tokio::spawn(async move {
let mut current_state = actor.initial_state();
println!(
"Actor {} spawned with initial state: {:?}",
id, current_state
);
while let Some(event) = receiver.recv().await {
match actor.receive(current_state.clone(), event).await {
Ok(new_state) => {
if new_state != current_state {
println!(
"Actor {} state changed: {:?} -> {:?}",
id, current_state, new_state
);
current_state = new_state; } else {
}
}
Err(err) => {
eprintln!("Actor {} error processing event: {}", id, err);
if matches!(err, ActorError::Stopped) {
eprintln!(
"Actor {} stopping due to explicit stop request or critical error.",
id
);
break; }
}
}
}
println!("Actor {} task finished.", id);
});
actor_ref
}
pub fn spawn<A: Actor>(actor: A) -> ActorRef<A>
where
A::State: PartialEq,
{
spawn_actor(actor, DEFAULT_BUFFER_SIZE)
}