emf_core_base_rs/
global.rs1use crate::ffi::{
5 collections::NonNullConst,
6 sys::api::{GetFunctionFn as GetFunctionFnFFI, SysBinding},
7 Bool, CBase as CBaseFFI,
8};
9use crate::init::CBaseAPILoader;
10use crate::{CBase, CBaseInterfaceInfo, CBaseRef};
11use std::mem::MaybeUninit;
12use std::ptr::NonNull;
13
14pub mod library;
15pub mod module;
16pub mod sys;
17pub mod version;
18
19#[cfg(feature = "extensions")]
20pub mod extensions;
21
22static mut INTERFACE: MaybeUninit<CBaseRef<'static>> = MaybeUninit::uninit();
23
24#[derive(Debug)]
26pub struct Unlock {}
27
28#[derive(Debug)]
30pub struct ForgetUnlock {}
31
32impl Drop for Unlock {
33 fn drop(&mut self) {
34 unsafe { SysBinding::unlock(get_interface()) }
35 }
36}
37
38#[derive(Debug)]
40pub struct LockToken<T> {
41 _phantom: T,
42}
43
44impl LockToken<Unlock> {
45 pub unsafe fn relinquish_locking(self) -> LockToken<ForgetUnlock> {
52 std::mem::forget(self);
53 LockToken {
54 _phantom: ForgetUnlock {},
55 }
56 }
57}
58
59impl LockToken<ForgetUnlock> {
60 pub unsafe fn take_ownership(self) -> LockToken<Unlock> {
67 std::mem::forget(self);
68 LockToken {
69 _phantom: Unlock {},
70 }
71 }
72}
73
74impl<T> LockToken<T> {
75 #[inline]
84 #[must_use]
85 pub fn lock() -> LockToken<Unlock> {
86 unsafe {
87 SysBinding::lock(get_interface());
88 LockToken {
89 _phantom: Unlock {},
90 }
91 }
92 }
93
94 #[inline]
102 #[must_use]
103 pub fn try_lock() -> Option<LockToken<Unlock>> {
104 unsafe {
105 match SysBinding::try_lock(get_interface()) {
106 Bool::False => None,
107 Bool::True => Some(LockToken {
108 _phantom: Unlock {},
109 }),
110 }
111 }
112 }
113
114 #[inline]
126 pub unsafe fn assume_locked() -> LockToken<ForgetUnlock> {
127 LockToken {
128 _phantom: ForgetUnlock {},
129 }
130 }
131}
132
133#[inline]
135pub fn initialize(base_module: Option<NonNull<CBaseFFI>>, get_function_fn: GetFunctionFnFFI) {
136 unsafe {
137 INTERFACE = MaybeUninit::new(CBaseRef::new(NonNullConst::from(
138 CBase::fetch_interface(base_module, get_function_fn).internal_interface(),
139 )));
140 }
141
142 #[cfg(feature = "unwind_internal")]
143 extensions::unwind_internal::initialize();
144}
145
146#[inline]
150pub fn get_interface<'a>() -> &'a CBaseRef<'static> {
151 unsafe { &*INTERFACE.as_ptr() }
152}
153
154#[inline]
158pub fn get_mut_interface<'a>() -> &'a mut CBaseRef<'static> {
159 unsafe { &mut *INTERFACE.as_mut_ptr() }
160}