use std::sync::{Arc, Mutex};
use crate::event::RosaceTrace;
pub trait TraceSubscriber: Send + Sync {
fn on_trace(&self, event: &RosaceTrace);
}
pub struct TracingBus {
subscribers: Mutex<Vec<Arc<dyn TraceSubscriber + Send + Sync>>>,
}
impl Default for TracingBus {
fn default() -> Self {
Self::new()
}
}
impl TracingBus {
pub const fn new() -> Self {
Self {
subscribers: Mutex::new(Vec::new()),
}
}
pub fn add_subscriber(&self, subscriber: Arc<dyn TraceSubscriber + Send + Sync>) {
self.subscribers
.lock()
.expect("TracingBus subscriber lock poisoned")
.push(subscriber);
}
pub fn clear_subscribers(&self) {
self.subscribers
.lock()
.expect("TracingBus subscriber lock poisoned")
.clear();
}
pub fn emit(&self, event: RosaceTrace) {
let subs: Vec<Arc<dyn TraceSubscriber + Send + Sync>> = self
.subscribers
.lock()
.expect("TracingBus subscriber lock poisoned")
.clone();
for sub in &subs {
sub.on_trace(&event);
}
}
}
pub static TRACING_BUS: TracingBus = TracingBus::new();
#[macro_export]
macro_rules! trace {
($event:expr) => {
#[cfg(debug_assertions)]
$crate::TRACING_BUS.emit($event);
};
}
#[macro_export]
macro_rules! location {
() => {
$crate::event::Location {
file: file!(),
line: line!(),
}
};
}