use std::collections::HashMap;
use std::sync::{Arc, Mutex};
#[derive(Clone)]
pub struct CallbackStore {
callbacks: HashMap<String, Arc<Mutex<dyn FnMut() + Send + 'static>>>
}
impl CallbackStore {
pub fn new() -> CallbackStore {
CallbackStore {
callbacks: HashMap::new(),
}
}
pub fn insert(&mut self, id: String, callback: Arc<Mutex<dyn FnMut() + Send + 'static>>) -> () {
if (self.callbacks.contains_key(&id)) {
panic!("[paro] callback ids must be unique, '{}' is not", &id);
}
self.callbacks.insert(id, callback);
}
pub fn clear(&mut self) -> () {
self.callbacks.clear();
}
pub fn call(&mut self, id: String) -> Result<(), String> {
match self.callbacks.get(&id) {
Some(callback) => {
let mut locked = { callback.lock().unwrap() };
Ok(locked())
},
None => Err(format!("[paro] callback '{}' not found", &id))
}
}
}
#[macro_export]
macro_rules! event {
($state:expr, $closure:tt)=>{
{
let mut state_clone = $state.clone();
let callback_id = uuid::Uuid::new_v4().to_string();
let callback = move || {
let mut closure_box: Box<dyn FnMut(&mut Arc<Mutex<ApplicationState>>) + Send + 'static> = Box::new($closure);
closure_box(&mut state_clone);
};
{
$state.lock().unwrap().callback_store.insert(
callback_id.clone(),
Arc::new(Mutex::new(callback))
);
}
let javascript_call = format!{"window.__PARO__.emitEvent(\"{}\")", &callback_id};
javascript_call
}
}
}