Skip to content

Commit a7981cd

Browse files
authored
feat: make usage of references to mutable static safe (#32)
1 parent 7807e34 commit a7981cd

File tree

2 files changed

+18
-6
lines changed

2 files changed

+18
-6
lines changed

msfs/src/msfs.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ pub enum MSFSEvent<'a> {
3535
SimConnect(SimConnectRecv<'a>),
3636
}
3737

38+
/// Internal helper function to allow usage of mutable globals.
39+
/// # Safety
40+
/// Only call this function if you know what you're doing! This function is only safe
41+
/// to be used if one is **absolutely sure** that there is only 1 reference to it at all times!
42+
pub unsafe fn wrap_executor<E, T>(executor: *mut E, handle: impl FnOnce(&mut E) -> T) -> T {
43+
handle(&mut *executor)
44+
}
45+
3846
/// Gauge
3947
pub struct Gauge {
4048
executor: *mut GaugeExecutor,

msfs_derive/src/lib.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ pub fn standalone_module(_args: TokenStream, item: TokenStream) -> TokenStream {
2929
let output = quote! {
3030
#input
3131

32+
// SAFETY: it is safe to create references of this static since all WASM modules are single threaded
33+
// and there is only 1 reference in use at all times
3234
#[allow(non_upper_case_globals)]
3335
static mut #executor_name: ::msfs::StandaloneModuleExecutor = ::msfs::StandaloneModuleExecutor {
3436
executor: ::msfs::executor::Executor {
@@ -41,14 +43,14 @@ pub fn standalone_module(_args: TokenStream, item: TokenStream) -> TokenStream {
4143
#[no_mangle]
4244
pub extern "C" fn module_init() {
4345
unsafe {
44-
#executor_name.handle_init();
46+
::msfs::wrap_executor(&raw mut #executor_name, |e| e.handle_init());
4547
}
4648
}
4749

4850
#[no_mangle]
4951
pub extern "C" fn module_deinit() {
5052
unsafe {
51-
#executor_name.handle_deinit();
53+
::msfs::wrap_executor(&raw mut #executor_name, |e| e.handle_deinit());
5254
}
5355
}
5456
};
@@ -110,6 +112,8 @@ pub fn gauge(args: TokenStream, item: TokenStream) -> TokenStream {
110112
let output = quote! {
111113
#input
112114

115+
// SAFETY: it is safe to create references of this static since all WASM modules are single threaded
116+
// and there is only 1 reference in use at all times
113117
#[allow(non_upper_case_globals)]
114118
static mut #executor_name: ::msfs::GaugeExecutor = ::msfs::GaugeExecutor {
115119
fs_ctx: None,
@@ -128,7 +132,7 @@ pub fn gauge(args: TokenStream, item: TokenStream) -> TokenStream {
128132
p_data: *mut std::os::raw::c_void,
129133
) -> bool {
130134
unsafe {
131-
#executor_name.handle_gauge(ctx, service_id, p_data)
135+
::msfs::wrap_executor(&raw mut #executor_name, |e| e.handle_gauge(ctx, service_id, p_data))
132136
}
133137
}
134138

@@ -139,9 +143,9 @@ pub fn gauge(args: TokenStream, item: TokenStream) -> TokenStream {
139143
fy: std::os::raw::c_float,
140144
i_flags: std::os::raw::c_uint,
141145
) {
142-
unsafe {
143-
#executor_name.handle_mouse(fx, fy, i_flags);
144-
}
146+
unsafe {
147+
::msfs::wrap_executor(&raw mut #executor_name, |e| e.handle_mouse(fx, fy, i_flags));
148+
}
145149
}
146150
};
147151

0 commit comments

Comments
 (0)