Skip to content

Commit

Permalink
Add downcasting
Browse files Browse the repository at this point in the history
  • Loading branch information
BenFordTytherington committed Feb 7, 2025
1 parent 9f08e5a commit f6c1f8c
Show file tree
Hide file tree
Showing 11 changed files with 181 additions and 30 deletions.
66 changes: 36 additions & 30 deletions crates/cxx-qt-gen/src/generator/rust/qobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
naming::TypeNames,
};
use quote::{format_ident, quote};
use syn::{parse_quote, Attribute, Ident, Result};
use syn::{parse_quote, Attribute, Result};

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

let mut generated = vec![
generate_qobject_definitions(
&qobject_names,
qobject.base_class.clone(),
type_names,
)?,
generate_qobject_definitions(&qobject_names, &qobject.cfgs)?,
generate_rust_properties(
&qobject.properties,
&qobject_names,
Expand Down Expand Up @@ -67,18 +63,7 @@ impl GeneratedRustFragment {
)?);
}

generated.extend(vec![
constructor::generate(
&structured_qobject.constructors,
&qobject_names,
&namespace_idents,
type_names,
&qobject.cfgs,
)?,
cxxqttype::generate(&qobject_names, type_names, &qobject.cfgs)?,
]);
// Generate casting impl
let mut blocks = GeneratedRustFragment::default();
let base = structured_qobject
.declaration
.base_class
Expand All @@ -88,7 +73,7 @@ impl GeneratedRustFragment {
.cloned()
.unwrap_or(
Name::new(format_ident!("QObject")).with_module(parse_quote! {::cxx_qt::qobject}),
); // TODO! is this default module here causing the issues in the threading examples
);

let base_unqualified = base.rust_unqualified();
let base_qualified = base.rust_qualified();
Expand All @@ -98,39 +83,55 @@ impl GeneratedRustFragment {
let (upcast_fn, upcast_fn_attrs, upcast_fn_qualified) = qobject_names
.cxx_qt_ffi_method("upcastPtr")
.into_cxx_parts();
let fragment = GeneratedRustFragment {
let (downcast_fn, downcast_fn_attrs, downcast_fn_qualified) = qobject_names
.cxx_qt_ffi_method("downcastPtr")
.into_cxx_parts();

generated.push(GeneratedRustFragment {
cxx_mod_contents: vec![parse_quote! {
extern "C++" {
#[doc(hidden)]
#(#upcast_fn_attrs)*
unsafe fn #upcast_fn(thiz: *const #struct_name_unqualified) -> *const #base_unqualified;

#[doc(hidden)]
#(#downcast_fn_attrs)*
unsafe fn #downcast_fn(base: *const #base_unqualified) -> *const #struct_name_unqualified;
}
}],
cxx_qt_mod_contents: vec![parse_quote! {
impl ::cxx_qt::Upcast<#base_qualified> for #struct_name{
unsafe fn upcast_ptr(this: *const Self) -> *const #base_qualified {
#upcast_fn_qualified(this)
}

unsafe fn from_base_ptr(base: *const #base_qualified) -> *const Self {
#downcast_fn_qualified(base)
}
}
}],
};
});

generated.push(fragment);
generated.push(blocks);

generated.push(constructor::generate(
&structured_qobject.constructors,
&qobject_names,
&namespace_idents,
type_names,
)?);
generated.extend(vec![
constructor::generate(
&structured_qobject.constructors,
&qobject_names,
&namespace_idents,
type_names,
&qobject.cfgs,
)?,
cxxqttype::generate(&qobject_names, type_names, &qobject.cfgs)?,
]);

Ok(GeneratedRustFragment::flatten(generated))
}
}

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

Expand Down Expand Up @@ -264,6 +265,11 @@ mod tests {
#[cxx_name = "upcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_MyObject_upcastPtr(thiz: *const MyObject) -> *const QObject;

#[doc(hidden)]
#[cxx_name = "downcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_MyObject_downcastPtr(base: *const QObject) -> *const MyObject;
}
},
);
Expand Down
1 change: 1 addition & 0 deletions crates/cxx-qt-gen/test_outputs/cfgs.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <cstdint>
#include <cxx-qt/casting.h>
#include <cxx-qt/signalhandler.h>
#include <cxx-qt/type.h>

Expand Down
49 changes: 49 additions & 0 deletions crates/cxx-qt-gen/test_outputs/cfgs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,20 @@ mod ffi {
self_value: Pin<&mut QObjectEnabled>,
);
}
extern "C++" {
#[doc(hidden)]
#[cxx_name = "upcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_QObjectEnabled_upcastPtr(
thiz: *const QObjectEnabled,
) -> *const QObject;
#[doc(hidden)]
#[cxx_name = "downcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_QObjectEnabled_downcastPtr(
base: *const QObject,
) -> *const QObjectEnabled;
}
extern "Rust" {
#[cxx_name = "createRs"]
#[namespace = "cxx_qt_QObjectEnabled"]
Expand Down Expand Up @@ -284,6 +298,20 @@ mod ffi {
self_value: Pin<&mut QObjectDisabled>,
);
}
extern "C++" {
#[doc(hidden)]
#[cxx_name = "upcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_QObjectDisabled_upcastPtr(
thiz: *const QObjectDisabled,
) -> *const QObject;
#[doc(hidden)]
#[cxx_name = "downcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_QObjectDisabled_downcastPtr(
base: *const QObject,
) -> *const QObjectDisabled;
}
extern "Rust" {
#[cxx_name = "createRs"]
#[namespace = "cxx_qt_QObjectDisabled"]
Expand Down Expand Up @@ -450,6 +478,11 @@ mod ffi {
self_value: Pin<&mut QObjectExternDisabled>,
);
}
extern "C++" {
#[doc(hidden)]
#[namespace = ""]
type QObject = cxx_qt::qobject::QObject;
}
}
#[cfg(not(enabled))]
impl ffi::QObjectEnabled {
Expand Down Expand Up @@ -599,6 +632,14 @@ cxx_qt::static_assertions::assert_eq_size!(
cxx_qt::signalhandler::CxxQtSignalHandler<QObjectEnabledCxxQtSignalClosuresignal_enabled>,
[usize; 2]
);
impl ::cxx_qt::Upcast<::cxx_qt::qobject::QObject> for ffi::QObjectEnabled {
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::qobject::QObject {
ffi::cxx_qt_ffi_QObjectEnabled_upcastPtr(this)
}
unsafe fn from_base_ptr(base: *const ::cxx_qt::qobject::QObject) -> *const Self {
ffi::cxx_qt_ffi_QObjectEnabled_downcastPtr(base)
}
}
#[doc(hidden)]
#[allow(clippy::unnecessary_box_returns)]
#[cfg(enabled)]
Expand Down Expand Up @@ -770,6 +811,14 @@ cxx_qt::static_assertions::assert_eq_size!(
cxx_qt::signalhandler::CxxQtSignalHandler<QObjectDisabledCxxQtSignalClosuresignal_enabled>,
[usize; 2]
);
impl ::cxx_qt::Upcast<::cxx_qt::qobject::QObject> for ffi::QObjectDisabled {
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::qobject::QObject {
ffi::cxx_qt_ffi_QObjectDisabled_upcastPtr(this)
}
unsafe fn from_base_ptr(base: *const ::cxx_qt::qobject::QObject) -> *const Self {
ffi::cxx_qt_ffi_QObjectDisabled_downcastPtr(base)
}
}
#[doc(hidden)]
#[allow(clippy::unnecessary_box_returns)]
#[cfg(not(enabled))]
Expand Down
9 changes: 9 additions & 0 deletions crates/cxx-qt-gen/test_outputs/inheritance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ mod inheritance {
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_MyObject_upcastPtr(thiz: *const MyObject)
-> *const QAbstractItemModel;
#[doc(hidden)]
#[cxx_name = "downcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_MyObject_downcastPtr(
base: *const QAbstractItemModel,
) -> *const MyObject;
}
extern "Rust" {
#[cxx_name = "createRs"]
Expand All @@ -90,6 +96,9 @@ 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 inheritance::QAbstractItemModel) -> *const Self {
inheritance::cxx_qt_ffi_MyObject_downcastPtr(base)
}
}
#[doc(hidden)]
#[allow(clippy::unnecessary_box_returns)]
Expand Down
7 changes: 7 additions & 0 deletions crates/cxx-qt-gen/test_outputs/invokables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ mod ffi {
#[cxx_name = "upcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_MyObject_upcastPtr(thiz: *const MyObject) -> *const QObject;
#[doc(hidden)]
#[cxx_name = "downcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_MyObject_downcastPtr(base: *const QObject) -> *const MyObject;
}
#[namespace = "cxx_qt::my_object::cxx_qt_MyObject"]
#[cxx_name = "CxxQtConstructorArguments0"]
Expand Down Expand Up @@ -315,6 +319,9 @@ 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 ::cxx_qt::qobject::QObject) -> *const Self {
ffi::cxx_qt_ffi_MyObject_downcastPtr(base)
}
}
#[doc(hidden)]
pub fn route_arguments_MyObject_0<'a>(
Expand Down
22 changes: 22 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 @@ -170,6 +170,11 @@ pub mod ffi {
#[cxx_name = "upcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_MyObject_upcastPtr(thiz: *const MyObject) -> *const QStringListModel;
#[doc(hidden)]
#[cxx_name = "downcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_MyObject_downcastPtr(base: *const QStringListModel)
-> *const MyObject;
}
extern "Rust" {
#[cxx_name = "createRs"]
Expand Down Expand Up @@ -292,6 +297,10 @@ pub mod ffi {
#[cxx_name = "upcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_SecondObject_upcastPtr(thiz: *const SecondObject) -> *const QObject;
#[doc(hidden)]
#[cxx_name = "downcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_SecondObject_downcastPtr(base: *const QObject) -> *const SecondObject;
}
extern "Rust" {
#[cxx_name = "createRs"]
Expand Down Expand Up @@ -334,6 +343,10 @@ pub mod ffi {
#[cxx_name = "upcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_MyCxxName_upcastPtr(thiz: *const MyRustName) -> *const QObject;
#[doc(hidden)]
#[cxx_name = "downcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_MyCxxName_downcastPtr(base: *const QObject) -> *const MyRustName;
}
extern "Rust" {
#[cxx_name = "createRs"]
Expand Down Expand Up @@ -613,6 +626,9 @@ 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 ffi::QStringListModel) -> *const Self {
ffi::cxx_qt_ffi_MyObject_downcastPtr(base)
}
}
#[doc(hidden)]
#[allow(clippy::unnecessary_box_returns)]
Expand Down Expand Up @@ -784,6 +800,9 @@ 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 ::cxx_qt::qobject::QObject) -> *const Self {
ffi::cxx_qt_ffi_SecondObject_downcastPtr(base)
}
}
#[doc(hidden)]
#[allow(clippy::unnecessary_box_returns)]
Expand All @@ -809,6 +828,9 @@ 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 ::cxx_qt::qobject::QObject) -> *const Self {
ffi::cxx_qt_ffi_MyCxxName_downcastPtr(base)
}
}
#[doc(hidden)]
#[allow(clippy::unnecessary_box_returns)]
Expand Down
7 changes: 7 additions & 0 deletions crates/cxx-qt-gen/test_outputs/properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,10 @@ mod ffi {
#[cxx_name = "upcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_MyObject_upcastPtr(thiz: *const MyObject) -> *const QObject;
#[doc(hidden)]
#[cxx_name = "downcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_MyObject_downcastPtr(base: *const QObject) -> *const MyObject;
}
extern "Rust" {
#[cxx_name = "createRs"]
Expand Down Expand Up @@ -1052,6 +1056,9 @@ 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 ::cxx_qt::qobject::QObject) -> *const Self {
ffi::cxx_qt_ffi_MyObject_downcastPtr(base)
}
}
#[doc(hidden)]
#[allow(clippy::unnecessary_box_returns)]
Expand Down
14 changes: 14 additions & 0 deletions crates/cxx-qt-gen/test_outputs/qenum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ mod ffi {
#[cxx_name = "upcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_MyObject_upcastPtr(thiz: *const MyObject) -> *const QObject;
#[doc(hidden)]
#[cxx_name = "downcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_MyObject_downcastPtr(base: *const QObject) -> *const MyObject;
}
extern "Rust" {
#[cxx_name = "createRs"]
Expand Down Expand Up @@ -135,6 +139,10 @@ mod ffi {
#[cxx_name = "upcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_CxxName_upcastPtr(thiz: *const MyRenamedObject) -> *const QObject;
#[doc(hidden)]
#[cxx_name = "downcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn cxx_qt_ffi_CxxName_downcastPtr(base: *const QObject) -> *const MyRenamedObject;
}
extern "Rust" {
#[cxx_name = "createRs"]
Expand Down Expand Up @@ -165,6 +173,9 @@ 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 ::cxx_qt::qobject::QObject) -> *const Self {
ffi::cxx_qt_ffi_MyObject_downcastPtr(base)
}
}
#[doc(hidden)]
#[allow(clippy::unnecessary_box_returns)]
Expand All @@ -190,6 +201,9 @@ 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 ::cxx_qt::qobject::QObject) -> *const Self {
ffi::cxx_qt_ffi_CxxName_downcastPtr(base)
}
}
#[doc(hidden)]
#[allow(clippy::unnecessary_box_returns)]
Expand Down
Loading

0 comments on commit f6c1f8c

Please sign in to comment.