qtbridge_runtime/
qml_register.rs

1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only
3
4use crate::QObjectHolder;
5use crate::QMetaInfo;
6use crate::qrustproxy::ConstructionMode;
7use qtbridge_type_lib::QObject;
8use qtbridge_type_lib::QMetaTypeGet;
9pub trait QmlRegister : QMetaTypeGet + QMetaInfo + QObjectHolder + Default
10{
11    const URI: &str;
12    const ELEMENT_NAME: &str;
13    const MINOR_VERSION: u8;
14    const MAJOR_VERSION: u8;
15    const IS_SINGLETON: bool;
16
17    fn register() {
18        let meta_obj_data = <Self as QMetaInfo>::get_shared_dynamic_meta_object_data();
19        let meta_obj = unsafe {
20            meta_obj_data
21                .get_meta_object()
22                .as_ref()
23                .expect("Failed to get QMetaObject")
24        };
25
26        if Self::IS_SINGLETON {
27            qtbridge_type_lib::qml_register_singleton(
28                <Self as QMetaTypeGet>::get_qmetatype(),
29                monomorphize_singleton_ctor::<Self>(),
30                Self::URI.as_bytes(),
31                Self::MAJOR_VERSION,
32                Self::MINOR_VERSION,
33                Self::ELEMENT_NAME.as_bytes(),
34                meta_obj,
35            )
36        } else {
37            qtbridge_type_lib::qml_register_element(
38                Self::get_qmetatype(),
39                Self::get_qmetatype_list_of_cpp_proxy(),
40                Self::get_size_of_cpp_proxy() as u32,
41                monomorphize_element_ctor::<Self>(),
42                Self::URI.as_bytes(),
43                Self::MAJOR_VERSION,
44                Self::MINOR_VERSION,
45                Self::ELEMENT_NAME.as_bytes(),
46                meta_obj,
47            );
48        }
49    }
50}
51
52fn element_ctor<T: QmlRegister>(addr: *mut u8, _userdata: *mut u8) {
53    let instance = std::rc::Rc::new(std::cell::RefCell::new(T::default()));
54    T::register_instance_in_map(instance.clone(), ConstructionMode::AtAddress(addr));
55    T::set_dynamic_meta(&instance);
56}
57
58fn singleton_ctor<T: QmlRegister>() -> *mut QObject {
59    let instance = std::rc::Rc::new(std::cell::RefCell::new(T::default()));
60    T::register_instance_in_map(instance.clone(), ConstructionMode::Strong);
61    T::set_dynamic_meta(&instance);
62    std::ptr::from_mut(T::get_qobject(&instance.borrow()))
63}
64
65fn monomorphize_element_ctor<T: QmlRegister>() -> usize {
66    extern "C" fn default_ctor<T: QmlRegister>(addr: *mut u8, userdata: *mut u8) {
67        element_ctor::<T>(addr, userdata)
68    }
69    default_ctor::<T> as *const () as usize
70}
71
72fn monomorphize_singleton_ctor<T: QmlRegister>() -> usize {
73    extern "C" fn default_ctor<T: QmlRegister>() -> *mut QObject {
74        singleton_ctor::<T>()
75    }
76    default_ctor::<T> as *const () as usize
77}