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