Skip to content

Commit 892f14f

Browse files
committed
cxx-qt-lib: Add binding for QQmlApplicationEngine::singletonInstance
This allows accessing QObject singleton instances registered in the QML engine (using #[qml_singleton]) from the Rust side.
1 parent f5afefe commit 892f14f

File tree

4 files changed

+61
-0
lines changed

4 files changed

+61
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717

1818
## [Unreleased](https://github.com/KDAB/cxx-qt/compare/v0.7.0...HEAD)
1919

20+
### Added
21+
22+
- Add binding for `singletonInstance` of `QQmlApplicationEngine`, allowing access to singleton instances registered in the QML engine.
23+
2024
### Fixed
2125

2226
- Build warnings due to unused unsafe blocks since CXX 1.0.130

crates/cxx-qt-lib/include/qml/qqmlapplicationengine.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ qqmlapplicationengineNew();
2222
QQmlEngine&
2323
qqmlapplicationengineAsQQmlEngine(QQmlApplicationEngine&);
2424

25+
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
26+
void*
27+
qqmlapplicationengineSingletonInstance(QQmlApplicationEngine& engine,
28+
QAnyStringView uri,
29+
QAnyStringView typeName);
30+
#endif
31+
2532
}
2633
}
2734

crates/cxx-qt-lib/src/qml/qqmlapplicationengine.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,16 @@ qqmlapplicationengineAsQQmlEngine(QQmlApplicationEngine& engine)
2222
return static_cast<QQmlEngine&>(engine);
2323
}
2424

25+
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
26+
void*
27+
qqmlapplicationengineSingletonInstance(QQmlApplicationEngine& engine,
28+
QAnyStringView uri,
29+
QAnyStringView typeName)
30+
{
31+
return reinterpret_cast<void*>(
32+
engine.singletonInstance<QObject*>(uri, typeName));
33+
}
34+
#endif
35+
2536
}
2637
}

crates/cxx-qt-lib/src/qml/qqmlapplicationengine.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ mod ffi {
6868

6969
#[namespace = "rust::cxxqtlib1"]
7070
unsafe extern "C++" {
71+
include!("cxx-qt-lib/common.h");
72+
type c_void = crate::c_void;
73+
7174
#[doc(hidden)]
7275
#[rust_name = "qqmlapplicationengine_new"]
7376
fn qqmlapplicationengineNew() -> UniquePtr<QQmlApplicationEngine>;
@@ -79,13 +82,33 @@ mod ffi {
7982
) -> Pin<&mut QQmlEngine>;
8083
}
8184

85+
#[cfg(any(cxxqt_qt_version_at_least_7, cxxqt_qt_version_at_least_6_5))]
86+
unsafe extern "C++" {
87+
include!("cxx-qt-lib/qanystringview.h");
88+
type QAnyStringView<'a> = crate::QAnyStringView<'a>;
89+
}
90+
91+
#[namespace = "rust::cxxqtlib1"]
92+
unsafe extern "C++" {
93+
#[doc(hidden)]
94+
#[rust_name = "qqmlapplicationengine_singleton_instance"]
95+
#[cfg(any(cxxqt_qt_version_at_least_7, cxxqt_qt_version_at_least_6_5))]
96+
fn qqmlapplicationengineSingletonInstance(
97+
ptr: Pin<&mut QQmlApplicationEngine>,
98+
uri: QAnyStringView,
99+
typeName: QAnyStringView,
100+
) -> *mut c_void;
101+
}
102+
82103
// QQmlApplicationEngine is not a trivial to CXX and is not relocatable in Qt
83104
// as the following fails in C++. So we cannot mark it as a trivial type
84105
// and need to use references or pointers.
85106
// static_assert(QTypeInfo<QQmlApplicationEngine>::isRelocatable);
86107
impl UniquePtr<QQmlApplicationEngine> {}
87108
}
88109

110+
#[cfg(any(cxxqt_qt_version_at_least_7, cxxqt_qt_version_at_least_6_5))]
111+
use crate::QAnyStringView;
89112
use crate::QQmlEngine;
90113
use core::pin::Pin;
91114

@@ -101,4 +124,20 @@ impl QQmlApplicationEngine {
101124
pub fn new() -> cxx::UniquePtr<Self> {
102125
ffi::qqmlapplicationengine_new()
103126
}
127+
128+
/// Returns the instance of a singleton type named typeName from the module specified by uri.
129+
/// This is inherently unsafe as it does not perform any type checks.
130+
/// This function was introduced in Qt 6.5.
131+
#[cfg(any(cxxqt_qt_version_at_least_7, cxxqt_qt_version_at_least_6_5))]
132+
pub unsafe fn singleton_instance<'a, T>(
133+
self: Pin<&'a mut Self>,
134+
uri: QAnyStringView,
135+
type_name: QAnyStringView,
136+
) -> Option<Pin<&'a mut T>> {
137+
let ptr = ffi::qqmlapplicationengine_singleton_instance(self, uri, type_name);
138+
if ptr.is_null() {
139+
return None;
140+
}
141+
Some(Pin::new_unchecked(&mut *(ptr as *mut T)))
142+
}
104143
}

0 commit comments

Comments
 (0)