cxx_qt/connection.rs
1// SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
2// SPDX-FileContributor: Andrew Hayzen <andrew.hayzen@kdab.com>
3//
4// SPDX-License-Identifier: MIT OR Apache-2.0
5use cxx::{type_id, ExternType};
6use std::mem::MaybeUninit;
7
8#[cxx::bridge]
9mod ffi {
10 #[namespace = "rust::cxxqt1"]
11 unsafe extern "C++" {
12 include!("cxx-qt/connection.h");
13
14 #[doc(hidden)]
15 type QMetaObjectConnection = crate::QMetaObjectConnection;
16
17 #[doc(hidden)]
18 #[rust_name = "qmetaobjectconnection_default"]
19 fn qmetaobjectconnectionDefault() -> QMetaObjectConnection;
20
21 #[doc(hidden)]
22 #[rust_name = "qmetaobjectconnection_disconnect"]
23 fn qmetaobjectconnectionDisconnect(connection: &QMetaObjectConnection) -> bool;
24
25 #[doc(hidden)]
26 #[rust_name = "qmetaobjectconnection_drop"]
27 fn qmetaobjectconnectionDrop(connection: &mut QMetaObjectConnection);
28 }
29
30 /// This enum describes the types of connection that can be used with signals.
31 ///
32 /// Note that [UniqueConnection](https://doc.qt.io/qt/qt.html#ConnectionType-enum) is not supported.
33 #[namespace = "Qt"]
34 #[repr(i32)]
35 enum ConnectionType {
36 /// If the receiver lives in the thread that emits the signal, [`DirectConnection`](Self::DirectConnection) is used.
37 /// Otherwise, [`QueuedConnection`](Self::QueuedConnection) is used. The connection type is determined when the signal is emitted.
38 AutoConnection,
39 /// The slot is invoked immediately when the signal is emitted.
40 /// The slot is executed in the signalling thread.
41 DirectConnection,
42 /// The slot is invoked when control returns to the event loop of the receiver's thread.
43 /// The slot is executed in the receiver's thread.
44 QueuedConnection,
45 /// Same as [`QueuedConnection`](Self::QueuedConnection), except that the signalling thread blocks until the slot returns.
46 /// This connection must not be used if the receiver lives in the signalling thread, or else the application will deadlock.
47 BlockingQueuedConnection,
48 }
49
50 // We need to tell CXX that the type already exists, otherwise the following error ocucrs
51 // "scoped/unscoped mismatch in enum"
52 #[namespace = "Qt"]
53 unsafe extern "C++" {
54 type ConnectionType;
55 }
56}
57
58/// Represents a handle to a signal-slot (or signal-functor) connection.
59///
60/// This struct is returned when a connection is made using `on_SIGNAL_NAME`.
61///
62/// Note that when this struct is dropped the connection is disconnected.
63/// So so keep a connection active either hold onto the struct for the duration
64/// that the connection should be active or call [`QMetaObjectConnectionGuard::release`](crate::QMetaObjectConnectionGuard::release).
65///
66/// Qt Documentation: [QMetaObject::Connection](https://doc.qt.io/qt/qmetaobject-connection.html#details)
67#[repr(C)]
68pub struct QMetaObjectConnection {
69 _space: MaybeUninit<usize>,
70}
71
72impl Default for QMetaObjectConnection {
73 /// Creates a Connection instance.
74 fn default() -> Self {
75 ffi::qmetaobjectconnection_default()
76 }
77}
78
79impl Drop for QMetaObjectConnection {
80 fn drop(&mut self) {
81 ffi::qmetaobjectconnection_drop(self);
82 }
83}
84
85impl QMetaObjectConnection {
86 /// Disconnect a connection.
87 ///
88 /// If the connection is invalid or has already been disconnected, do nothing and return `false`.
89 pub fn disconnect(&self) -> bool {
90 ffi::qmetaobjectconnection_disconnect(self)
91 }
92}
93
94// Safety:
95//
96// Static checks on the C++ side to ensure the size is the same.
97unsafe impl ExternType for QMetaObjectConnection {
98 type Id = type_id!("rust::cxxqt1::QMetaObjectConnection");
99 type Kind = cxx::kind::Trivial;
100}
101
102pub use ffi::ConnectionType;