1pub use rusteal_ffi as ffi;
11pub use rusteal_core as runtime;
12pub use rusteal_ue_flags as ue_flags;
13pub use rusteal_macros::{uclass, uclass_impl, ustruct};
14
15#[doc(hidden)]
17pub extern crate inventory as __inventory;
18
19pub mod prelude;
20
21pub use glam;
23
24extern "C" fn real_drop_rust_instance(
29 handle: ffi::UObjectHandle,
30 type_id: u64,
31 _rust_data: *mut u8,
32) {
33 runtime::ffi_boundary((), || {
34 runtime::reify_registry::drop_instance(handle, type_id);
35 });
36}
37
38extern "C" fn real_invoke_rust_function(
39 callback_id: u64,
40 obj: ffi::UObjectHandle,
41 params: *mut u8,
42) {
43 runtime::ffi_boundary((), || {
44 runtime::reify_registry::invoke_function(callback_id, obj, params);
45 });
46}
47
48extern "C" fn real_invoke_delegate_callback(callback_id: u64, params: *mut u8) {
49 runtime::ffi_boundary((), || {
50 runtime::delegate_registry::invoke(callback_id, params);
51 });
52}
53
54extern "C" fn real_construct_rust_instance(
55 obj: ffi::UObjectHandle,
56 type_id: u64,
57 _is_cdo: bool,
58) {
59 runtime::ffi_boundary((), || {
60 runtime::reify_registry::construct_instance(obj, type_id);
61 });
62}
63
64extern "C" fn real_on_shutdown() {
65 runtime::ffi_boundary((), || {
66 runtime::task::shutdown();
69 runtime::reify_registry::clear_all();
70 runtime::delegate_registry::clear_all();
71 runtime::pinned::clear_all();
72 });
73}
74
75extern "C" fn real_notify_pinned_destroyed(handle: ffi::UObjectHandle) {
76 runtime::ffi_boundary((), || {
77 runtime::pinned::notify_pinned_destroyed(handle);
78 });
79}
80
81extern "C" fn real_on_tick(delta_seconds: f32) {
82 runtime::ffi_boundary((), || {
83 runtime::task::tick(delta_seconds);
84 });
85}
86
87#[doc(hidden)]
88pub static __CALLBACKS: ffi::RustealRustCallbacks = ffi::RustealRustCallbacks {
89 drop_rust_instance: real_drop_rust_instance,
90 invoke_rust_function: real_invoke_rust_function,
91 invoke_delegate_callback: real_invoke_delegate_callback,
92 on_shutdown: real_on_shutdown,
93 construct_rust_instance: real_construct_rust_instance,
94 notify_pinned_destroyed: real_notify_pinned_destroyed,
95 on_tick: real_on_tick,
96};
97
98pub unsafe fn init(api_table: *const ffi::RustealApiTable) -> *const ffi::RustealRustCallbacks {
113 std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
114 if api_table.is_null() {
115 return std::ptr::null();
116 }
117 if unsafe { (*api_table).version } != ffi::RUSTEAL_VERSION {
121 return std::ptr::null();
122 }
123
124 runtime::init_api(api_table);
126 runtime::task::mark_game_thread();
127
128 log_greeting();
129 register_all_classes();
130 run_load_hooks();
131 &__CALLBACKS as *const ffi::RustealRustCallbacks
132 }))
133 .unwrap_or(std::ptr::null())
134}
135
136fn log_greeting() {
138 let msg = "[Rusteal] Rust side initialized";
139 let bytes = msg.as_bytes();
140 unsafe {
141 runtime::ffi_dispatch::logging_log(0, bytes.as_ptr(), bytes.len() as u32);
142 }
143}
144
145fn register_all_classes() {
147 runtime::reify_registry::register_all_from_inventory();
148}
149
150#[doc(hidden)]
153pub struct LoadHook(pub fn());
154inventory::collect!(LoadHook);
155
156fn run_load_hooks() {
157 for hook in inventory::iter::<LoadHook> {
158 (hook.0)();
159 }
160}
161
162#[macro_export]
173macro_rules! on_load {
174 ($function:path) => {
175 $crate::__inventory::submit! { $crate::LoadHook($function) }
176 };
177}
178
179pub fn shutdown() {
181 let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
182 (__CALLBACKS.on_shutdown)();
183 }));
184}
185
186#[macro_export]
193macro_rules! entry {
194 () => {
195 mod __rusteal_native_entry {
196 #[unsafe(no_mangle)]
197 pub extern "C" fn rusteal_init(
198 api_table: *const $crate::ffi::RustealApiTable,
199 ) -> *const $crate::ffi::RustealRustCallbacks {
200 unsafe { $crate::init(api_table) }
202 }
203
204 #[unsafe(no_mangle)]
205 pub extern "C" fn rusteal_shutdown() {
206 $crate::shutdown()
207 }
208
209 #[unsafe(no_mangle)]
212 pub extern "C" fn rusteal_version() -> u32 {
213 $crate::ffi::RUSTEAL_VERSION
214 }
215
216 #[unsafe(no_mangle)]
220 pub extern "C" fn rusteal_callbacks() -> *const $crate::ffi::RustealRustCallbacks {
221 &$crate::__CALLBACKS
222 }
223 }
224 };
225}