use std::sync::Arc;
use crate::{addr::Addr, context::Context, envelope::Envelope};
use async_trait::async_trait;
use tokio::sync::{mpsc, oneshot, Mutex};
#[async_trait]
pub trait Actor: Sized + Send + Sync + 'static {
type Context: Send + Sync + 'static;
fn start(self) -> Addr<Self>
where
Self: Actor<Context = Context<Self>>,
{
Context::new().run(self)
}
async fn started(&self) {}
async fn stopped(&self) {}
}
pub trait Message: Send + 'static {
type Response: Send;
}
#[async_trait]
pub trait Handler<M>
where
Self: Actor,
M: Message,
{
async fn handle(&mut self, msg: M, ctx: Self::Context) -> M::Response;
}
pub trait ToEnvelope<A, M>
where
A: Actor,
M: Message,
{
fn pack(&self, msg: Option<M>, tx: Option<oneshot::Sender<M::Response>>) -> Envelope<A>;
}
#[async_trait]
pub trait EnvelopeApi<A: Actor> {
async fn handle(&mut self, act: Arc<Mutex<A>>, ctx: A::Context);
}
#[async_trait]
pub trait Sender<M: Message>: Sync {
fn do_send(&self, msg: M);
async fn send(&self, msg: M) -> Result<M::Response, String>;
}
pub trait EnvelopeSender<A: Actor> {
fn get_tx(&self) -> mpsc::Sender<Envelope<A>>;
fn send_env(&self, env: Envelope<A>) {
let tx = self.get_tx();
tokio::spawn(async move {
let _ = tx.send(env).await;
});
}
}