Skip to content

Commit

Permalink
WIP Add downcasting
Browse files Browse the repository at this point in the history
  • Loading branch information
BenFordTytherington committed Jan 16, 2025
1 parent 0b1b681 commit 59af069
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 0 deletions.
7 changes: 7 additions & 0 deletions crates/cxx-qt-gen/src/generator/rust/qobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,14 @@ impl GeneratedRustFragment {
unsafe fn upcast_ptr(this: *const Self) -> *const #base_qualified {
#upcast_fn_qualified(this)
}

unsafe fn from_base_ptr(base: *const T) -> Option<*const Self> {
None //TODO! placeholder, use the right dynamic_cast function
}
}
},
quote! {
impl ::cxx_qt::Downcast for #struct_name {}
}],
};
blocks
Expand Down
4 changes: 4 additions & 0 deletions crates/cxx-qt-gen/test_outputs/inheritance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,11 @@ impl ::cxx_qt::Upcast<inheritance::QAbstractItemModel> for inheritance::MyObject
unsafe fn upcast_ptr(this: *const Self) -> *const inheritance::QAbstractItemModel {
inheritance::cxx_qt_ffi_MyObject_upcastPtr(this)
}
unsafe fn from_base_ptr(base: *const T) -> Option<*const Self> {
None
}
}
impl ::cxx_qt::Downcast for inheritance::MyObject {}
#[doc(hidden)]
pub fn create_rs_MyObjectRust() -> std::boxed::Box<MyObjectRust> {
std::boxed::Box::new(core::default::Default::default())
Expand Down
4 changes: 4 additions & 0 deletions crates/cxx-qt-gen/test_outputs/invokables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,11 @@ impl ::cxx_qt::Upcast<::cxx_qt::qobject::QObject> for ffi::MyObject {
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::qobject::QObject {
ffi::cxx_qt_ffi_MyObject_upcastPtr(this)
}
unsafe fn from_base_ptr(base: *const T) -> Option<*const Self> {
None
}
}
impl ::cxx_qt::Downcast for ffi::MyObject {}
#[doc(hidden)]
pub fn route_arguments_MyObject_0<'a>(
arg0: i32,
Expand Down
12 changes: 12 additions & 0 deletions crates/cxx-qt-gen/test_outputs/passthrough_and_naming.rs
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,11 @@ impl ::cxx_qt::Upcast<ffi::QStringListModel> for ffi::MyObject {
unsafe fn upcast_ptr(this: *const Self) -> *const ffi::QStringListModel {
ffi::cxx_qt_ffi_MyObject_upcastPtr(this)
}
unsafe fn from_base_ptr(base: *const T) -> Option<*const Self> {
None
}
}
impl ::cxx_qt::Downcast for ffi::MyObject {}
#[doc(hidden)]
pub fn create_rs_MyObjectRust() -> std::boxed::Box<MyObjectRust> {
std::boxed::Box::new(core::default::Default::default())
Expand Down Expand Up @@ -782,7 +786,11 @@ impl ::cxx_qt::Upcast<::cxx_qt::qobject::QObject> for ffi::SecondObject {
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::qobject::QObject {
ffi::cxx_qt_ffi_SecondObject_upcastPtr(this)
}
unsafe fn from_base_ptr(base: *const T) -> Option<*const Self> {
None
}
}
impl ::cxx_qt::Downcast for ffi::SecondObject {}
#[doc(hidden)]
pub fn create_rs_SecondObjectRust() -> std::boxed::Box<SecondObjectRust> {
std::boxed::Box::new(core::default::Default::default())
Expand All @@ -806,7 +814,11 @@ impl ::cxx_qt::Upcast<::cxx_qt::qobject::QObject> for ffi::MyRustName {
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::qobject::QObject {
ffi::cxx_qt_ffi_MyCxxName_upcastPtr(this)
}
unsafe fn from_base_ptr(base: *const T) -> Option<*const Self> {
None
}
}
impl ::cxx_qt::Downcast for ffi::MyRustName {}
#[doc(hidden)]
pub fn create_rs_ThirdObjectRust() -> std::boxed::Box<ThirdObjectRust> {
std::boxed::Box::new(core::default::Default::default())
Expand Down
4 changes: 4 additions & 0 deletions crates/cxx-qt-gen/test_outputs/properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,11 @@ impl ::cxx_qt::Upcast<::cxx_qt::qobject::QObject> for ffi::MyObject {
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::qobject::QObject {
ffi::cxx_qt_ffi_MyObject_upcastPtr(this)
}
unsafe fn from_base_ptr(base: *const T) -> Option<*const Self> {
None
}
}
impl ::cxx_qt::Downcast for ffi::MyObject {}
#[doc(hidden)]
pub fn create_rs_MyObjectRust() -> std::boxed::Box<MyObjectRust> {
std::boxed::Box::new(core::default::Default::default())
Expand Down
8 changes: 8 additions & 0 deletions crates/cxx-qt-gen/test_outputs/qenum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,11 @@ impl ::cxx_qt::Upcast<::cxx_qt::qobject::QObject> for ffi::MyObject {
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::qobject::QObject {
ffi::cxx_qt_ffi_MyObject_upcastPtr(this)
}
unsafe fn from_base_ptr(base: *const T) -> Option<*const Self> {
None
}
}
impl ::cxx_qt::Downcast for ffi::MyObject {}
#[doc(hidden)]
pub fn create_rs_MyObjectRust() -> std::boxed::Box<MyObjectRust> {
std::boxed::Box::new(core::default::Default::default())
Expand All @@ -188,7 +192,11 @@ impl ::cxx_qt::Upcast<::cxx_qt::qobject::QObject> for ffi::MyRenamedObject {
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::qobject::QObject {
ffi::cxx_qt_ffi_CxxName_upcastPtr(this)
}
unsafe fn from_base_ptr(base: *const T) -> Option<*const Self> {
None
}
}
impl ::cxx_qt::Downcast for ffi::MyRenamedObject {}
#[doc(hidden)]
pub fn create_rs_InternalObject() -> std::boxed::Box<InternalObject> {
std::boxed::Box::new(core::default::Default::default())
Expand Down
4 changes: 4 additions & 0 deletions crates/cxx-qt-gen/test_outputs/signals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,11 @@ impl ::cxx_qt::Upcast<::cxx_qt::qobject::QObject> for ffi::MyObject {
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::qobject::QObject {
ffi::cxx_qt_ffi_MyObject_upcastPtr(this)
}
unsafe fn from_base_ptr(base: *const T) -> Option<*const Self> {
None
}
}
impl ::cxx_qt::Downcast for ffi::MyObject {}
#[doc(hidden)]
pub fn create_rs_MyObjectRust() -> std::boxed::Box<MyObjectRust> {
std::boxed::Box::new(core::default::Default::default())
Expand Down
2 changes: 2 additions & 0 deletions crates/cxx-qt/include/casting.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ upcastPtr(const Sub* sub)
return static_cast<const Base*>(sub);
}

// TODO! add base_ptr downcasting function here

}
12 changes: 12 additions & 0 deletions crates/cxx-qt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ pub trait Upcast<T> {
/// Internal function, Should not be implemented manually
unsafe fn upcast_ptr(this: *const Self) -> *const T;

#[doc(hidden)]
/// Internal function, Should not be implemented manually
unsafe fn from_base_ptr(base: *const T) -> Option<*const Self>;

/// Upcast a reference to a reference to the base class
fn upcast(&self) -> &T {
let ptr = self as *const Self;
Expand Down Expand Up @@ -160,6 +164,14 @@ pub trait Upcast<T> {
}
}

/// Trait for downcasting to a subclass, provided the subclass implements Upcast to this type
pub trait Downcast: Sized {
/// Downcast to a subclass of this, given that the subclass upcasts to this type
fn downcast<Sub: Upcast<Self>>(&self) -> Option<&Sub> {
unsafe { Sub::from_base_ptr(self as *const Self).map(|sub| &*sub) }
}
}

/// This trait can be implemented on any [CxxQtType] to define a
/// custom constructor in C++ for the QObject.
///
Expand Down

0 comments on commit 59af069

Please sign in to comment.