Skip to main content

spider_browser/
events.rs

1//! Lock-free event emitter for SpiderBrowser events.
2
3use dashmap::DashMap;
4use serde_json::Value;
5use std::sync::Arc;
6
7/// Callback type for event handlers.
8pub type EventHandler = Arc<dyn Fn(Value) + Send + Sync>;
9
10/// Browser type identifier.
11pub type BrowserType = String;
12
13/// Common browser type constants.
14pub mod browsers {
15    pub const AUTO: &str = "auto";
16    pub const CHROME: &str = "chrome";
17    pub const CHROME_NEW: &str = "chrome-new";
18    pub const CHROME_H: &str = "chrome-h";
19    pub const FIREFOX: &str = "firefox";
20    pub const SERVO: &str = "servo";
21    pub const LIGHTPANDA: &str = "lightpanda";
22}
23
24/// Lock-free event emitter using DashMap for concurrent handler access.
25#[derive(Clone, Default)]
26pub struct SpiderEventEmitter {
27    handlers: Arc<DashMap<String, Vec<EventHandler>>>,
28}
29
30impl SpiderEventEmitter {
31    pub fn new() -> Self {
32        Self::default()
33    }
34
35    pub fn on(&self, event: &str, handler: EventHandler) {
36        self.handlers
37            .entry(event.to_string())
38            .or_default()
39            .push(handler);
40    }
41
42    pub fn off(&self, event: &str) {
43        self.handlers.remove(event);
44    }
45
46    pub fn emit(&self, event: &str, data: Value) {
47        if let Some(list) = self.handlers.get(event) {
48            // Clone the vec to release the DashMap shard lock before invoking callbacks.
49            let handlers = list.clone();
50            drop(list);
51            for handler in &handlers {
52                let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
53                    handler(data.clone());
54                }));
55            }
56        }
57    }
58
59    pub fn remove_all_listeners(&self) {
60        self.handlers.clear();
61    }
62}