6 #ifndef SWIFT_MISC_SLOT_H
7 #define SWIFT_MISC_SLOT_H
26 template <
typename T,
typename U,
typename F,
typename G>
27 QMetaObject::Connection
connectOnce(T *sender, F signal, U *receiver, G &&slot,
28 Qt::ConnectionType type = Qt::AutoConnection)
30 std::promise<QMetaObject::Connection> promise;
31 auto called = std::make_shared<std::atomic_flag>();
33 auto wrapper = [receiver, called, connection = promise.get_future().share(),
34 slot = std::forward<G>(slot)](
auto &&...args) {
35 if (called->test_and_set()) {
return; }
36 QObject::disconnect(connection.get());
37 private_ns::invokeSlot(slot, receiver, std::forward<decltype(args)>(args)...);
39 auto connection = QObject::connect(sender, signal, receiver, std::move(wrapper), type);
40 promise.set_value(connection);
48 template <
typename T,
typename F,
typename G>
49 QMetaObject::Connection
connectOnce(T *sender, F signal, G &&slot)
51 static_assert(!std::is_member_pointer_v<std::decay_t<G>>,
52 "If slot is a pointer to member, a receiver must be supplied");
53 return connectOnce(sender, signal, sender, std::forward<G>(slot));
68 template <
typename R,
typename... Args>
76 template <
typename T,
typename U>
77 CSlot(T *
object, R (U::*
function)(Args...))
78 : m_object(object), m_function([=](Args... args) {
return (object->*
function)(args...); })
80 Q_ASSERT_X(
object, Q_FUNC_INFO,
"Need object");
85 CSlot(T *
object, std::function<R(Args...)>
function) : m_object(object), m_function(function)
91 Q_ASSERT_X(m_function, Q_FUNC_INFO,
"Empty CSlot was called");
92 return m_function(args...);
99 if (!m_object || !m_function) {
return false; }
100 QTimer::singleShot(0, m_object.data(), std::bind(*
this, std::forward<Args>(args)...));
106 QObject *
object()
const {
return m_object.data(); }
112 Q_ASSERT_X(hasNullObject(), Q_FUNC_INFO,
"Can only set, not change the object");
117 operator bool()
const {
return !this->isEmpty() && !this->hasNullObject(); }
120 bool operator!()
const {
return this->isEmpty() || this->hasNullObject(); }
129 QPointer<QObject> m_object;
130 std::function<R(Args...)> m_function;
R operator()(Args... args) const
Call the slot. The behaviour is undefined if the slot is empty.
bool hasNullObject() const
True if the object is null.
CSlot(T *object, std::function< R(Args...)> function)
Construct a slot from the given object passing a function and a object.
QObject * object() const
Returns the object which the slot belongs to. Use this as the third argument to QObject::connect to e...
bool operator!() const
True if the slot is empty or object is null, false if it can be called.
bool isEmpty() const
True if the slot is empty, false if it can be called.
CSlot()
Construct an empty slot.
CSlot(T *object, R(U::*function)(Args...))
Construct a slot from the given member function of the given object.
void setObject(QObject *object)
Set the object which the slot belongs to. Use this as the third argument to QObject::connect to ensur...
bool singleShot(Args... args) const
Call function "de-coupled" in original thread.
Callable wrapper for a member function with function signature F.
Free functions in swift::misc.
QMetaObject::Connection connectOnce(T *sender, F signal, U *receiver, G &&slot, Qt::ConnectionType type=Qt::AutoConnection)
Wrapper around QObject::connect which disconnects after the signal has been emitted once.
auto singleShot(int msec, QObject *target, F &&task)
Starts a single-shot timer which will call a task in the thread of the given object when it times out...