qtbridge_interfaces/
genericrustproxy.rs1use crate::{RustObjAccess, call_rust_trait_impl, call_cpp_impl};
5use qtbridge_runtime::qproxies::{QRustProxy, QCppProxy, PlacementAddress};
6use qtbridge_runtime::{DispatchMetaCall, DynamicMetaObjectData};
7use qtbridge_type_lib::QVariant;
8use std::cell::RefCell;
9use std::pin::Pin;
10use std::rc::Rc;
11
12pub struct GenericRustProxy<CppProxy: QCppProxy, Adapter: ?Sized> {
13 pub(crate) cpp_proxy: *mut CppProxy,
14 pub(crate) rust_obj: RustObjAccess<Adapter>,
15 pub(crate) on_drop: Box<dyn FnOnce()>,
16}
17
18impl<CppProxy: QCppProxy, Adapter: ?Sized> GenericRustProxy<CppProxy, Adapter> {
19 pub(crate) fn cpp_proxy_ref(&self) -> &CppProxy {
20 unsafe { self.cpp_proxy.as_ref() }.expect("cpp_proxy was null")
22 }
23
24 #[allow(clippy::mut_from_ref)]
27 pub(crate) fn cpp_proxy_pin_mut(&self) -> Pin<&mut CppProxy> {
28 let proxy = unsafe { self.cpp_proxy.as_mut() }.expect("cpp_proxy was null");
30 unsafe { Pin::new_unchecked(proxy) }
32 }
33}
34
35unsafe impl<CppProxy, Adapter> QRustProxy for GenericRustProxy<CppProxy, Adapter>
38where
39 CppProxy: QCppProxy<ProxyRustType = Self>,
40 Adapter: ?Sized + DispatchMetaCall,
41{
42 type ProxyCppType = CppProxy;
43 type AdapterType = Adapter;
44
45 fn new(
46 rust_obj: &Rc<RefCell<Adapter>>,
47 metatype: &'static DynamicMetaObjectData,
48 at_address: Option<PlacementAddress>,
49 on_drop: Box<dyn FnOnce() + 'static>,
50 ) -> *mut Self {
51 let boxed_self = Box::new(Self {
52 cpp_proxy: std::ptr::null_mut(),
53 rust_obj: RustObjAccess::new(rust_obj.clone()),
54 on_drop,
55 });
56 let raw_self = Box::into_raw(boxed_self);
57 unsafe {
58 (*raw_self).cpp_proxy = match at_address {
59 Some(addr) => CppProxy::create_at(raw_self, metatype, addr),
60 None => CppProxy::create(raw_self, metatype),
61 }
62 };
63 raw_self
64 }
65
66 fn get_cpp_proxy(&self) -> *const CppProxy {
67 self.cpp_proxy
68 }
69
70 fn get_cpp_proxy_mut(&self) -> *mut CppProxy {
71 self.cpp_proxy
72 }
73
74 fn emit_signal(&self, mut_ref: &mut Adapter, signal_name: &str, argv: &[*const u8]) {
75 call_cpp_impl!(mut self, mut_ref, emit_signal(signal_name, argv))
76 }
77
78 fn with_rust_ref<R, F: FnOnce(&Adapter) -> R>(&self, f: F) -> R {
79 self.rust_obj
80 .try_call_rust_with_handle(|adapter| f(adapter))
81 .expect("Failed to access Rust object via shared handle")
82 }
83
84 fn with_rust_ref_mut<R, F: FnOnce(&mut Adapter) -> R>(&self, f: F) -> R {
85 self.rust_obj
86 .try_call_rust_with_handle_mut(|adapter| f(adapter))
87 .expect("Failed to access Rust object via mutable handle")
88 }
89
90 fn get_rust_object_rc(&self) -> Rc<RefCell<Adapter>> {
91 self.rust_obj.get_rc()
92 }
93}
94
95impl<CppProxy, Adapter> GenericRustProxy<CppProxy, Adapter>
96where
97 CppProxy: QCppProxy<ProxyRustType = Self>,
98 Adapter: ?Sized + DispatchMetaCall,
99{
100 pub unsafe fn drop_self(self_ptr: *mut Self) {
109 let boxed_self = unsafe { Box::from_raw(self_ptr) };
110 (boxed_self.on_drop)();
111 }
112
113 pub unsafe fn invoke_slot(&self, slot_id: u32, inputs: &[*const u8], outputs: &[*mut u8]) {
119 unsafe { call_rust_trait_impl!(self, invoke_slot(slot_id, inputs, outputs)) }
120 }
121
122 pub unsafe fn invoke_slot_mut(&self, slot_id: u32, inputs: &[*const u8], outputs: &[*mut u8]) {
129 unsafe {call_rust_trait_impl!(mut self, invoke_slot_mut(slot_id, inputs, outputs)) }
130 }
131
132 pub unsafe fn read_property(&self, prop_id: u32) -> QVariant {
139 unsafe { call_rust_trait_impl!(self, read_property(prop_id)) }
140 }
141
142 pub unsafe fn write_property(&self, prop_id: u32, value: &QVariant) {
150 unsafe { call_rust_trait_impl!(mut self, write_property(prop_id, value)) }
151 }
152
153}
154
155#[macro_export]
156macro_rules! impl_qcpp_proxy {
157 ($cpp_proxy:ty, $rust_proxy:ty) => {
158 unsafe impl QCppProxy for $cpp_proxy {
161 type ProxyRustType = $rust_proxy;
162 fn get_static_meta_object() -> &'static QMetaObject {
163 Self::static_qmeta_object()
164 }
165 fn get_size() -> usize {
166 Self::size_of()
167 }
168 fn get_align() -> usize {
169 Self::align_of()
170 }
171 fn parser_status_cast() -> i32 {
172 Self::parser_status_cast()
173 }
174 unsafe fn create(rust_proxy: *mut Self::ProxyRustType, metaobject: &'static DynamicMetaObjectData) -> *mut Self {
175 unsafe { Self::create(rust_proxy, metaobject) }
176 }
177 unsafe fn create_at(rust_proxy: *mut Self::ProxyRustType, metaobject: &'static DynamicMetaObjectData, addr: *mut u8) -> *mut Self {
178 unsafe { Self::create_at(rust_proxy, metaobject, addr) }
179 }
180 fn emit_signal(self: std::pin::Pin<&mut Self>, signal_name: &str, argv: &[*const u8]) {
181 self.emit_signal_cpp(signal_name, argv)
182 }
183 }
184 };
185}