1use crate::{
2 exports::raw::{
3 Export0, Export10, Export3, Export5, Export6, Export7, Export8, Export9,
4 ExportAddExtension, ExportFreeExtension, ExportListExtension,
5 },
6 util::{exported_proc, str_from_cstr},
7};
8use std::{ffi::c_char, mem::transmute, sync::OnceLock};
9use windows::Win32::Foundation::HMODULE;
10
11#[inline]
13pub unsafe fn init_arc(arc_handle: HMODULE, version: *const c_char) {
14 ArcGlobals::init(arc_handle, str_from_cstr(version));
15}
16
17static ARC_GLOBALS: OnceLock<ArcGlobals> = OnceLock::new();
19
20#[derive(Debug)]
23pub struct ArcGlobals {
24 pub handle: HMODULE,
26
27 pub version: Option<&'static str>,
29
30 pub e0: Option<Export0>,
32
33 pub e3: Option<Export3>,
35
36 pub e5: Option<Export5>,
38
39 pub e6: Option<Export6>,
41
42 pub e7: Option<Export7>,
44
45 pub e8: Option<Export8>,
47
48 pub e9: Option<Export9>,
50
51 pub e10: Option<Export10>,
53
54 pub add_extension: Option<ExportAddExtension>,
56
57 pub free_extension: Option<ExportFreeExtension>,
59
60 pub list_extension: Option<ExportListExtension>,
62}
63
64impl ArcGlobals {
65 pub unsafe fn new(handle: HMODULE, version: Option<&'static str>) -> Self {
67 #![allow(clippy::missing_transmute_annotations)]
68 Self {
69 handle,
70 version,
71 e0: transmute(exported_proc(handle, "e0\0")),
72 e3: transmute(exported_proc(handle, "e3\0")),
73 e5: transmute(exported_proc(handle, "e5\0")),
74 e6: transmute(exported_proc(handle, "e6\0")),
75 e7: transmute(exported_proc(handle, "e7\0")),
76 e8: transmute(exported_proc(handle, "e8\0")),
77 e9: transmute(exported_proc(handle, "e9\0")),
78 e10: transmute(exported_proc(handle, "e10\0")),
79 add_extension: transmute(exported_proc(handle, "addextension2\0")),
80 free_extension: transmute(exported_proc(handle, "freeextension2\0")),
81 list_extension: transmute(exported_proc(handle, "listextension\0")),
82 }
83 }
84
85 pub unsafe fn init(handle: HMODULE, version: Option<&'static str>) -> &'static Self {
87 ARC_GLOBALS.get_or_init(|| Self::new(handle, version))
88 }
89
90 #[inline]
92 pub fn get() -> &'static Self {
93 Self::try_get().expect("arcdps globals not initialized")
94 }
95
96 #[inline]
98 pub fn try_get() -> Option<&'static Self> {
99 ARC_GLOBALS.get()
100 }
101}
102
103unsafe impl Send for ArcGlobals {}
104
105unsafe impl Sync for ArcGlobals {}