1use tm_sys::ffi::{
2 TM_ENTITY_CREATE_COMPONENT_INTERFACE_NAME, TM_THE_TRUTH_CREATE_TYPES_INTERFACE_NAME,
3};
4
5use crate::component::DerivedComponent;
6
7use super::ffi;
8use std::{ffi::c_void, os::raw::c_char};
9
10pub struct RegistryApi {
11 reg: *mut ffi::tm_api_registry_api,
12 load: bool,
13}
14
15impl RegistryApi {
16 #[allow(clippy::missing_safety_doc)]
17 pub unsafe fn new(reg: *mut ffi::tm_api_registry_api, load: bool) -> Self {
18 assert!(!reg.is_null());
19 Self { reg, load }
20 }
21
22 #[inline]
23 pub fn get(&mut self, name: &[u8]) -> *mut c_void {
24 unsafe { (*self.reg).get.unwrap()(name.as_ptr() as *const c_char) }
25 }
26
27 #[inline]
28 #[allow(clippy::missing_safety_doc)]
29 pub unsafe fn add_implementation(&mut self, name: &[u8], implementation: *mut c_void) {
30 assert!(!implementation.is_null());
31 (*self.reg).add_implementation.unwrap()(name.as_ptr() as *const c_char, implementation)
32 }
33
34 #[inline]
35 #[allow(clippy::missing_safety_doc)]
36 pub unsafe fn remove_implementation(&mut self, name: &[u8], implementation: *mut c_void) {
37 assert!(!implementation.is_null());
38 (*self.reg).remove_implementation.unwrap()(name.as_ptr() as *const c_char, implementation)
39 }
40
41 #[inline]
42 #[allow(clippy::missing_safety_doc)]
43 pub unsafe fn add_or_remove_implementation(&mut self, name: &[u8], ptr: *mut c_void) {
44 assert!(!ptr.is_null());
45
46 if self.load {
47 self.add_implementation(name, ptr);
48 } else {
49 self.remove_implementation(name, ptr);
50 }
51 }
52
53 pub fn add_or_remove_component<C: DerivedComponent>(&mut self) {
54 unsafe {
55 if let Some(create_types) = C::CREATE_TYPES {
56 self.add_or_remove_implementation(
57 TM_THE_TRUTH_CREATE_TYPES_INTERFACE_NAME,
58 create_types as *mut c_void,
59 );
60 }
61 self.add_or_remove_implementation(
62 TM_ENTITY_CREATE_COMPONENT_INTERFACE_NAME,
63 C::CREATE_COMPONENT as *mut c_void,
64 );
65 }
66 }
67}
68
69#[macro_export]
70macro_rules! add_or_remove_entity_simulation {
71 ($reg:expr, $name:ident) => {
72 $crate::paste::paste! {
73 unsafe extern "C" fn [<$name _extern>](ctx: *mut $crate::ffi::tm_entity_context_o) {
74 assert!(!ctx.is_null());
75
76 let mut entity_api = $crate::api::with_ctx_mut::<$crate::entity::EntityApi>(ctx);
77
78 $name(&mut entity_api);
79 }
80
81 $reg.add_or_remove_implementation(
82 $crate::ffi::TM_ENTITY_SIMULATION_INTERFACE_NAME,
83 [<$name _extern>] as *mut ::std::ffi::c_void,
84 );
85 }
86 };
87}