use crate::mailbox::Inbox;
use crate::scheduler::Scheduler;
use crate::{create_mailbox, Actor, ActorContext, ActorHandle, ActorRunner, KillSwitch, Mailbox};
pub struct SpawnBuilder<A: Actor> {
actor: A,
scheduler_mailbox: Mailbox<Scheduler>,
kill_switch: KillSwitch,
#[allow(clippy::type_complexity)]
mailboxes: Option<(Mailbox<A>, Inbox<A>)>,
}
impl<A: Actor> SpawnBuilder<A> {
pub(crate) fn new(
actor: A,
scheduler_mailbox: Mailbox<Scheduler>,
kill_switch: KillSwitch,
) -> Self {
SpawnBuilder {
actor,
scheduler_mailbox,
kill_switch,
mailboxes: None,
}
}
pub fn set_kill_switch(mut self, kill_switch: KillSwitch) -> Self {
self.kill_switch = kill_switch;
self
}
pub fn set_mailboxes(mut self, mailbox: Mailbox<A>, inbox: Inbox<A>) -> Self {
self.mailboxes = Some((mailbox, inbox));
self
}
fn create_actor_context_and_inbox(mut self) -> (A, ActorContext<A>, Inbox<A>) {
let (mailbox, inbox) = self.mailboxes.take().unwrap_or_else(|| {
let actor_name = self.actor.name();
let queue_capacity = self.actor.queue_capacity();
create_mailbox(actor_name, queue_capacity)
});
let ctx = ActorContext::new(
mailbox,
self.kill_switch.clone(),
self.scheduler_mailbox.clone(),
);
(self.actor, ctx, inbox)
}
}
impl<A: Actor> SpawnBuilder<A> {
pub fn spawn(self) -> (Mailbox<A>, ActorHandle<A>) {
let runner = self.actor.runner();
self.spawn_with_forced_runner(runner)
}
pub fn spawn_with_forced_runner(self, runner: ActorRunner) -> (Mailbox<A>, ActorHandle<A>) {
let (actor, ctx, inbox) = self.create_actor_context_and_inbox();
let mailbox = ctx.mailbox().clone();
let actor_handle = runner.spawn_actor(actor, ctx, inbox);
(mailbox, actor_handle)
}
}