Skip to content

Commit

Permalink
cxx-qt-gen: impl Deref for qobject::T to reach T easily
Browse files Browse the repository at this point in the history
Related to #559
  • Loading branch information
ahayzen-kdab committed Jul 19, 2023
1 parent 7254978 commit a9c1b4e
Show file tree
Hide file tree
Showing 16 changed files with 112 additions and 42 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Ensure that generated Rust code works when `#![deny(missing_docs)]` is enabled
- Ability to connect and disconnect from signals in Rust triggering a function pointer
- `unsafe impl !cxx_qt::Locking for qobject::T` to disable internal locking
- `Deref` is now implemented for `qobject::T` to reach the `T` Rust struct

### Changed

Expand Down
2 changes: 1 addition & 1 deletion crates/cxx-qt-gen/src/generator/rust/property/getter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub fn generate(
#[doc = "Getter for the Q_PROPERTY "]
#[doc = #ident_str]
pub fn #getter_rust(&self) -> &#ty {
&self.rust().#ident
&self.#ident
}
}
},
Expand Down
12 changes: 6 additions & 6 deletions crates/cxx-qt-gen/src/generator/rust/property/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ mod tests {
#[doc = "Getter for the Q_PROPERTY "]
#[doc = "trivial_property"]
pub fn trivial_property(&self) -> &i32 {
&self.rust().trivial_property
&self.trivial_property
}
}
},
Expand Down Expand Up @@ -151,7 +151,7 @@ mod tests {
#[doc = "Setter for the Q_PROPERTY "]
#[doc = "trivial_property"]
pub fn set_trivial_property(mut self: Pin<&mut Self>, value: i32) {
if self.rust().trivial_property == value {
if self.trivial_property == value {
return;
}
self.as_mut().rust_mut().trivial_property = value;
Expand Down Expand Up @@ -191,7 +191,7 @@ mod tests {
#[doc = "Getter for the Q_PROPERTY "]
#[doc = "opaque_property"]
pub fn opaque_property(&self) -> &UniquePtr<QColor> {
&self.rust().opaque_property
&self.opaque_property
}
}
},
Expand Down Expand Up @@ -225,7 +225,7 @@ mod tests {
#[doc = "Setter for the Q_PROPERTY "]
#[doc = "opaque_property"]
pub fn set_opaque_property(mut self: Pin<&mut Self>, value: UniquePtr<QColor>) {
if self.rust().opaque_property == value {
if self.opaque_property == value {
return;
}
self.as_mut().rust_mut().opaque_property = value;
Expand Down Expand Up @@ -265,7 +265,7 @@ mod tests {
#[doc = "Getter for the Q_PROPERTY "]
#[doc = "unsafe_property"]
pub fn unsafe_property(&self) -> &*mut T {
&self.rust().unsafe_property
&self.unsafe_property
}
}
},
Expand Down Expand Up @@ -299,7 +299,7 @@ mod tests {
#[doc = "Setter for the Q_PROPERTY "]
#[doc = "unsafe_property"]
pub fn set_unsafe_property(mut self: Pin<&mut Self>, value: *mut T) {
if self.rust().unsafe_property == value {
if self.unsafe_property == value {
return;
}
self.as_mut().rust_mut().unsafe_property = value;
Expand Down
2 changes: 1 addition & 1 deletion crates/cxx-qt-gen/src/generator/rust/property/setter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub fn generate(
#[doc = "Setter for the Q_PROPERTY "]
#[doc = #ident_str]
pub fn #setter_rust(mut self: Pin<&mut Self>, value: #ty) {
if self.rust().#ident == value {
if self.#ident == value {
// don't want to set the value again and reemit the signal,
// as this can cause binding loops
return;
Expand Down
53 changes: 44 additions & 9 deletions crates/cxx-qt-gen/src/writer/rust/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,30 @@ fn cxx_qt_common_blocks(qobject: &GeneratedRustQObject) -> Vec<TokenStream> {
let cpp_struct_ident = &qobject.cpp_struct_ident;
let rust_struct_ident = &qobject.rust_struct_ident;

vec![quote! {
impl cxx_qt::CxxQtType for #cpp_struct_ident {
type Rust = #rust_struct_ident;
vec![
quote! {
impl core::ops::Deref for #cpp_struct_ident {
type Target = #rust_struct_ident;

fn rust(&self) -> &Self::Rust {
self.cxx_qt_ffi_rust()
fn deref(&self) -> &Self::Target {
self.cxx_qt_ffi_rust()
}
}
},
quote! {
impl cxx_qt::CxxQtType for #cpp_struct_ident {
type Rust = #rust_struct_ident;

fn rust(&self) -> &Self::Rust {
self.cxx_qt_ffi_rust()
}

fn rust_mut(self: core::pin::Pin<&mut Self>) -> Pin<&mut Self::Rust> {
self.cxx_qt_ffi_rust_mut()
fn rust_mut(self: core::pin::Pin<&mut Self>) -> Pin<&mut Self::Rust> {
self.cxx_qt_ffi_rust_mut()
}
}
}
}]
},
]
}

/// For a given GeneratedRustBlocks write this into a Rust TokenStream
Expand Down Expand Up @@ -365,6 +376,14 @@ mod tests {
}
}

impl core::ops::Deref for MyObject {
type Target = MyObjectRust;

fn deref(&self) -> &Self::Target {
self.cxx_qt_ffi_rust()
}
}

impl cxx_qt::CxxQtType for MyObject {
type Rust = MyObjectRust;
fn rust(&self) -> &Self::Rust {
Expand Down Expand Up @@ -466,6 +485,14 @@ mod tests {
}
}

impl core::ops::Deref for FirstObject {
type Target = FirstObjectRust;

fn deref(&self) -> &Self::Target {
self.cxx_qt_ffi_rust()
}
}

impl cxx_qt::CxxQtType for FirstObject {
type Rust = FirstObjectRust;
fn rust(&self) -> &Self::Rust {
Expand All @@ -485,6 +512,14 @@ mod tests {
}
}

impl core::ops::Deref for SecondObject {
type Target = SecondObjectRust;

fn deref(&self) -> &Self::Target {
self.cxx_qt_ffi_rust()
}
}

impl cxx_qt::CxxQtType for SecondObject {
type Rust = SecondObjectRust;
fn rust(&self) -> &Self::Rust {
Expand Down
6 changes: 6 additions & 0 deletions crates/cxx-qt-gen/test_outputs/inheritance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ pub mod cxx_qt_inheritance {
pub fn create_rs_my_object_rust() -> std::boxed::Box<MyObjectRust> {
core::default::Default::default()
}
impl core::ops::Deref for MyObject {
type Target = MyObjectRust;
fn deref(&self) -> &Self::Target {
self.cxx_qt_ffi_rust()
}
}
impl cxx_qt::CxxQtType for MyObject {
type Rust = MyObjectRust;
fn rust(&self) -> &Self::Rust {
Expand Down
6 changes: 6 additions & 0 deletions crates/cxx-qt-gen/test_outputs/invokables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,12 @@ pub mod cxx_qt_ffi {
initialize_arguments,
)
}
impl core::ops::Deref for MyObject {
type Target = MyObjectRust;
fn deref(&self) -> &Self::Target {
self.cxx_qt_ffi_rust()
}
}
impl cxx_qt::CxxQtType for MyObject {
type Rust = MyObjectRust;
fn rust(&self) -> &Self::Rust {
Expand Down
20 changes: 16 additions & 4 deletions crates/cxx-qt-gen/test_outputs/passthrough_and_naming.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ pub mod cxx_qt_ffi {
#[doc = "Getter for the Q_PROPERTY "]
#[doc = "property_name"]
pub fn property_name(&self) -> &i32 {
&self.rust().property_name
&self.property_name
}
}
impl MyObjectRust {
Expand All @@ -239,7 +239,7 @@ pub mod cxx_qt_ffi {
#[doc = "Setter for the Q_PROPERTY "]
#[doc = "property_name"]
pub fn set_property_name(mut self: Pin<&mut Self>, value: i32) {
if self.rust().property_name == value {
if self.property_name == value {
return;
}
self.as_mut().rust_mut().property_name = value;
Expand Down Expand Up @@ -285,6 +285,12 @@ pub mod cxx_qt_ffi {
pub fn create_rs_my_object_rust() -> std::boxed::Box<MyObjectRust> {
core::default::Default::default()
}
impl core::ops::Deref for MyObject {
type Target = MyObjectRust;
fn deref(&self) -> &Self::Target {
self.cxx_qt_ffi_rust()
}
}
impl cxx_qt::CxxQtType for MyObject {
type Rust = MyObjectRust;
fn rust(&self) -> &Self::Rust {
Expand All @@ -305,7 +311,7 @@ pub mod cxx_qt_ffi {
#[doc = "Getter for the Q_PROPERTY "]
#[doc = "property_name"]
pub fn property_name(&self) -> &i32 {
&self.rust().property_name
&self.property_name
}
}
impl SecondObjectRust {
Expand All @@ -318,7 +324,7 @@ pub mod cxx_qt_ffi {
#[doc = "Setter for the Q_PROPERTY "]
#[doc = "property_name"]
pub fn set_property_name(mut self: Pin<&mut Self>, value: i32) {
if self.rust().property_name == value {
if self.property_name == value {
return;
}
self.as_mut().rust_mut().property_name = value;
Expand Down Expand Up @@ -363,6 +369,12 @@ pub mod cxx_qt_ffi {
pub fn create_rs_second_object_rust() -> std::boxed::Box<SecondObjectRust> {
core::default::Default::default()
}
impl core::ops::Deref for SecondObject {
type Target = SecondObjectRust;
fn deref(&self) -> &Self::Target {
self.cxx_qt_ffi_rust()
}
}
impl cxx_qt::CxxQtType for SecondObject {
type Rust = SecondObjectRust;
fn rust(&self) -> &Self::Rust {
Expand Down
14 changes: 10 additions & 4 deletions crates/cxx-qt-gen/test_outputs/properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ pub mod cxx_qt_ffi {
#[doc = "Getter for the Q_PROPERTY "]
#[doc = "primitive"]
pub fn primitive(&self) -> &i32 {
&self.rust().primitive
&self.primitive
}
}
impl MyObjectRust {
Expand All @@ -131,7 +131,7 @@ pub mod cxx_qt_ffi {
#[doc = "Setter for the Q_PROPERTY "]
#[doc = "primitive"]
pub fn set_primitive(mut self: Pin<&mut Self>, value: i32) {
if self.rust().primitive == value {
if self.primitive == value {
return;
}
self.as_mut().rust_mut().primitive = value;
Expand All @@ -148,7 +148,7 @@ pub mod cxx_qt_ffi {
#[doc = "Getter for the Q_PROPERTY "]
#[doc = "trivial"]
pub fn trivial(&self) -> &QPoint {
&self.rust().trivial
&self.trivial
}
}
impl MyObjectRust {
Expand All @@ -161,7 +161,7 @@ pub mod cxx_qt_ffi {
#[doc = "Setter for the Q_PROPERTY "]
#[doc = "trivial"]
pub fn set_trivial(mut self: Pin<&mut Self>, value: QPoint) {
if self.rust().trivial == value {
if self.trivial == value {
return;
}
self.as_mut().rust_mut().trivial = value;
Expand Down Expand Up @@ -201,6 +201,12 @@ pub mod cxx_qt_ffi {
pub fn create_rs_my_object_rust() -> std::boxed::Box<MyObjectRust> {
core::default::Default::default()
}
impl core::ops::Deref for MyObject {
type Target = MyObjectRust;
fn deref(&self) -> &Self::Target {
self.cxx_qt_ffi_rust()
}
}
impl cxx_qt::CxxQtType for MyObject {
type Rust = MyObjectRust;
fn rust(&self) -> &Self::Rust {
Expand Down
6 changes: 6 additions & 0 deletions crates/cxx-qt-gen/test_outputs/signals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,12 @@ pub mod cxx_qt_ffi {
pub fn create_rs_my_object_rust() -> std::boxed::Box<MyObjectRust> {
core::default::Default::default()
}
impl core::ops::Deref for MyObject {
type Target = MyObjectRust;
fn deref(&self) -> &Self::Target {
self.cxx_qt_ffi_rust()
}
}
impl cxx_qt::CxxQtType for MyObject {
type Rust = MyObjectRust;
fn rust(&self) -> &Self::Rust {
Expand Down
3 changes: 1 addition & 2 deletions examples/demo_threading/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,8 @@ impl cxx_qt::Constructor<()> for qobject::EnergyUsage {
EnergyUsageRust::default()
}

/// A Q_INVOKABLE which starts the TCP server
fn initialize(mut self: core::pin::Pin<&mut Self>, _arguments: Self::InitializeArguments) {
if self.rust().join_handles.is_some() {
if self.join_handles.is_some() {
println!("Already running a server!");
return;
}
Expand Down
10 changes: 5 additions & 5 deletions examples/qml_features/rust/src/custom_base_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,11 @@ impl qobject::CustomBaseClass {
}

fn add_cpp_context(mut self: Pin<&mut Self>) {
let count = self.as_ref().rust().vector.len();
let count = self.vector.len();
unsafe {
self.as_mut()
.begin_insert_rows(&QModelIndex::default(), count as i32, count as i32);
let id = self.as_ref().rust().id;
let id = self.id;
self.as_mut().rust_mut().id = id + 1;
self.as_mut()
.rust_mut()
Expand Down Expand Up @@ -255,7 +255,7 @@ impl qobject::CustomBaseClass {

/// Remove the row with the given index
pub fn remove(mut self: Pin<&mut Self>, index: i32) {
if index < 0 || (index as usize) >= self.as_ref().rust().vector.len() {
if index < 0 || (index as usize) >= self.vector.len() {
return;
}

Expand All @@ -278,7 +278,7 @@ impl qobject::CustomBaseClass {
pub const VALUE_ROLE: i32 = 1;

fn data(&self, index: &QModelIndex, role: i32) -> QVariant {
if let Some((id, value)) = self.rust().vector.get(index.row() as usize) {
if let Some((id, value)) = self.vector.get(index.row() as usize) {
return match role {
Self::ID_ROLE => QVariant::from(id),
Self::VALUE_ROLE => QVariant::from(value),
Expand Down Expand Up @@ -312,7 +312,7 @@ impl qobject::CustomBaseClass {

/// Return the row count for the QAbstractListModel
pub fn row_count(&self, _parent: &QModelIndex) -> i32 {
self.rust().vector.len() as i32
self.vector.len() as i32
}
}
// ANCHOR_END: book_macro_code
2 changes: 1 addition & 1 deletion examples/qml_features/rust/src/invokables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ impl Default for RustInvokablesRust {
impl qobject::RustInvokables {
/// Immutable invokable method that returns the QColor
fn load_color(&self) -> QColor {
self.rust().as_qcolor()
self.as_qcolor()
}

/// Mutable invokable method that stores a color
Expand Down
2 changes: 1 addition & 1 deletion examples/qml_features/rust/src/signals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ impl cxx_qt::Constructor<()> for qobject::RustSignals {
// Determine if logging is enabled
if *qobject.as_ref().logging_enabled() {
// If no connections have been made, then create them
if qobject.as_ref().rust().connections.is_none() {
if qobject.as_ref().connections.is_none() {
// ANCHOR: book_signals_connect
let connections = [
qobject.as_mut().on_connected(|_, url| {
Expand Down
2 changes: 1 addition & 1 deletion tests/basic_cxx_qt/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,6 @@ impl qobject::MyObject {
}

fn fetch_update_call_count(&self) -> i32 {
self.rust().update_call_count
self.update_call_count
}
}
Loading

0 comments on commit a9c1b4e

Please sign in to comment.