use std::fmt;
use crate::actor::{Actor, ActorContext, ActorState, AsyncContext, SpawnHandle};
use crate::address::{Addr, AddressReceiver};
use crate::contextimpl::{AsyncContextParts, ContextFut, ContextParts};
use crate::fut::ActorFuture;
use crate::mailbox::Mailbox;
pub struct Context<A>
where
A: Actor<Context = Context<A>>,
{
parts: ContextParts<A>,
mb: Option<Mailbox<A>>,
}
impl<A: Actor<Context = Context<A>>> fmt::Debug for Context<A> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("Context")
.field("parts", &self.parts)
.field("mb", &self.mb)
.finish()
}
}
impl<A> ActorContext for Context<A>
where
A: Actor<Context = Self>,
{
#[inline]
fn stop(&mut self) {
self.parts.stop()
}
#[inline]
fn terminate(&mut self) {
self.parts.terminate()
}
#[inline]
fn state(&self) -> ActorState {
self.parts.state()
}
}
impl<A> AsyncContext<A> for Context<A>
where
A: Actor<Context = Self>,
{
#[inline]
fn spawn<F>(&mut self, fut: F) -> SpawnHandle
where
F: ActorFuture<Output = (), Actor = A> + 'static,
{
self.parts.spawn(fut)
}
#[inline]
fn wait<F>(&mut self, fut: F)
where
F: ActorFuture<Output = (), Actor = A> + 'static,
{
self.parts.wait(fut)
}
#[inline]
fn waiting(&self) -> bool {
self.parts.waiting()
}
#[inline]
fn cancel_future(&mut self, handle: SpawnHandle) -> bool {
self.parts.cancel_future(handle)
}
#[inline]
fn address(&self) -> Addr<A> {
self.parts.address()
}
}
impl<A> Context<A>
where
A: Actor<Context = Self>,
{
#[inline]
pub(crate) fn new() -> Self {
let mb = Mailbox::default();
Self {
parts: ContextParts::new(mb.sender_producer()),
mb: Some(mb),
}
}
#[inline]
pub fn with_receiver(rx: AddressReceiver<A>) -> Self {
let mb = Mailbox::new(rx);
Self {
parts: ContextParts::new(mb.sender_producer()),
mb: Some(mb),
}
}
#[inline]
pub fn run(self, act: A) -> Addr<A> {
let fut = self.into_future(act);
let addr = fut.address();
actix_rt::spawn(fut);
addr
}
pub fn into_future(mut self, act: A) -> ContextFut<A, Self> {
let mb = self.mb.take().unwrap();
ContextFut::new(self, act, mb)
}
pub fn handle(&self) -> SpawnHandle {
self.parts.curr_handle()
}
pub fn set_mailbox_capacity(&mut self, cap: usize) {
self.parts.set_mailbox_capacity(cap)
}
pub fn connected(&self) -> bool {
self.parts.connected()
}
}
impl<A> AsyncContextParts<A> for Context<A>
where
A: Actor<Context = Self>,
{
fn parts(&mut self) -> &mut ContextParts<A> {
&mut self.parts
}
}
pub trait ContextFutureSpawner<A>
where
A: Actor,
A::Context: AsyncContext<A>,
{
fn spawn(self, ctx: &mut A::Context);
fn wait(self, ctx: &mut A::Context);
}
impl<A, T> ContextFutureSpawner<A> for T
where
A: Actor,
A::Context: AsyncContext<A>,
T: ActorFuture<Output = (), Actor = A> + 'static,
{
#[inline]
fn spawn(self, ctx: &mut A::Context) {
let _ = ctx.spawn(self);
}
#[inline]
fn wait(self, ctx: &mut A::Context) {
ctx.wait(self);
}
}