qtbridge_interfaces/
genericrustproxy.rs1use crate::{RustObjAccess, call_rust_trait_impl, call_cpp_impl};
5use qtbridge_runtime::qproxies::{QRustProxy, QCppProxy, ConstructionMode};
6use qtbridge_runtime::{DispatchMetaCall, DynamicMetaObjectData};
7use qtbridge_type_lib::QVariant;
8use std::cell::RefCell;
9use std::rc::Rc;
10
11pub struct GenericRustProxy<CppProxy: QCppProxy, Adapter: ?Sized> {
12 pub(crate) cpp_proxy: *mut CppProxy,
13 pub(crate) rust_obj: RustObjAccess<Adapter>,
14 pub(crate) on_drop: Box<dyn FnOnce()>,
15}
16
17impl<CppProxy, Adapter> QRustProxy for GenericRustProxy<CppProxy, Adapter>
18where
19 CppProxy: QCppProxy<ProxyRustType = Self>,
20 Adapter: ?Sized + DispatchMetaCall,
21{
22 type ProxyCppType = CppProxy;
23 type AdapterType = Adapter;
24
25 fn new(
26 rust_obj: &Rc<RefCell<Adapter>>,
27 metatype: &'static DynamicMetaObjectData,
28 construct: ConstructionMode,
29 on_drop: Box<dyn FnOnce() + 'static>,
30 ) -> *mut Self {
31 let boxed_self = Box::new(Self {
32 cpp_proxy: std::ptr::null_mut(),
33 rust_obj: match construct {
34 ConstructionMode::Strong | ConstructionMode::AtAddress(_) =>
35 RustObjAccess::new_strong(rust_obj.clone()),
36 ConstructionMode::Weak =>
37 RustObjAccess::new_weak(Rc::downgrade(rust_obj)),
38 },
39 on_drop,
40 });
41 let raw_self = Box::into_raw(boxed_self);
42 unsafe {
43 (*raw_self).cpp_proxy = match construct {
44 ConstructionMode::AtAddress(addr) =>
45 CppProxy::create_at(raw_self, metatype, addr),
46 ConstructionMode::Strong | ConstructionMode::Weak =>
47 CppProxy::create(raw_self, metatype),
48 }
49 };
50 raw_self
51 }
52
53 fn get_cpp_proxy(&self) -> *const CppProxy {
54 self.cpp_proxy
55 }
56
57 fn get_cpp_proxy_mut(&self) -> *mut CppProxy {
58 self.cpp_proxy
59 }
60
61 fn emit_signal(&self, mut_ref: &mut Adapter, signal_name: &str, argv: &[*const u8]) {
62 call_cpp_impl!(mut self, mut_ref, emit_signal(signal_name, argv))
63 }
64
65 fn with_rust_ref<R, F: FnOnce(&Adapter) -> R>(&self, f: F) -> R {
66 self.rust_obj
67 .try_call_rust_with_handle(|adapter| f(adapter))
68 .expect("Failed to access Rust object via shared handle")
69 }
70
71 fn with_rust_ref_mut<R, F: FnOnce(&mut Adapter) -> R>(&self, f: F) -> R {
72 self.rust_obj
73 .try_call_rust_with_handle_mut(|adapter| f(adapter))
74 .expect("Failed to access Rust object via mutable handle")
75 }
76
77 fn get_rust_object_rc(&self) -> Option<Rc<RefCell<Adapter>>> {
78 self.rust_obj.get_rc()
79 }
80}
81
82impl<CppProxy, Adapter> GenericRustProxy<CppProxy, Adapter>
83where
84 CppProxy: QCppProxy<ProxyRustType = Self>,
85 Adapter: ?Sized + DispatchMetaCall,
86{
87 pub fn drop_self(self_ptr: *mut Self) {
94 let boxed_self = unsafe { Box::from_raw(self_ptr) };
95 (boxed_self.on_drop)();
96 }
97
98 pub fn invoke_slot(&self, slot_id: u32, inputs: &[*const u8], outputs: &[*mut u8]) {
99 call_rust_trait_impl!(self, invoke_slot(slot_id, inputs, outputs))
100 }
101
102 pub fn invoke_slot_mut(&mut self, slot_id: u32, inputs: &[*const u8], outputs: &[*mut u8]) {
103 call_rust_trait_impl!(mut self, invoke_slot_mut(slot_id, inputs, outputs))
104 }
105
106 pub fn read_property(&self, prop_id: u32) -> QVariant {
107 call_rust_trait_impl!(self, read_property(prop_id))
108 }
109
110 pub fn write_property(&mut self, prop_id: u32, value: &QVariant) {
111 call_rust_trait_impl!(mut self, write_property(prop_id, value))
112 }
113
114}
115
116#[macro_export]
117macro_rules! impl_qcpp_proxy {
118 ($cpp_proxy:ty, $rust_proxy:ty) => {
119 impl QCppProxy for $cpp_proxy {
120 type ProxyRustType = $rust_proxy;
121 fn get_static_meta_object() -> &'static QMetaObject {
122 Self::static_qmeta_object()
123 }
124 fn get_size() -> usize {
125 Self::size_of()
126 }
127 fn get_align() -> usize {
128 Self::align_of()
129 }
130 fn parser_status_cast() -> i32 {
131 Self::parser_status_cast()
132 }
133 unsafe fn create(rust_proxy: *mut Self::ProxyRustType, metaobject: &'static DynamicMetaObjectData) -> *mut Self {
134 unsafe { Self::create(rust_proxy, metaobject) }
135 }
136 unsafe fn create_at(rust_proxy: *mut Self::ProxyRustType, metaobject: &'static DynamicMetaObjectData, addr: *mut u8) -> *mut Self {
137 unsafe { Self::create_at(rust_proxy, metaobject, addr) }
138 }
139 fn emit_signal(self: std::pin::Pin<&mut Self>, signal_name: &str, argv: &[*const u8]) {
140 self.emit_signal_cpp(signal_name, argv)
141 }
142 }
143 };
144}