use std::collections::HashSet;
use std::sync::RwLock;
use std::hash::{Hash, Hasher};
use crate::{Signal, Handler, MutHandler, Remote, WeakRemote};
#[derive(Clone)]
struct Receiver<S: Signal> {
ptr: *const (),
actor: WeakRemote<Handler<S>>
}
impl<S: Signal> PartialEq for Receiver<S> {
fn eq(&self, other: &Receiver<S>) -> bool {
self.ptr == other.ptr
}
}
impl<S: Signal> Eq for Receiver<S> {
}
impl<S: Signal> Hash for Receiver<S> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.ptr.hash(state);
}
}
#[derive(Clone)]
struct MutReceiver<S: Signal> {
ptr: *const (),
actor: WeakRemote<MutHandler<S>>
}
impl<S: Signal> PartialEq for MutReceiver<S> {
fn eq(&self, other: &MutReceiver<S>) -> bool {
self.ptr == other.ptr
}
}
impl<S: Signal> Eq for MutReceiver<S> {
}
impl<S: Signal> Hash for MutReceiver<S> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.ptr.hash(state);
}
}
pub struct Broadcaster<S: Signal + Clone> {
receivers: RwLock<HashSet<Receiver<S>>>,
receivers_mut: RwLock<HashSet<MutReceiver<S>>>
}
impl<S: 'static + Signal + Clone> Broadcaster<S> {
pub fn new() -> Broadcaster<S> {
Broadcaster {
receivers: RwLock::new(HashSet::new()),
receivers_mut: RwLock::new(HashSet::new())
}
}
pub fn register(&self, actor: Remote<dyn 'static + Handler<S>>) {
let mut receivers = self.receivers.write().unwrap();
let receiver = Receiver {
ptr: actor.ptr() as *const (),
actor: actor.downgrade() };
receivers.insert(receiver);
}
pub fn register_mut(&self, actor: Remote<dyn 'static + MutHandler<S>>) {
let mut receivers_mut = self.receivers_mut.write().unwrap();
let receiver = MutReceiver {
ptr: actor.ptr() as *const (),
actor: actor.downgrade() };
receivers_mut.insert(receiver);
}
pub fn emit(&self, signal: S) {
{
let mut receivers = self.receivers.write().unwrap();
let mut dead_receivers: Vec<Receiver<S>> = Vec::new();
for receiver in receivers.iter() {
match receiver.actor.upgrade() {
Some(actor) => {
actor.send(signal.clone());
},
None => dead_receivers.push(receiver.clone())
}
}
for dead_receiver in dead_receivers.iter() {
receivers.remove(dead_receiver);
}
}
{
let mut receivers_mut = self.receivers_mut.write().unwrap();
let mut dead_receivers: Vec<MutReceiver<S>> = Vec::new();
for receiver in receivers_mut.iter() {
match receiver.actor.upgrade() {
Some(actor) => {
actor.send_mut(signal.clone());
},
None => dead_receivers.push(receiver.clone())
}
}
for dead_receiver in dead_receivers.iter() {
receivers_mut.remove(dead_receiver);
}
}
}
}
pub enum Subscription<S: Signal> {
Const(Remote<dyn 'static + Handler<S>>),
Mut(Remote<dyn 'static + MutHandler<S>>)
}
impl<S: Signal> Signal for Subscription<S> {
type Response = ();
}
pub trait Emitter<S: Signal> {
fn subscribe(&self, actor: Remote<dyn 'static + Handler<S>>);
fn subscribe_mut(&self, actor: Remote<dyn 'static + MutHandler<S>>);
}
impl<T, S: Signal> Handler<Subscription<S>> for T where T: Emitter<S> {
fn handle(&self, s: Subscription<S>) {
match s {
Subscription::Const(actor) => self.subscribe(actor),
Subscription::Mut(actor) => self.subscribe_mut(actor)
}
}
}