use std::sync::{Arc, RwLock};
use crate::common::*;
type EventListenerList<T> = Arc<RwLock<Vec<EventListener<T>>>>;
pub struct EventEmitter<T: Clone> {
listener_list: EventListenerList<T>,
}
impl<T: Clone> EventEmitter<T> {
pub fn new() -> Self {
Self {
listener_list: Arc::new(RwLock::new(vec![])),
}
}
pub fn listener<F>(&self, function: F) -> EventListener<T>
where F: Fn(T) + Send + Sync + 'static
{
let listener = EventListener::new(Arc::clone(&self.listener_list), function);
listener.add();
listener
}
pub fn emit(&self, data: T) {
let mut list_2 = vec![];
for listener in &*self.listener_list.read().unwrap() {
list_2.push(listener.clone());
}
for listener in list_2 {
(listener.inner.function)(data.clone());
}
}
}
pub struct EventListener<T: Clone> {
inner: Arc<EventListenerInner<T>>,
}
impl<T: Clone> PartialEq for EventListener<T> {
fn eq(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.inner, &other.inner)
}
}
impl<T: Clone> Eq for EventListener<T> {}
impl<T: Clone> Clone for EventListener<T> {
fn clone(&self) -> Self {
Self {
inner: Arc::clone(&self.inner),
}
}
}
impl<T: Clone> EventListener<T> {
pub fn new<F: Fn(T) + Send + Sync + 'static>(listener_list: EventListenerList<T>, function: F) -> Self {
Self {
inner: Arc::new(EventListenerInner {
listener_list,
function: Box::new(function),
}),
}
}
pub fn add(&self) {
self.remove();
let list = &self.inner.listener_list;
list.write().unwrap().push(self.clone());
}
pub fn is_active(&self) -> bool {
let list = &self.inner.listener_list;
list.read().unwrap().contains(self)
}
pub fn remove(&self) {
let list = &self.inner.listener_list;
list.write().unwrap().remove_equals(self);
}
}
struct EventListenerInner<T: Clone> {
listener_list: EventListenerList<T>,
function: Box<dyn Fn(T) + Send + Sync + 'static>,
}