use crate::actor::addr::Addr;
use crate::actor::short_type_name;
use crate::actor::traits::Handler;
use crate::trace::Bus;
use std::any::{Any, TypeId};
use std::marker::PhantomData;
use std::rc::Weak;
use super::EventBus;
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct SubscriptionId {
pub(super) seq: u64,
pub(super) event: TypeId,
}
pub struct BusSubscription {
pub(super) bus: Weak<EventBus>,
pub(super) id: SubscriptionId,
}
impl BusSubscription {
pub fn leak(self) {
std::mem::forget(self);
}
}
impl Drop for BusSubscription {
fn drop(&mut self) {
if let Some(bus) = self.bus.upgrade() {
bus.remove(self.id);
}
}
}
impl crate::scope::Teardown for BusSubscription {
fn teardown(self) {
drop(self);
}
}
pub trait Event: Clone + Send + 'static {}
pub trait UntypedSubscriber: 'static {
fn deliver(&self, msg: Box<dyn Any>, bus: Bus);
fn seq(&self) -> u64;
fn event(&self) -> &'static str;
}
pub struct Subscriber<A: Handler<M>, M: Event> {
pub(super) seq: u64,
pub(super) addr: Addr<A>,
pub(super) _marker: PhantomData<M>,
}
impl<A, M> UntypedSubscriber for Subscriber<A, M>
where
A: Handler<M> + 'static,
M: Event,
{
fn deliver(&self, msg: Box<dyn Any>, _bus: Bus) {
if let Ok(concrete_msg) = msg.downcast::<M>() {
self.addr.send(*concrete_msg);
}
}
fn seq(&self) -> u64 {
self.seq
}
fn event(&self) -> &'static str {
short_type_name::<M>()
}
}
pub struct FnSubscriber<M: Event> {
pub(super) seq: u64,
pub(super) callback: std::sync::Arc<dyn Fn(M) + 'static>,
}
impl<M: Event> UntypedSubscriber for FnSubscriber<M> {
fn deliver(&self, msg: Box<dyn Any>, _bus: Bus) {
if let Ok(concrete_msg) = msg.downcast::<M>() {
(self.callback)(*concrete_msg);
}
}
fn seq(&self) -> u64 {
self.seq
}
fn event(&self) -> &'static str {
short_type_name::<M>()
}
}