From a5267dbaa22581e316f440dc7327f2e7431012d5 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sun, 13 Jan 2019 11:48:06 +0900 Subject: qt_connection_util.h: a new home for connectSingleShot() and newly made connectUntil() --- lib/connection.h | 21 +--------- lib/qt_connection_util.h | 102 +++++++++++++++++++++++++++++++++++++++++++++++ lib/util.h | 33 ++------------- libqmatrixclient.pri | 1 + 4 files changed, 108 insertions(+), 49 deletions(-) create mode 100644 lib/qt_connection_util.h diff --git a/lib/connection.h b/lib/connection.h index ff3e2028..98e8dced 100644 --- a/lib/connection.h +++ b/lib/connection.h @@ -21,6 +21,7 @@ #include "csapi/create_room.h" #include "joinstate.h" #include "events/accountdataevents.h" +#include "qt_connection_util.h" #include #include @@ -49,26 +50,6 @@ namespace QMatrixClient class SendToDeviceJob; class SendMessageJob; - /** Create a single-shot connection that triggers on the signal and - * then self-disconnects - * - * Only supports DirectConnection type. - */ - template - inline auto connectSingleShot(SenderT1* sender, SignalT signal, - ReceiverT2* receiver, SlotT slot) - { - QMetaObject::Connection connection; - connection = QObject::connect(sender, signal, receiver, slot, - Qt::DirectConnection); - Q_ASSERT(connection); - QObject::connect(sender, signal, receiver, - [connection] { QObject::disconnect(connection); }, - Qt::DirectConnection); - return connection; - } - class Connection; using room_factory_t = std::function + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include "util.h" + +#include + +namespace QMatrixClient { + namespace _impl { + template + inline QMetaObject::Connection connectUntil( + SenderT* sender, SignalT signal, ContextT* context, + std::function slot, Qt::ConnectionType connType) + { + auto pc = std::make_unique(); + auto& c = *pc; // Resolve a reference before pc is moved to lambda + c = QObject::connect(sender, signal, context, + [pc=std::move(pc),slot] (ArgTs... args) { + Q_ASSERT(*pc); + if (slot(std::forward(args)...)) + QObject::disconnect(*pc); + }, connType); + return c; + } + } + + template + inline auto connectUntil(SenderT* sender, SignalT signal, ContextT* context, + const FunctorT& slot, + Qt::ConnectionType connType = Qt::AutoConnection) + { + return _impl::connectUntil(sender, signal, context, + typename function_traits::function_type(slot), + connType); + } + + /** Create a single-shot connection that triggers on the signal and + * then self-disconnects + * + * Only supports DirectConnection type. + */ + template + inline auto connectSingleShot(SenderT* sender, SignalT signal, + ReceiverT* receiver, SlotT slot) + { + QMetaObject::Connection connection; + connection = QObject::connect(sender, signal, receiver, slot, + Qt::DirectConnection); + Q_ASSERT(connection); + QObject::connect(sender, signal, receiver, + [connection] { QObject::disconnect(connection); }, + Qt::DirectConnection); + return connection; + } + + /** A guard pointer that disconnects an interested object upon destruction + * It's almost QPointer<> except that you have to initialise it with one + * more additional parameter - a pointer to a QObject that will be + * disconnected from signals of the underlying pointer upon the guard's + * destruction. + */ + template + class ConnectionsGuard : public QPointer + { + public: + ConnectionsGuard(T* publisher, QObject* subscriber) + : QPointer(publisher), subscriber(subscriber) + { } + ~ConnectionsGuard() + { + if (*this) + (*this)->disconnect(subscriber); + } + ConnectionsGuard(ConnectionsGuard&&) = default; + ConnectionsGuard& operator=(ConnectionsGuard&&) = default; + Q_DISABLE_COPY(ConnectionsGuard) + using QPointer::operator=; + + private: + QObject* subscriber; + }; +} diff --git a/lib/util.h b/lib/util.h index 336248d3..bae7f93f 100644 --- a/lib/util.h +++ b/lib/util.h @@ -18,8 +18,9 @@ #pragma once -#include -#if (QT_VERSION < QT_VERSION_CHECK(5, 5, 0)) +#include + +#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) #include #include #endif @@ -166,6 +167,7 @@ namespace QMatrixClient static constexpr auto is_callable = true; using return_type = ReturnT; using arg_types = std::tuple; + using function_type = std::function; static constexpr auto arg_number = std::tuple_size::value; }; @@ -265,33 +267,6 @@ namespace QMatrixClient return std::make_pair(last, sLast); } - /** A guard pointer that disconnects an interested object upon destruction - * It's almost QPointer<> except that you have to initialise it with one - * more additional parameter - a pointer to a QObject that will be - * disconnected from signals of the underlying pointer upon the guard's - * destruction. - */ - template - class ConnectionsGuard : public QPointer - { - public: - ConnectionsGuard(T* publisher, QObject* subscriber) - : QPointer(publisher), subscriber(subscriber) - { } - ~ConnectionsGuard() - { - if (*this) - (*this)->disconnect(subscriber); - } - ConnectionsGuard(ConnectionsGuard&&) = default; - ConnectionsGuard& operator=(ConnectionsGuard&&) = default; - Q_DISABLE_COPY(ConnectionsGuard) - using QPointer::operator=; - - private: - QObject* subscriber; - }; - /** Pretty-prints plain text into HTML * This includes HTML escaping of <,>,",& and URLs linkification. */ diff --git a/libqmatrixclient.pri b/libqmatrixclient.pri index eefaec67..f523f3a2 100644 --- a/libqmatrixclient.pri +++ b/libqmatrixclient.pri @@ -19,6 +19,7 @@ HEADERS += \ $$SRCPATH/avatar.h \ $$SRCPATH/syncdata.h \ $$SRCPATH/util.h \ + $$SRCPATH/qt_connection_util.h \ $$SRCPATH/events/event.h \ $$SRCPATH/events/roomevent.h \ $$SRCPATH/events/stateevent.h \ -- cgit v1.2.3