Skip to main content

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;