1use crate::events::Events;
2use std::{
3 cell::{RefCell, RefMut},
4 rc::Rc,
5};
6
7type OMPRSModule = Rc<RefCell<dyn Events + 'static>>;
8
9thread_local! {
10 pub static Runtime: RefCell<Vec<OMPRSModule>> = RefCell::new(Vec::new());
12
13 pub static API_QUEUE: RefCell<Vec<Box<dyn FnOnce()>>> = RefCell::new(Vec::new());
14
15 #[doc(hidden)]
16 pub static __terminate_event_chain: RefCell<bool> = const { RefCell::new(false) };
17}
18
19pub fn each_module<F>(mut f: F) -> Option<bool>
20where
21 F: FnMut(RefMut<dyn Events>) -> Option<bool>,
22{
23 let mut result = None;
24 let mut break_iteration = false;
25
26 Runtime.with(|runtime| {
27 for module in runtime.borrow().iter() {
28 let ret = f(module.borrow_mut());
29 result = ret;
30 if result.is_none() {
31 continue;
32 }
33
34 crate::runtime::__terminate_event_chain.with_borrow_mut(|terminate| {
35 if *terminate {
36 *terminate = false;
37 break_iteration = true;
38 }
39 });
40 if break_iteration {
41 break;
42 }
43 }
44 });
45
46 result
47}
48
49pub fn queue_api_call(callback: Box<dyn FnOnce()>) {
50 API_QUEUE.with_borrow_mut(|queue| {
51 queue.push(callback);
52 });
53}