diff options
Diffstat (limited to 'src/corelib/kernel/qmetaobject.cpp')
-rw-r--r-- | src/corelib/kernel/qmetaobject.cpp | 122 |
1 files changed, 73 insertions, 49 deletions
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 71f375f..b4c37f4 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -218,12 +218,20 @@ QObject *QMetaObject::newInstance(QGenericArgument val0, */ int QMetaObject::static_metacall(Call cl, int idx, void **argv) const { - if (priv(d.data)->revision < 2) - return 0; - const QMetaObjectExtraData *extra = (const QMetaObjectExtraData*)(d.extradata); - if (!extra || !extra->static_metacall) - return 0; - return extra->static_metacall(cl, idx, argv); + const QMetaObjectExtraData *extra = reinterpret_cast<const QMetaObjectExtraData *>(d.extradata); + if (priv(d.data)->revision >= 6) { + if (!extra || !extra->static_metacall) + return 0; + extra->static_metacall(0, cl, idx, argv); + return -1; + } else if (priv(d.data)->revision >= 2) { + if (!extra || !extra->static_metacall) + return 0; + typedef int (*OldMetacall)(QMetaObject::Call, int, void **); + OldMetacall o = reinterpret_cast<OldMetacall>(extra->static_metacall); + return o(cl, idx, argv); + } + return 0; } /*! @@ -266,7 +274,25 @@ QObject *QMetaObject::cast(QObject *obj) const const QMetaObject *m = obj->metaObject(); do { if (m == this) - return const_cast<QObject*>(obj); + return obj; + } while ((m = m->d.superdata)); + } + return 0; +} + +/*! + \internal + + Returns \a obj if object \a obj inherits from this + meta-object; otherwise returns 0. +*/ +const QObject *QMetaObject::cast(const QObject *obj) const +{ + if (obj) { + const QMetaObject *m = obj->metaObject(); + do { + if (m == this) + return obj; } while ((m = m->d.superdata)); } return 0; @@ -621,20 +647,21 @@ int QMetaObjectPrivate::indexOfSignalRelative(const QMetaObject **baseObject, */ int QMetaObject::indexOfSlot(const char *slot) const { - int i = QMetaObjectPrivate::indexOfSlot(this, slot, false); + const QMetaObject *m = this; + int i = QMetaObjectPrivate::indexOfSlotRelative(&m, slot, false); if (i < 0) - i = QMetaObjectPrivate::indexOfSlot(this, slot, true); + i = QMetaObjectPrivate::indexOfSlotRelative(&m, slot, true); + if (i >= 0) + i += m->methodOffset(); return i; } -int QMetaObjectPrivate::indexOfSlot(const QMetaObject *m, +// same as indexOfSignalRelative but for slots. +int QMetaObjectPrivate::indexOfSlotRelative(const QMetaObject **m, const char *slot, bool normalizeStringData) { - int i = indexOfMethodRelative<MethodSlot>(&m, slot, normalizeStringData); - if (i >= 0) - i += m->methodOffset(); - return i; + return indexOfMethodRelative<MethodSlot>(m, slot, normalizeStringData); } static const QMetaObject *QMetaObject_findMetaObject(const QMetaObject *self, const char *name) @@ -1577,6 +1604,12 @@ bool QMetaMethod::invoke(QObject *object, : Qt::QueuedConnection; } +#ifdef QT_NO_THREAD + if (connectionType == Qt::BlockingQueuedConnection) { + connectionType = Qt::DirectConnection; + } +#endif + // invoke! void *param[] = { returnValue.data(), @@ -1592,10 +1625,20 @@ bool QMetaMethod::invoke(QObject *object, val9.data() }; // recompute the methodIndex by reversing the arithmetic in QMetaObject::property() - int methodIndex = ((handle - priv(mobj->d.data)->methodData) / 5) + mobj->methodOffset(); + int idx_relative = ((handle - priv(mobj->d.data)->methodData) / 5); + int idx_offset = mobj->methodOffset(); + QObjectPrivate::StaticMetaCallFunction callFunction = + (QMetaObjectPrivate::get(mobj)->revision >= 6 && mobj->d.extradata) + ? reinterpret_cast<const QMetaObjectExtraData *>(mobj->d.extradata)->static_metacall : 0; + if (connectionType == Qt::DirectConnection) { - return QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, methodIndex, param) < 0; - } else { + if (callFunction) { + callFunction(object, QMetaObject::InvokeMetaMethod, idx_relative, param); + return true; + } else { + return QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, idx_relative + idx_offset, param) < 0; + } + } else if (connectionType == Qt::QueuedConnection) { if (returnValue.data()) { qWarning("QMetaMethod::invoke: Unable to invoke methods with return values in " "queued connections"); @@ -1628,40 +1671,21 @@ bool QMetaMethod::invoke(QObject *object, } } - if (connectionType == Qt::QueuedConnection) { - QCoreApplication::postEvent(object, new QMetaCallEvent(methodIndex, - 0, - -1, - nargs, - types, - args)); - } else { - if (currentThread == objectThread) { - qWarning("QMetaMethod::invoke: Dead lock detected in " - "BlockingQueuedConnection: Receiver is %s(%p)", - mobj->className(), object); - } + QCoreApplication::postEvent(object, new QMetaCallEvent(idx_offset, idx_relative, callFunction, + 0, -1, nargs, types, args)); + } else { // blocking queued connection +#ifndef QT_NO_THREAD + if (currentThread == objectThread) { + qWarning("QMetaMethod::invoke: Dead lock detected in " + "BlockingQueuedConnection: Receiver is %s(%p)", + mobj->className(), object); + } - // blocking queued connection -#ifdef QT_NO_THREAD - QCoreApplication::postEvent(object, new QMetaCallEvent(methodIndex, - 0, - -1, - nargs, - types, - args)); -#else - QSemaphore semaphore; - QCoreApplication::postEvent(object, new QMetaCallEvent(methodIndex, - 0, - -1, - nargs, - types, - args, - &semaphore)); - semaphore.acquire(); + QSemaphore semaphore; + QCoreApplication::postEvent(object, new QMetaCallEvent(idx_offset, idx_relative, callFunction, + 0, -1, 0, 0, param, &semaphore)); + semaphore.acquire(); #endif // QT_NO_THREAD - } } return true; } |