qtbridge_runtime/
qmetainfo.rs1use std::any::TypeId;
5use std::cell::RefCell;
6use std::collections::HashMap;
7use crate::qproxies::QCppProxy;
8use crate::{DynamicMetaObjectBuilder, DynamicMetaObjectData};
9
10#[cfg(doc)]
11use qtbridge_type_lib::QMetaObject;
12
13pub trait QMetaInfo : 'static {
24 type CppProxy: QCppProxy;
26
27 fn class_name() -> &'static str {
29 std::any::type_name::<Self>()
30 }
31
32 fn build_dynamic_meta_type(meta_obj_builder: std::pin::Pin<&mut DynamicMetaObjectBuilder>);
36
37 fn get_shared_dynamic_meta_object_data() -> &'static DynamicMetaObjectData;
40
41 fn create_dynamic_meta_object_data_for_type() -> *const DynamicMetaObjectData {
45 let mut builder = crate::create_dynamic_meta_object_builder(
46 Self::class_name(),
47 Self::CppProxy::get_static_meta_object());
48 Self::build_dynamic_meta_type(builder.pin_mut());
49 builder.pin_mut()
50 .take_dynamic_metaobject_data()
51 }
52}
53
54pub fn dynamic_meta_object_data_for_generic<T: QMetaInfo + ?Sized>() -> &'static DynamicMetaObjectData {
55 thread_local!(static DYNAMIC_META_MAP: RefCell<HashMap<TypeId, *const DynamicMetaObjectData>> =
56 RefCell::new(HashMap::new()));
57
58 let type_id = TypeId::of::<T>();
59 {
60 let meta_data_ptr = DYNAMIC_META_MAP.with_borrow(|dynamic_meta_builder_map| {
61 dynamic_meta_builder_map.get(&type_id)
62 .copied()
63 .unwrap_or_default()
64 });
65 if let Some(meta_data_ref) = unsafe { meta_data_ptr.as_ref() } {
66 return meta_data_ref;
67 }
68 }
69
70 let meta_data_ptr = T::create_dynamic_meta_object_data_for_type();
71 let meta_data_ref = unsafe { meta_data_ptr.as_ref() }.unwrap();
72 DYNAMIC_META_MAP.with_borrow_mut(|dynamic_meta_builder_map| {
73 dynamic_meta_builder_map.insert(type_id, meta_data_ptr);
74 });
75
76 meta_data_ref
77}