omp_gdk/
runtime.rs

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    /// Runtime global object that implements all the callbacks and gamemode data
11    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}