summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@woboq.com>2011-11-23 15:03:04 +0100
committerQt by Nokia <qt-info@nokia.com>2011-11-25 01:12:14 +0100
commit66b659c8a4a429b483b66fd1a1d1429a2c0d3b4a (patch)
treec654cac67ca5d6cc2cbd2d41d03b83f5011dc0c3 /src/corelib/kernel
parent583c55b243d9894d93d32fbe15bece2a9beb1d10 (diff)
Add support for QueuedConnection when connecting using the new syntax
QMetaCallEvent now can handle a pointer to QSlotObjectBase Change-Id: I94da1e68ce9bb1fd96a9ae013a389552eb625faa Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qobject.cpp39
-rw-r--r--src/corelib/kernel/qobject.h4
-rw-r--r--src/corelib/kernel/qobject_impl.h37
-rw-r--r--src/corelib/kernel/qobject_p.h4
4 files changed, 71 insertions, 13 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index e8735d0c09..0adbc9c819 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -498,13 +498,25 @@ void QObjectPrivate::clearGuards(QObject *object)
QMetaCallEvent::QMetaCallEvent(ushort method_offset, ushort method_relative, QObjectPrivate::StaticMetaCallFunction callFunction,
const QObject *sender, int signalId,
int nargs, int *types, void **args, QSemaphore *semaphore)
- : QEvent(MetaCall), sender_(sender), signalId_(signalId),
+ : QEvent(MetaCall), slotObj_(0), sender_(sender), signalId_(signalId),
nargs_(nargs), types_(types), args_(args), semaphore_(semaphore),
callFunction_(callFunction), method_offset_(method_offset), method_relative_(method_relative)
{ }
/*! \internal
*/
+QMetaCallEvent::QMetaCallEvent(QObject::QSlotObjectBase *slotO, const QObject *sender, int signalId,
+ int nargs, int *types, void **args, QSemaphore *semaphore)
+ : QEvent(MetaCall), slotObj_(slotO), sender_(sender), signalId_(signalId),
+ nargs_(nargs), types_(types), args_(args), semaphore_(semaphore),
+ callFunction_(0), method_offset_(0), method_relative_(-1)
+{
+ if (slotObj_)
+ slotObj_->ref.ref();
+}
+
+/*! \internal
+ */
QMetaCallEvent::~QMetaCallEvent()
{
if (types_) {
@@ -519,13 +531,17 @@ QMetaCallEvent::~QMetaCallEvent()
if (semaphore_)
semaphore_->release();
#endif
+ if (slotObj_ && !slotObj_->ref.deref())
+ delete slotObj_;
}
/*! \internal
*/
void QMetaCallEvent::placeMetaCall(QObject *object)
{
- if (callFunction_) {
+ if (slotObj_) {
+ slotObj_->call(object, args_);
+ } else if (callFunction_) {
callFunction_(object, QMetaObject::InvokeMetaMethod, method_relative_, args_);
} else {
QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, method_offset_ + method_relative_, args_);
@@ -3261,11 +3277,10 @@ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connect
args[0] = 0; // return value
for (int n = 1; n < nargs; ++n)
args[n] = QMetaType::create((types[n] = argumentTypes[n-1]), argv[n]);
- QCoreApplication::postEvent(c->receiver, new QMetaCallEvent(c->method_offset,
- c->method_relative,
- c->callFunction,
- sender, signal, nargs,
- types, args));
+ QMetaCallEvent *ev = c->isSlotObject ?
+ new QMetaCallEvent(c->slotObj, sender, signal, nargs, types, args) :
+ new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal, nargs, types, args);
+ QCoreApplication::postEvent(c->receiver, ev);
}
@@ -3378,12 +3393,10 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign
receiver->metaObject()->className(), receiver);
}
QSemaphore semaphore;
- QCoreApplication::postEvent(receiver, new QMetaCallEvent(c->method_offset, c->method_relative,
- c->callFunction,
- sender, signal_absolute_index,
- 0, 0,
- argv ? argv : empty_argv,
- &semaphore));
+ QMetaCallEvent *ev = c->isSlotObject ?
+ new QMetaCallEvent(c->slotObj, sender, signal_absolute_index, 0, 0, argv ? argv : empty_argv, &semaphore) :
+ new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal_absolute_index, 0, 0, argv ? argv : empty_argv, &semaphore);
+ QCoreApplication::postEvent(receiver, ev);
semaphore.acquire();
locker.relock();
continue;
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 93448b5ad1..d4a532a9d8 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -221,6 +221,9 @@ public:
typedef typename QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::IncompatibleSignalSlotArguments EnsureCompatibleArguments;
const int *types = 0;
+ if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
+ types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
+
return connectImpl(sender, reinterpret_cast<void **>(&signal),
receiver, new QSlotObject<Func2,
typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
@@ -318,6 +321,7 @@ protected:
static const QMetaObject staticQtMetaObject;
friend struct QMetaObject;
+ friend class QMetaCallEvent;
friend class QApplication;
friend class QApplicationPrivate;
friend class QCoreApplication;
diff --git a/src/corelib/kernel/qobject_impl.h b/src/corelib/kernel/qobject_impl.h
index 7d3dc1659b..9918b1f1c2 100644
--- a/src/corelib/kernel/qobject_impl.h
+++ b/src/corelib/kernel/qobject_impl.h
@@ -344,6 +344,43 @@ namespace QtPrivate {
#endif
+ /*
+ Logic to statically generate the array of qMetaTypeId
+ ConnectionTypes<FunctionPointer<Signal>::Arguments>::types() returns an array
+ of int that is suitable for the types arguments of the connection functions.
+
+ The array only exist of all the types are declared as a metatype
+ (detected using the TypesAreDeclaredMetaType helper struct)
+ If one of the type is not declared, the function return 0 and the signal
+ cannot be used in queued connection.
+ */
+#ifndef Q_COMPILER_VARIADIC_TEMPLATES
+ template <typename ArgList> struct TypesAreDeclaredMetaType { enum { Value = false }; };
+ template <> struct TypesAreDeclaredMetaType<void> { enum { Value = true }; };
+ template <typename Arg, typename Tail> struct TypesAreDeclaredMetaType<List<Arg, Tail> > { enum { Value = QMetaTypeId2<Arg>::Defined && TypesAreDeclaredMetaType<Tail>::Value }; };
+
+ template <typename ArgList, bool Declared = TypesAreDeclaredMetaType<ArgList>::Value > struct ConnectionTypes
+ { static const int *types() { return 0; } };
+ template <> struct ConnectionTypes<void, true>
+ { static const int *types() { static const int t[1] = { 0 }; return t; } };
+ template <typename Arg1> struct ConnectionTypes<List<Arg1, void>, true>
+ { static const int *types() { static const int t[2] = { QtPrivate::QMetaTypeIdHelper<Arg1>::qt_metatype_id(), 0 }; return t; } };
+ template <typename Arg1, typename Arg2> struct ConnectionTypes<List<Arg1, List<Arg2, void> >, true>
+ { static const int *types() { static const int t[3] = { QtPrivate::QMetaTypeIdHelper<Arg1>::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper<Arg2>::qt_metatype_id(), 0 }; return t; } };
+ template <typename Arg1, typename Arg2, typename Arg3> struct ConnectionTypes<List<Arg1, List<Arg2, List<Arg3, void> > >, true>
+ { static const int *types() { static const int t[4] = { QtPrivate::QMetaTypeIdHelper<Arg1>::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper<Arg2>::qt_metatype_id(),
+ QtPrivate::QMetaTypeIdHelper<Arg3>::qt_metatype_id(), 0 }; return t; } };
+#else
+ template <typename ArgList> struct TypesAreDeclaredMetaType { enum { Value = false }; };
+ template <> struct TypesAreDeclaredMetaType<List<>> { enum { Value = true }; };
+ template <typename Arg, typename... Tail> struct TypesAreDeclaredMetaType<List<Arg, Tail...> >
+ { enum { Value = QMetaTypeId2<Arg>::Defined && TypesAreDeclaredMetaType<List<Tail...>>::Value }; };
+
+ template <typename ArgList, bool Declared = TypesAreDeclaredMetaType<ArgList>::Value > struct ConnectionTypes
+ { static const int *types() { return 0; } };
+ template <typename... Args> struct ConnectionTypes<List<Args...>, true>
+ { static const int *types() { static const int t[sizeof...(Args) + 1] = { (QtPrivate::QMetaTypeIdHelper<Args>::qt_metatype_id())..., 0 }; return t; } };
+#endif
}
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 72cf5a8cca..5519a69c34 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -264,6 +264,9 @@ class Q_CORE_EXPORT QMetaCallEvent : public QEvent
public:
QMetaCallEvent(ushort method_offset, ushort method_relative, QObjectPrivate::StaticMetaCallFunction callFunction , const QObject *sender, int signalId,
int nargs = 0, int *types = 0, void **args = 0, QSemaphore *semaphore = 0);
+ QMetaCallEvent(QObject::QSlotObjectBase *slotObj, const QObject *sender, int signalId,
+ int nargs = 0, int *types = 0, void **args = 0, QSemaphore *semaphore = 0);
+
~QMetaCallEvent();
inline int id() const { return method_offset_ + method_relative_; }
@@ -274,6 +277,7 @@ public:
virtual void placeMetaCall(QObject *object);
private:
+ QObject::QSlotObjectBase *slotObj_;
const QObject *sender_;
int signalId_;
int nargs_;