use std::sync::mpsc::{channel, Sender};
use std::sync::{Arc, Mutex};
use std::thread;
pub struct SimpleQueue<T: Send + Sync + 'static> {
listeners: Arc<Mutex<Vec<SimpleQueueListener<T>>>>,
}
impl<T: Send + Sync + 'static> SimpleQueue<T> {
pub fn builder() -> Self {
Self {
listeners: Arc::new(Mutex::new(Vec::new())),
}
}
pub fn add_listen(&self, name: &str, listener: fn(message: T)) -> Self {
let (tx, rx) = channel::<T>();
let running = Arc::new(std::sync::atomic::AtomicBool::new(true));
thread::spawn(move || {
loop {
match rx.recv() {
Ok(message) => {
listener(message);
}
Err(_) => {
break;
}
}
if !running.load(std::sync::atomic::Ordering::Relaxed) {
break;
}
}
});
let mut listeners = self.listeners.lock().unwrap();
listeners.push(SimpleQueueListener {
name: name.to_string(),
sender: tx,
});
self.clone()
}
pub fn send(&self, name: &str, message: T) {
let listeners = self.listeners.lock().unwrap();
if let Some(listener) = listeners.iter().find(|l| l.name == name) {
let _ = listener.sender.send(message);
}
}
}
pub struct SimpleQueueListener<T: Send + Sync + 'static> {
name: String,
sender: Sender<T>,
}
impl<T: Send + Sync + 'static> Clone for SimpleQueue<T> {
fn clone(&self) -> Self {
Self {
listeners: self.listeners.clone(),
}
}
}