use std::sync::{Arc, Weak};
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};
use crate::{task::Task, Actor, Addr};
pub struct Context<A: Actor> {
actor: Option<A>,
sender: Weak<UnboundedSender<Box<dyn Task<A>>>>,
receiver: UnboundedReceiver<Box<dyn Task<A>>>,
}
impl<A: Actor> Context<A> {
pub(crate) fn start(actor: A) -> Addr<A> {
let (sender, receiver) = unbounded_channel();
let sender = Arc::new(sender);
let context = Context {
actor: Some(actor),
sender: Arc::downgrade(&sender),
receiver,
};
tokio::spawn(context.run());
Addr::new(sender)
}
async fn run(mut self) {
let mut actor = self.actor.take().unwrap();
while let Some(task) = self.receiver.recv().await {
actor = task.run(actor, &mut self).await;
}
}
pub fn addr(&self) -> Option<Addr<A>> {
Weak::upgrade(&self.sender).map(Addr::new)
}
}