scripthookv_rs_macros/
lib.rs1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, ItemFn};
4
5#[proc_macro_attribute]
6pub fn shv_entrypoint(_metadata: TokenStream, item: TokenStream) -> TokenStream {
7 let entrypoint = parse_macro_input!(item as ItemFn);
8
9 let expanded = quote! {
10 #entrypoint
11
12 static __SCRIPTHOOKV: ::once_cell::sync::OnceCell<::std::sync::Arc<::std::sync::Mutex<scripthookv::ScriptHookV>>> = ::once_cell::sync::OnceCell::new();
13
14 thread_local! {
15 static __SCRIPT_MANAGER: ::once_cell::unsync::OnceCell<::std::cell::RefCell<::scripthookv::scripting::ScriptManager<'static>>> = ::once_cell::unsync::OnceCell::new();
16 }
17
18 extern "C" fn __shv_script_entrypoint() {
19 __SCRIPT_MANAGER.with(|shvm| {
20 let mut script_manager = shvm.get_or_init(|| {
21 __SCRIPTHOOKV
22 .get()
23 .expect("ScriptHookv is not initialized")
24 .lock()
25 .unwrap()
26 .new_script_manager_for_thread()
27 .into()
28 }).borrow_mut();
29 loop {
30 script_manager.tick();
31 unsafe {
32 ::scripthookv::shv_bindings::scriptWait(0);
33 }
34 }
35 });
36 }
37
38 #[no_mangle]
39 #[allow(non_snake_case)]
40 pub extern "stdcall" fn DllMain(
41 instance: scripthookv::ModuleHandle,
42 reason: u32,
43 _reserved: *const std::ffi::c_void
44 ) -> i32 {
45 match reason {
46 1 => {
47 __SCRIPTHOOKV.get_or_init(|| {
48 ::std::sync::Arc::new(::std::sync::Mutex::new(entrypoint(instance)))
49 });
50 unsafe {
51 ::scripthookv::shv_bindings::scriptRegister(instance, __shv_script_entrypoint);
52 }
53 1
54 }
55 0 => {
56 if let Some(shv) = &__SCRIPTHOOKV.get() {
57 shv.lock().unwrap().cleanup();
58 }
59 1
60 },
61 _ => 1,
62 }
63 }
64 };
65
66 expanded.into()
67}