Skip to content

Commit f6c1f8c

Browse files
Add downcasting
1 parent 9f08e5a commit f6c1f8c

File tree

11 files changed

+181
-30
lines changed

11 files changed

+181
-30
lines changed

crates/cxx-qt-gen/src/generator/rust/qobject.rs

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::{
1616
naming::TypeNames,
1717
};
1818
use quote::{format_ident, quote};
19-
use syn::{parse_quote, Attribute, Ident, Result};
19+
use syn::{parse_quote, Attribute, Result};
2020

2121
impl GeneratedRustFragment {
2222
// Might need to be refactored to use a StructuredQObject instead (confirm with Leon)
@@ -30,11 +30,7 @@ impl GeneratedRustFragment {
3030
let namespace_idents = NamespaceName::from(qobject);
3131

3232
let mut generated = vec![
33-
generate_qobject_definitions(
34-
&qobject_names,
35-
qobject.base_class.clone(),
36-
type_names,
37-
)?,
33+
generate_qobject_definitions(&qobject_names, &qobject.cfgs)?,
3834
generate_rust_properties(
3935
&qobject.properties,
4036
&qobject_names,
@@ -67,18 +63,7 @@ impl GeneratedRustFragment {
6763
)?);
6864
}
6965

70-
generated.extend(vec![
71-
constructor::generate(
72-
&structured_qobject.constructors,
73-
&qobject_names,
74-
&namespace_idents,
75-
type_names,
76-
&qobject.cfgs,
77-
)?,
78-
cxxqttype::generate(&qobject_names, type_names, &qobject.cfgs)?,
79-
]);
8066
// Generate casting impl
81-
let mut blocks = GeneratedRustFragment::default();
8267
let base = structured_qobject
8368
.declaration
8469
.base_class
@@ -88,7 +73,7 @@ impl GeneratedRustFragment {
8873
.cloned()
8974
.unwrap_or(
9075
Name::new(format_ident!("QObject")).with_module(parse_quote! {::cxx_qt::qobject}),
91-
); // TODO! is this default module here causing the issues in the threading examples
76+
);
9277

9378
let base_unqualified = base.rust_unqualified();
9479
let base_qualified = base.rust_qualified();
@@ -98,39 +83,55 @@ impl GeneratedRustFragment {
9883
let (upcast_fn, upcast_fn_attrs, upcast_fn_qualified) = qobject_names
9984
.cxx_qt_ffi_method("upcastPtr")
10085
.into_cxx_parts();
101-
let fragment = GeneratedRustFragment {
86+
let (downcast_fn, downcast_fn_attrs, downcast_fn_qualified) = qobject_names
87+
.cxx_qt_ffi_method("downcastPtr")
88+
.into_cxx_parts();
89+
90+
generated.push(GeneratedRustFragment {
10291
cxx_mod_contents: vec![parse_quote! {
10392
extern "C++" {
10493
#[doc(hidden)]
10594
#(#upcast_fn_attrs)*
10695
unsafe fn #upcast_fn(thiz: *const #struct_name_unqualified) -> *const #base_unqualified;
96+
97+
#[doc(hidden)]
98+
#(#downcast_fn_attrs)*
99+
unsafe fn #downcast_fn(base: *const #base_unqualified) -> *const #struct_name_unqualified;
107100
}
108101
}],
109102
cxx_qt_mod_contents: vec![parse_quote! {
110103
impl ::cxx_qt::Upcast<#base_qualified> for #struct_name{
111104
unsafe fn upcast_ptr(this: *const Self) -> *const #base_qualified {
112105
#upcast_fn_qualified(this)
113106
}
107+
108+
unsafe fn from_base_ptr(base: *const #base_qualified) -> *const Self {
109+
#downcast_fn_qualified(base)
110+
}
114111
}
115112
}],
116-
};
113+
});
117114

118-
generated.push(fragment);
119-
generated.push(blocks);
120-
121-
generated.push(constructor::generate(
122-
&structured_qobject.constructors,
123-
&qobject_names,
124-
&namespace_idents,
125-
type_names,
126-
)?);
115+
generated.extend(vec![
116+
constructor::generate(
117+
&structured_qobject.constructors,
118+
&qobject_names,
119+
&namespace_idents,
120+
type_names,
121+
&qobject.cfgs,
122+
)?,
123+
cxxqttype::generate(&qobject_names, type_names, &qobject.cfgs)?,
124+
]);
127125

128126
Ok(GeneratedRustFragment::flatten(generated))
129127
}
130128
}
131129

132130
/// Generate the C++ and Rust CXX definitions for the QObject
133-
fn generate_qobject_definitions(qobject_idents: &QObjectNames) -> Result<GeneratedRustFragment> {
131+
fn generate_qobject_definitions(
132+
qobject_idents: &QObjectNames,
133+
cfgs: &[Attribute],
134+
) -> Result<GeneratedRustFragment> {
134135
let cpp_class_name_rust = &qobject_idents.name.rust_unqualified();
135136
let cpp_class_name_cpp = &qobject_idents.name.cxx_unqualified();
136137

@@ -264,6 +265,11 @@ mod tests {
264265
#[cxx_name = "upcastPtr"]
265266
#[namespace = "rust::cxxqt1"]
266267
unsafe fn cxx_qt_ffi_MyObject_upcastPtr(thiz: *const MyObject) -> *const QObject;
268+
269+
#[doc(hidden)]
270+
#[cxx_name = "downcastPtr"]
271+
#[namespace = "rust::cxxqt1"]
272+
unsafe fn cxx_qt_ffi_MyObject_downcastPtr(base: *const QObject) -> *const MyObject;
267273
}
268274
},
269275
);

crates/cxx-qt-gen/test_outputs/cfgs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include <cstdint>
4+
#include <cxx-qt/casting.h>
45
#include <cxx-qt/signalhandler.h>
56
#include <cxx-qt/type.h>
67

crates/cxx-qt-gen/test_outputs/cfgs.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,20 @@ mod ffi {
158158
self_value: Pin<&mut QObjectEnabled>,
159159
);
160160
}
161+
extern "C++" {
162+
#[doc(hidden)]
163+
#[cxx_name = "upcastPtr"]
164+
#[namespace = "rust::cxxqt1"]
165+
unsafe fn cxx_qt_ffi_QObjectEnabled_upcastPtr(
166+
thiz: *const QObjectEnabled,
167+
) -> *const QObject;
168+
#[doc(hidden)]
169+
#[cxx_name = "downcastPtr"]
170+
#[namespace = "rust::cxxqt1"]
171+
unsafe fn cxx_qt_ffi_QObjectEnabled_downcastPtr(
172+
base: *const QObject,
173+
) -> *const QObjectEnabled;
174+
}
161175
extern "Rust" {
162176
#[cxx_name = "createRs"]
163177
#[namespace = "cxx_qt_QObjectEnabled"]
@@ -284,6 +298,20 @@ mod ffi {
284298
self_value: Pin<&mut QObjectDisabled>,
285299
);
286300
}
301+
extern "C++" {
302+
#[doc(hidden)]
303+
#[cxx_name = "upcastPtr"]
304+
#[namespace = "rust::cxxqt1"]
305+
unsafe fn cxx_qt_ffi_QObjectDisabled_upcastPtr(
306+
thiz: *const QObjectDisabled,
307+
) -> *const QObject;
308+
#[doc(hidden)]
309+
#[cxx_name = "downcastPtr"]
310+
#[namespace = "rust::cxxqt1"]
311+
unsafe fn cxx_qt_ffi_QObjectDisabled_downcastPtr(
312+
base: *const QObject,
313+
) -> *const QObjectDisabled;
314+
}
287315
extern "Rust" {
288316
#[cxx_name = "createRs"]
289317
#[namespace = "cxx_qt_QObjectDisabled"]
@@ -450,6 +478,11 @@ mod ffi {
450478
self_value: Pin<&mut QObjectExternDisabled>,
451479
);
452480
}
481+
extern "C++" {
482+
#[doc(hidden)]
483+
#[namespace = ""]
484+
type QObject = cxx_qt::qobject::QObject;
485+
}
453486
}
454487
#[cfg(not(enabled))]
455488
impl ffi::QObjectEnabled {
@@ -599,6 +632,14 @@ cxx_qt::static_assertions::assert_eq_size!(
599632
cxx_qt::signalhandler::CxxQtSignalHandler<QObjectEnabledCxxQtSignalClosuresignal_enabled>,
600633
[usize; 2]
601634
);
635+
impl ::cxx_qt::Upcast<::cxx_qt::qobject::QObject> for ffi::QObjectEnabled {
636+
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::qobject::QObject {
637+
ffi::cxx_qt_ffi_QObjectEnabled_upcastPtr(this)
638+
}
639+
unsafe fn from_base_ptr(base: *const ::cxx_qt::qobject::QObject) -> *const Self {
640+
ffi::cxx_qt_ffi_QObjectEnabled_downcastPtr(base)
641+
}
642+
}
602643
#[doc(hidden)]
603644
#[allow(clippy::unnecessary_box_returns)]
604645
#[cfg(enabled)]
@@ -770,6 +811,14 @@ cxx_qt::static_assertions::assert_eq_size!(
770811
cxx_qt::signalhandler::CxxQtSignalHandler<QObjectDisabledCxxQtSignalClosuresignal_enabled>,
771812
[usize; 2]
772813
);
814+
impl ::cxx_qt::Upcast<::cxx_qt::qobject::QObject> for ffi::QObjectDisabled {
815+
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::qobject::QObject {
816+
ffi::cxx_qt_ffi_QObjectDisabled_upcastPtr(this)
817+
}
818+
unsafe fn from_base_ptr(base: *const ::cxx_qt::qobject::QObject) -> *const Self {
819+
ffi::cxx_qt_ffi_QObjectDisabled_downcastPtr(base)
820+
}
821+
}
773822
#[doc(hidden)]
774823
#[allow(clippy::unnecessary_box_returns)]
775824
#[cfg(not(enabled))]

crates/cxx-qt-gen/test_outputs/inheritance.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ mod inheritance {
6767
#[namespace = "rust::cxxqt1"]
6868
unsafe fn cxx_qt_ffi_MyObject_upcastPtr(thiz: *const MyObject)
6969
-> *const QAbstractItemModel;
70+
#[doc(hidden)]
71+
#[cxx_name = "downcastPtr"]
72+
#[namespace = "rust::cxxqt1"]
73+
unsafe fn cxx_qt_ffi_MyObject_downcastPtr(
74+
base: *const QAbstractItemModel,
75+
) -> *const MyObject;
7076
}
7177
extern "Rust" {
7278
#[cxx_name = "createRs"]
@@ -90,6 +96,9 @@ impl ::cxx_qt::Upcast<inheritance::QAbstractItemModel> for inheritance::MyObject
9096
unsafe fn upcast_ptr(this: *const Self) -> *const inheritance::QAbstractItemModel {
9197
inheritance::cxx_qt_ffi_MyObject_upcastPtr(this)
9298
}
99+
unsafe fn from_base_ptr(base: *const inheritance::QAbstractItemModel) -> *const Self {
100+
inheritance::cxx_qt_ffi_MyObject_downcastPtr(base)
101+
}
93102
}
94103
#[doc(hidden)]
95104
#[allow(clippy::unnecessary_box_returns)]

crates/cxx-qt-gen/test_outputs/invokables.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ mod ffi {
151151
#[cxx_name = "upcastPtr"]
152152
#[namespace = "rust::cxxqt1"]
153153
unsafe fn cxx_qt_ffi_MyObject_upcastPtr(thiz: *const MyObject) -> *const QObject;
154+
#[doc(hidden)]
155+
#[cxx_name = "downcastPtr"]
156+
#[namespace = "rust::cxxqt1"]
157+
unsafe fn cxx_qt_ffi_MyObject_downcastPtr(base: *const QObject) -> *const MyObject;
154158
}
155159
#[namespace = "cxx_qt::my_object::cxx_qt_MyObject"]
156160
#[cxx_name = "CxxQtConstructorArguments0"]
@@ -315,6 +319,9 @@ impl ::cxx_qt::Upcast<::cxx_qt::qobject::QObject> for ffi::MyObject {
315319
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::qobject::QObject {
316320
ffi::cxx_qt_ffi_MyObject_upcastPtr(this)
317321
}
322+
unsafe fn from_base_ptr(base: *const ::cxx_qt::qobject::QObject) -> *const Self {
323+
ffi::cxx_qt_ffi_MyObject_downcastPtr(base)
324+
}
318325
}
319326
#[doc(hidden)]
320327
pub fn route_arguments_MyObject_0<'a>(

crates/cxx-qt-gen/test_outputs/passthrough_and_naming.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ pub mod ffi {
170170
#[cxx_name = "upcastPtr"]
171171
#[namespace = "rust::cxxqt1"]
172172
unsafe fn cxx_qt_ffi_MyObject_upcastPtr(thiz: *const MyObject) -> *const QStringListModel;
173+
#[doc(hidden)]
174+
#[cxx_name = "downcastPtr"]
175+
#[namespace = "rust::cxxqt1"]
176+
unsafe fn cxx_qt_ffi_MyObject_downcastPtr(base: *const QStringListModel)
177+
-> *const MyObject;
173178
}
174179
extern "Rust" {
175180
#[cxx_name = "createRs"]
@@ -292,6 +297,10 @@ pub mod ffi {
292297
#[cxx_name = "upcastPtr"]
293298
#[namespace = "rust::cxxqt1"]
294299
unsafe fn cxx_qt_ffi_SecondObject_upcastPtr(thiz: *const SecondObject) -> *const QObject;
300+
#[doc(hidden)]
301+
#[cxx_name = "downcastPtr"]
302+
#[namespace = "rust::cxxqt1"]
303+
unsafe fn cxx_qt_ffi_SecondObject_downcastPtr(base: *const QObject) -> *const SecondObject;
295304
}
296305
extern "Rust" {
297306
#[cxx_name = "createRs"]
@@ -334,6 +343,10 @@ pub mod ffi {
334343
#[cxx_name = "upcastPtr"]
335344
#[namespace = "rust::cxxqt1"]
336345
unsafe fn cxx_qt_ffi_MyCxxName_upcastPtr(thiz: *const MyRustName) -> *const QObject;
346+
#[doc(hidden)]
347+
#[cxx_name = "downcastPtr"]
348+
#[namespace = "rust::cxxqt1"]
349+
unsafe fn cxx_qt_ffi_MyCxxName_downcastPtr(base: *const QObject) -> *const MyRustName;
337350
}
338351
extern "Rust" {
339352
#[cxx_name = "createRs"]
@@ -613,6 +626,9 @@ impl ::cxx_qt::Upcast<ffi::QStringListModel> for ffi::MyObject {
613626
unsafe fn upcast_ptr(this: *const Self) -> *const ffi::QStringListModel {
614627
ffi::cxx_qt_ffi_MyObject_upcastPtr(this)
615628
}
629+
unsafe fn from_base_ptr(base: *const ffi::QStringListModel) -> *const Self {
630+
ffi::cxx_qt_ffi_MyObject_downcastPtr(base)
631+
}
616632
}
617633
#[doc(hidden)]
618634
#[allow(clippy::unnecessary_box_returns)]
@@ -784,6 +800,9 @@ impl ::cxx_qt::Upcast<::cxx_qt::qobject::QObject> for ffi::SecondObject {
784800
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::qobject::QObject {
785801
ffi::cxx_qt_ffi_SecondObject_upcastPtr(this)
786802
}
803+
unsafe fn from_base_ptr(base: *const ::cxx_qt::qobject::QObject) -> *const Self {
804+
ffi::cxx_qt_ffi_SecondObject_downcastPtr(base)
805+
}
787806
}
788807
#[doc(hidden)]
789808
#[allow(clippy::unnecessary_box_returns)]
@@ -809,6 +828,9 @@ impl ::cxx_qt::Upcast<::cxx_qt::qobject::QObject> for ffi::MyRustName {
809828
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::qobject::QObject {
810829
ffi::cxx_qt_ffi_MyCxxName_upcastPtr(this)
811830
}
831+
unsafe fn from_base_ptr(base: *const ::cxx_qt::qobject::QObject) -> *const Self {
832+
ffi::cxx_qt_ffi_MyCxxName_downcastPtr(base)
833+
}
812834
}
813835
#[doc(hidden)]
814836
#[allow(clippy::unnecessary_box_returns)]

crates/cxx-qt-gen/test_outputs/properties.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,10 @@ mod ffi {
394394
#[cxx_name = "upcastPtr"]
395395
#[namespace = "rust::cxxqt1"]
396396
unsafe fn cxx_qt_ffi_MyObject_upcastPtr(thiz: *const MyObject) -> *const QObject;
397+
#[doc(hidden)]
398+
#[cxx_name = "downcastPtr"]
399+
#[namespace = "rust::cxxqt1"]
400+
unsafe fn cxx_qt_ffi_MyObject_downcastPtr(base: *const QObject) -> *const MyObject;
397401
}
398402
extern "Rust" {
399403
#[cxx_name = "createRs"]
@@ -1052,6 +1056,9 @@ impl ::cxx_qt::Upcast<::cxx_qt::qobject::QObject> for ffi::MyObject {
10521056
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::qobject::QObject {
10531057
ffi::cxx_qt_ffi_MyObject_upcastPtr(this)
10541058
}
1059+
unsafe fn from_base_ptr(base: *const ::cxx_qt::qobject::QObject) -> *const Self {
1060+
ffi::cxx_qt_ffi_MyObject_downcastPtr(base)
1061+
}
10551062
}
10561063
#[doc(hidden)]
10571064
#[allow(clippy::unnecessary_box_returns)]

crates/cxx-qt-gen/test_outputs/qenum.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ mod ffi {
9595
#[cxx_name = "upcastPtr"]
9696
#[namespace = "rust::cxxqt1"]
9797
unsafe fn cxx_qt_ffi_MyObject_upcastPtr(thiz: *const MyObject) -> *const QObject;
98+
#[doc(hidden)]
99+
#[cxx_name = "downcastPtr"]
100+
#[namespace = "rust::cxxqt1"]
101+
unsafe fn cxx_qt_ffi_MyObject_downcastPtr(base: *const QObject) -> *const MyObject;
98102
}
99103
extern "Rust" {
100104
#[cxx_name = "createRs"]
@@ -135,6 +139,10 @@ mod ffi {
135139
#[cxx_name = "upcastPtr"]
136140
#[namespace = "rust::cxxqt1"]
137141
unsafe fn cxx_qt_ffi_CxxName_upcastPtr(thiz: *const MyRenamedObject) -> *const QObject;
142+
#[doc(hidden)]
143+
#[cxx_name = "downcastPtr"]
144+
#[namespace = "rust::cxxqt1"]
145+
unsafe fn cxx_qt_ffi_CxxName_downcastPtr(base: *const QObject) -> *const MyRenamedObject;
138146
}
139147
extern "Rust" {
140148
#[cxx_name = "createRs"]
@@ -165,6 +173,9 @@ impl ::cxx_qt::Upcast<::cxx_qt::qobject::QObject> for ffi::MyObject {
165173
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::qobject::QObject {
166174
ffi::cxx_qt_ffi_MyObject_upcastPtr(this)
167175
}
176+
unsafe fn from_base_ptr(base: *const ::cxx_qt::qobject::QObject) -> *const Self {
177+
ffi::cxx_qt_ffi_MyObject_downcastPtr(base)
178+
}
168179
}
169180
#[doc(hidden)]
170181
#[allow(clippy::unnecessary_box_returns)]
@@ -190,6 +201,9 @@ impl ::cxx_qt::Upcast<::cxx_qt::qobject::QObject> for ffi::MyRenamedObject {
190201
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::qobject::QObject {
191202
ffi::cxx_qt_ffi_CxxName_upcastPtr(this)
192203
}
204+
unsafe fn from_base_ptr(base: *const ::cxx_qt::qobject::QObject) -> *const Self {
205+
ffi::cxx_qt_ffi_CxxName_downcastPtr(base)
206+
}
193207
}
194208
#[doc(hidden)]
195209
#[allow(clippy::unnecessary_box_returns)]

0 commit comments

Comments
 (0)