#![no_std]
extern crate alloc;
use alloc::sync::Arc;
pub mod actor;
pub use actor::{
Actor, ActorHandle, Message, MessageSender
};
use actor::ActorRef;
pub struct Slacktor {
slab: slab::Slab<Arc<dyn ActorRef>>,
}
impl Slacktor {
pub const fn new() -> Self {
Self {
slab: slab::Slab::new(),
}
}
pub fn next_id(&self) -> usize {
self.slab.vacant_key() as usize
}
pub fn spawn<A: Actor>(&mut self, actor: A) -> usize {
self.slab.insert(Arc::new(ActorHandle::new(actor)))
}
#[cfg(not(feature = "async"))]
pub fn kill(&mut self, id: usize) {
if !self.slab.contains(id) {
return;
}
let a = self.slab.remove(id);
a.kill();
}
#[cfg(feature = "async")]
pub async fn kill<A: Actor>(&mut self, id: usize) -> Option<()> {
if !self.slab.contains(id) {
return None;
}
let a = self.slab.remove(id);
let a = a.as_any().downcast_ref::<ActorHandle<A>>()?;
a.kill().await;
Some(())
}
pub fn get<A: Actor>(&self, id: usize) -> Option<&ActorHandle<A>> {
self.slab.get(id)
.and_then(|actor| actor.as_any().downcast_ref())
}
#[cfg(feature = "async")]
pub async fn shutdown(&mut self) {
for a in self.slab.drain() {
a.kill().await;
}
self.slab.shrink_to_fit();
}
#[cfg(not(feature = "async"))]
pub fn shutdown(&mut self) {
for a in self.slab.drain() {
a.kill();
}
self.slab.shrink_to_fit();
}
pub fn shrink(&mut self) {
self.slab.shrink_to_fit();
}
}