qtbridge_interfaces/qobject/
proxy_rust.rs

1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only
3
4use super::proxy_cpp_bridge::{QObjectProxyCpp, ffi};
5use crate::RustObjAccess;
6use crate::call_rust_trait_impl;
7use qtbridge_runtime::qrustproxy::{QRustProxy, ConstructionMode};
8use qtbridge_runtime::{DispatchMetaCall, QObjectHolder};
9use qtbridge_type_lib::{QMetaObject, QMetaType, QVariant};
10use std::cell::RefCell;
11use std::rc::Rc;
12
13/* QObject trait left out on purpose */
14
15pub trait QObjectAdapter: DispatchMetaCall {
16}
17
18impl<T> QObjectAdapter for T
19where T: QObjectHolder<ProxyRust = QObjectProxyRust> {}
20
21pub struct QObjectProxyRust {
22    cpp_proxy: *mut QObjectProxyCpp,
23    #[allow(dead_code)]
24    rust_obj: RustObjAccess<dyn QObjectAdapter>,
25    on_drop: Box<dyn FnOnce()>,
26}
27
28impl QRustProxy for QObjectProxyRust {
29
30    type ProxyCppType = QObjectProxyCpp;
31    type AdapterType = dyn QObjectAdapter;
32
33    fn new<OnDropFn: FnOnce() + 'static>(rust_obj: &Rc<RefCell<dyn QObjectAdapter>>, construct: ConstructionMode, on_drop: OnDropFn) -> *mut Self {
34        let boxed_self = Box::new(Self {
35            cpp_proxy: std::ptr::null_mut(),
36            rust_obj: match construct {
37                ConstructionMode::Strong | ConstructionMode::AtAddress(_) => RustObjAccess::new_strong(rust_obj.clone()),
38                ConstructionMode::Weak => RustObjAccess::new_weak(Rc::downgrade(rust_obj)),
39            },
40            on_drop: Box::new(on_drop),
41        });
42        let raw_self = Box::into_raw(boxed_self);
43
44        unsafe{ (*raw_self).cpp_proxy = match construct {
45            ConstructionMode::AtAddress(addr) => {
46                ffi::create_qobject_proxy_cpp_at(addr, raw_self)
47            }
48            ConstructionMode::Strong | ConstructionMode::Weak => {
49                ffi::create_qobject_proxy_cpp(raw_self)
50            }
51        }};
52        raw_self
53    }
54    fn get_static_meta_object() -> &'static QMetaObject {
55        ffi::static_qmeta_object_of_qobject_proxy_cpp()
56    }
57    fn get_size_of_cpp_proxy() -> usize {
58        ffi::size_of_qobject_proxy_cpp()
59    }
60    fn get_align_of_cpp_proxy() -> usize {
61        ffi::align_of_qobject_proxy_cpp()
62    }
63    fn get_qmetatype_list_of_cpp_proxy() -> QMetaType {
64        ffi::qmetatype_list_of_qobject_proxy_cpp()
65    }
66    fn get_cpp_proxy(&self) -> *const QObjectProxyCpp {
67        self.cpp_proxy as *const _
68    }
69    fn get_cpp_proxy_mut(&self) -> *mut QObjectProxyCpp {
70        self.cpp_proxy
71    }
72}
73
74impl QObjectProxyRust {
75    pub fn drop_self(self_ptr: *mut Self) {
76        let boxed_self = unsafe { Box::from_raw(self_ptr) };
77        (boxed_self.on_drop)();
78    }
79
80    pub fn invoke_slot(&self, slot_id: u32, inputs: &[*const u8], outputs: &[*mut u8]) {
81        call_rust_trait_impl!(self, invoke_slot(slot_id, inputs, outputs))
82    }
83    pub fn invoke_slot_mut(&mut self, slot_id: u32, inputs: &[*const u8], outputs: &[*mut u8]) {
84        call_rust_trait_impl!(mut self, invoke_slot_mut(slot_id, inputs, outputs))
85    }
86    pub fn read_property(&self, prop_id: u32) -> QVariant {
87        call_rust_trait_impl!(self, read_property(prop_id))
88    }
89    pub fn write_property(&mut self, prop_id: u32, value: &QVariant) {
90        call_rust_trait_impl!(mut self, write_property(prop_id, value))
91    }
92}