aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2019-01-13 11:48:06 +0900
committerKitsune Ral <Kitsune-Ral@users.sf.net>2019-01-13 17:12:48 +0900
commita5267dbaa22581e316f440dc7327f2e7431012d5 (patch)
treedd13d8013dcd479f0610a447887c0d2e524a7ace
parent4824705ea4eddfdb5d3845a64a96a1f5e2c022d0 (diff)
downloadlibquotient-a5267dbaa22581e316f440dc7327f2e7431012d5.tar.gz
libquotient-a5267dbaa22581e316f440dc7327f2e7431012d5.zip
qt_connection_util.h: a new home for connectSingleShot() and newly made connectUntil()
-rw-r--r--lib/connection.h21
-rw-r--r--lib/qt_connection_util.h102
-rw-r--r--lib/util.h33
-rw-r--r--libqmatrixclient.pri1
4 files changed, 108 insertions, 49 deletions
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 <QtCore/QObject>
#include <QtCore/QUrl>
@@ -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 <typename SenderT1, typename SignalT,
- typename ReceiverT2, typename SlotT>
- 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<Room*(Connection*, const QString&,
diff --git a/lib/qt_connection_util.h b/lib/qt_connection_util.h
new file mode 100644
index 00000000..2df2b186
--- /dev/null
+++ b/lib/qt_connection_util.h
@@ -0,0 +1,102 @@
+/******************************************************************************
+ * Copyright (C) 2019 Kitsune Ral <kitsune-ral@users.sf.net>
+ *
+ * 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 <QtCore/QPointer>
+
+namespace QMatrixClient {
+ namespace _impl {
+ template <typename SenderT, typename SignalT,
+ typename ContextT, typename... ArgTs>
+ inline QMetaObject::Connection connectUntil(
+ SenderT* sender, SignalT signal, ContextT* context,
+ std::function<bool(ArgTs...)> slot, Qt::ConnectionType connType)
+ {
+ auto pc = std::make_unique<QMetaObject::Connection>();
+ 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<ArgTs>(args)...))
+ QObject::disconnect(*pc);
+ }, connType);
+ return c;
+ }
+ }
+
+ template <typename SenderT, typename SignalT,
+ typename ContextT, typename FunctorT>
+ 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<FunctorT>::function_type(slot),
+ connType);
+ }
+
+ /** Create a single-shot connection that triggers on the signal and
+ * then self-disconnects
+ *
+ * Only supports DirectConnection type.
+ */
+ template <typename SenderT, typename SignalT,
+ typename ReceiverT, typename SlotT>
+ 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 <typename T>
+ class ConnectionsGuard : public QPointer<T>
+ {
+ public:
+ ConnectionsGuard(T* publisher, QObject* subscriber)
+ : QPointer<T>(publisher), subscriber(subscriber)
+ { }
+ ~ConnectionsGuard()
+ {
+ if (*this)
+ (*this)->disconnect(subscriber);
+ }
+ ConnectionsGuard(ConnectionsGuard&&) = default;
+ ConnectionsGuard& operator=(ConnectionsGuard&&) = default;
+ Q_DISABLE_COPY(ConnectionsGuard)
+ using QPointer<T>::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 <QtCore/QPointer>
-#if (QT_VERSION < QT_VERSION_CHECK(5, 5, 0))
+#include <QtCore/QLatin1String>
+
+#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
#include <QtCore/QMetaEnum>
#include <QtCore/QDebug>
#endif
@@ -166,6 +167,7 @@ namespace QMatrixClient
static constexpr auto is_callable = true;
using return_type = ReturnT;
using arg_types = std::tuple<ArgTs...>;
+ using function_type = std::function<ReturnT(ArgTs...)>;
static constexpr auto arg_number = std::tuple_size<arg_types>::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 <typename T>
- class ConnectionsGuard : public QPointer<T>
- {
- public:
- ConnectionsGuard(T* publisher, QObject* subscriber)
- : QPointer<T>(publisher), subscriber(subscriber)
- { }
- ~ConnectionsGuard()
- {
- if (*this)
- (*this)->disconnect(subscriber);
- }
- ConnectionsGuard(ConnectionsGuard&&) = default;
- ConnectionsGuard& operator=(ConnectionsGuard&&) = default;
- Q_DISABLE_COPY(ConnectionsGuard)
- using QPointer<T>::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 \