summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmetaobject.cpp
diff options
context:
space:
mode:
authorBenjamin Terrier <b.terrier@gmail.com>2017-01-14 17:01:50 +0100
committerAapo Keskimolo <aapo.keskimolo@qt.io>2017-04-02 08:00:27 +0000
commitd2388f15e7fa420415d119b0e422ea03da050a60 (patch)
tree336c4b8762d8a455e4f3eed3ba6b6200f1758abf /src/corelib/kernel/qmetaobject.cpp
parent0c4eb097eda5301b64f6a12d5219bc9d2c43ab1d (diff)
Add QMetaObject::invokeMethod() overloads for function pointers
The new overloads do not accept parameters for the invoked function, this use case is handled by using lambda. Overloads for non member function pointers and functors are separated as the return type is not retrieved in the same way. Move QSlotObjectBase, QSlotObject and QFunctorSlotObject from qobject_impl.h to qobjectdefs_impl.h in order to make them available in qobjectdefs.h. Update autotests of previous overloads because of a soft break in source compatibility: passing null literals (0, NULL, nullptr, etc.) for the second parameter of invokeMethod() is not supported anymore. [ChangeLog][QtCore] Added QMetaObject::invokeMethod() overloads for function pointers. Task-number: QTBUG-37253 Change-Id: I6fb67e086d315ae393ce32743c4eb1abd6cc9139 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/kernel/qmetaobject.cpp')
-rw-r--r--src/corelib/kernel/qmetaobject.cpp83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 2e0dd8e5d2..68ee2bb241 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -1489,6 +1489,51 @@ bool QMetaObject::invokeMethod(QObject *obj,
val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);
}
+bool QMetaObject::invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase *slot, Qt::ConnectionType type, void *ret)
+{
+ if (! object)
+ return false;
+
+ QThread *currentThread = QThread::currentThread();
+ QThread *objectThread = object->thread();
+ if (type == Qt::AutoConnection)
+ type = (currentThread == objectThread) ? Qt::DirectConnection : Qt::QueuedConnection;
+
+ void *argv[] = { ret };
+
+ if (type == Qt::DirectConnection) {
+ slot->call(object, argv);
+ } else if (type == Qt::QueuedConnection) {
+ if (argv[0]) {
+ qWarning("QMetaObject::invokeMethod: Unable to invoke methods with return values in "
+ "queued connections");
+ return false;
+ }
+
+ // args and typesCopy will be deallocated by ~QMetaCallEvent() using free()
+ void **args = static_cast<void **>(calloc(1, sizeof(void *)));
+ Q_CHECK_PTR(args);
+
+ int *types = static_cast<int *>(calloc(1, sizeof(int)));
+ Q_CHECK_PTR(types);
+
+ QCoreApplication::postEvent(object, new QMetaCallEvent(slot, 0, -1, 1, types, args));
+ } else if (type == Qt::BlockingQueuedConnection) {
+#ifndef QT_NO_THREAD
+ if (currentThread == objectThread)
+ qWarning("QMetaObject::invokeMethod: Dead lock detected");
+
+ QSemaphore semaphore;
+ QCoreApplication::postEvent(object, new QMetaCallEvent(slot, 0, -1, 0, 0, argv, &semaphore));
+ semaphore.acquire();
+#endif // QT_NO_THREAD
+ } else {
+ qWarning("QMetaObject::invokeMethod: Unknown connection type");
+ return false;
+ }
+ return true;
+}
+
/*! \fn bool QMetaObject::invokeMethod(QObject *obj, const char *member,
QGenericReturnArgument ret,
QGenericArgument val0 = QGenericArgument(0),
@@ -1544,6 +1589,44 @@ bool QMetaObject::invokeMethod(QObject *obj,
*/
/*!
+ \fn bool QMetaObject::invokeMethod(QObject *receiver, PointerToMemberFunction function, Qt::ConnectionType type = Qt::AutoConnection, MemberFunctionReturnType *ret = Q_NULLPTR)
+
+ \since 5.10
+
+ \overload
+*/
+
+/*!
+ \fn bool QMetaObject::invokeMethod(QObject *receiver, PointerToMemberFunction function, MemberFunctionReturnType *ret)
+
+ \since 5.10
+
+ \overload
+
+ This overload invokes the member function using the connection type Qt::AutoConnection.
+*/
+
+/*!
+ \fn bool QMetaObject::invokeMethod(QObject *context, Functor function, Qt::ConnectionType type = Qt::AutoConnection, FunctorReturnType *ret = Q_NULLPTR)
+
+ \since 5.10
+
+ \overload
+
+ Call the functor in the event loop of \a context.
+*/
+
+/*!
+ \fn bool QMetaObject::invokeMethod(QObject *context, Functor function, FunctorReturnType *ret = Q_NULLPTR)
+
+ \since 5.10
+
+ \overload
+
+ Call the functor in the event loop of \a context using the connection type Qt::AutoConnection.
+*/
+
+/*!
\fn QMetaObject::Connection::Connection(const Connection &other)
Constructs a copy of \a other.