Skip to content

Commit 2cea6c4

Browse files
Add Transitive casting and testing code
1 parent 68651a3 commit 2cea6c4

File tree

4 files changed

+44
-46
lines changed

4 files changed

+44
-46
lines changed

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

-6
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,6 @@ impl GeneratedRustFragment {
8989
}
9090
}
9191
},
92-
// Add back once we figure out the bug with QObject, for automatic transitive casts
93-
// parse_quote! {
94-
// unsafe impl ::cxx_qt::MainCast for #struct_name {
95-
// type Base = #base_qualified;
96-
// }
97-
// }
9892
],
9993
})
10094
}

crates/cxx-qt/src/lib.rs

-26
Original file line numberDiff line numberDiff line change
@@ -178,32 +178,6 @@ pub unsafe trait Upcast<T> {
178178
}
179179
}
180180

181-
/// Docs
182-
pub unsafe trait MainCast: Upcast<Self::Base> {
183-
/// The first parent of the Type
184-
type Base;
185-
}
186-
187-
unsafe impl<T, A, B> Upcast<B> for T
188-
where
189-
T: MainCast<Base = A>,
190-
A: MainCast<Base = B>,
191-
{
192-
unsafe fn upcast_ptr(this: *const Self) -> *const B {
193-
let base = Self::upcast_ptr(this);
194-
A::upcast_ptr(base)
195-
}
196-
197-
unsafe fn from_base_ptr(base: *const B) -> *const Self {
198-
let base = A::from_base_ptr(base);
199-
if base.is_null() {
200-
std::ptr::null()
201-
} else {
202-
Self::from_base_ptr(base)
203-
}
204-
}
205-
}
206-
207181
/// This trait is automatically implemented by CXX-Qt and you most likely do not need to manually implement it.
208182
/// Trait for downcasting to a subclass, provided the subclass implements [Upcast] to this type.
209183
/// Returns `None` in cases where `Sub` isn't a child class of `Self`.

examples/qml_features/rust/src/custom_base_class.rs

+44-3
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@
1010
#[cxx_qt::bridge]
1111
pub mod qobject {
1212
// ANCHOR: book_base_include
13-
unsafe extern "C++" {
13+
unsafe extern "C++Qt" {
1414
include!(<QtCore/QAbstractListModel>);
1515
/// Base for Qt type
16+
#[qobject]
1617
type QAbstractListModel;
1718
}
1819
// ANCHOR_END: book_base_include
@@ -272,11 +273,44 @@ pub mod qobject {
272273
}
273274
}
274275

275-
use crate::custom_base_class::qobject::CustomBaseClass;
276+
macro_rules! impl_transitive_cast {
277+
($first:ty, $second:ty, $third:ty) => {
278+
unsafe impl cxx_qt::Upcast<$third> for $first {
279+
unsafe fn upcast_ptr(this: *const Self) -> *const $third {
280+
let base = Self::upcast_ptr(this);
281+
<$second as Upcast<$third>>::upcast_ptr(base)
282+
}
283+
284+
unsafe fn from_base_ptr(base: *const $third) -> *const Self {
285+
let base = <$second as Upcast<$third>>::from_base_ptr(base);
286+
if base.is_null() {
287+
std::ptr::null()
288+
} else {
289+
Self::from_base_ptr(base)
290+
}
291+
}
292+
}
293+
};
294+
}
295+
296+
macro_rules! chain_cast {
297+
($first:ty, $second:ty, $third:ty) => {
298+
impl_transitive_cast!($first, $second, $third);
299+
};
300+
301+
($first:ty, $second:ty, $third:ty, $($rest:ty),*) => {
302+
impl_transitive_cast!($first, $second, $third);
303+
$(impl_transitive_cast!($first, $third, $rest);)*
304+
};
305+
}
306+
307+
use crate::custom_base_class::qobject::{CustomBaseClass, AbstractBaseClass, QAbstractListModel, QObject};
276308
use core::pin::Pin;
277-
use cxx_qt::{CxxQtType, Threading};
309+
use cxx_qt::{CxxQtType, Threading, Upcast};
278310
use cxx_qt_lib::{QByteArray, QHash, QHashPair_i32_QByteArray, QModelIndex, QVariant, QVector};
279311

312+
chain_cast!(CustomBaseClass, AbstractBaseClass, QAbstractListModel, QObject);
313+
280314
impl Default for qobject::State {
281315
fn default() -> Self {
282316
Self::Idle
@@ -297,9 +331,16 @@ pub struct CustomBaseClassRust {
297331
pub(crate) vector: Vec<(u32, f64)>,
298332
}
299333

334+
300335
impl qobject::CustomBaseClass {
301336
/// Virtual method for logging type
302337
pub fn log(self: &CustomBaseClass) {
338+
let _abs: &AbstractBaseClass = self.upcast();
339+
let _qabs: &QAbstractListModel = self.upcast();
340+
let qobj: &QObject = self.upcast();
341+
342+
qobj.dump_object_info();
343+
303344
println!(
304345
"state: {}\npending adds: {}\nid: {}\nvector: {:?}\n",
305346
self.state.repr, self.pending_adds, self.id, self.vector

examples/qml_minimal/qml/main.qml

-11
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,6 @@ ApplicationWindow {
2828
string: qsTr("My String with my number: %1").arg(myObject.number)
2929
}
3030

31-
A {
32-
id: a
33-
number: 10
34-
}
35-
3631
Column {
3732
anchors.fill: parent
3833
anchors.margins: 10
@@ -60,12 +55,6 @@ ApplicationWindow {
6055
onClicked: myObject.sayHi(myObject.string, myObject.number)
6156
}
6257

63-
Button {
64-
text: qsTr("Test A")
65-
66-
onClicked: a.test()
67-
}
68-
6958
Button {
7059
text: qsTr("Quit")
7160

0 commit comments

Comments
 (0)