diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 5cb30a74ac..a8e8866339 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -3654,6 +3654,21 @@ const char* QMetaClassInfo::value() const return rawStringData(mobj, mobj->d.data[handle + 1]); } +/*! + \class QMethodRawArguments + \internal + + A wrapper class for the void ** arguments array used by the meta + object system. If a slot uses a single argument of this type, + the meta object system will pass the raw arguments array directly + to the slot and set the arguments count in the slot description to + zero, so that any signal can connect to it. + + This is used internally to implement signal relay functionality in + our state machine and dbus. +*/ + + /*! \macro QGenericArgument Q_ARG(Type, const Type &value) \relates QMetaObject diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index dc2d832fe5..9f654b0318 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -285,6 +285,10 @@ class QMetaEnum; class QMetaProperty; class QMetaClassInfo; +struct QMethodRawArguments +{ + void **arguments; +}; class Q_CORE_EXPORT QGenericArgument { diff --git a/src/corelib/statemachine/qsignaleventgenerator_p.h b/src/corelib/statemachine/qsignaleventgenerator_p.h index 72592b8731..a9d5b96920 100644 --- a/src/corelib/statemachine/qsignaleventgenerator_p.h +++ b/src/corelib/statemachine/qsignaleventgenerator_p.h @@ -62,13 +62,12 @@ class QStateMachine; class QSignalEventGenerator : public QObject { - Q_OBJECT_FAKE + Q_OBJECT public: QSignalEventGenerator(QStateMachine *parent); -private: -// slots - void execute(void **_a); +private Q_SLOTS: + void execute(QMethodRawArguments a); private: Q_DISABLE_COPY_MOVE(QSignalEventGenerator) diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 945e36968f..0ed92514f9 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -3045,102 +3045,14 @@ void QStateMachine::removeDefaultAnimation(QAbstractAnimation *animation) #endif // animation - -// Begin moc-generated code -- modify carefully (check "HAND EDIT" parts)! -struct qt_meta_stringdata_QSignalEventGenerator_t { - QByteArrayData data[3]; - char stringdata[32]; -}; -#define QT_MOC_LITERAL(idx, ofs, len) \ - Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \ - offsetof(qt_meta_stringdata_QSignalEventGenerator_t, stringdata) + ofs \ - - idx * sizeof(QByteArrayData) \ - ) -static const qt_meta_stringdata_QSignalEventGenerator_t qt_meta_stringdata_QSignalEventGenerator = { - { -QT_MOC_LITERAL(0, 0, 21), -QT_MOC_LITERAL(1, 22, 7), -QT_MOC_LITERAL(2, 30, 0) - }, - "QSignalEventGenerator\0execute\0\0" -}; -#undef QT_MOC_LITERAL - -static const uint qt_meta_data_QSignalEventGenerator[] = { - - // content: - 7, // revision - 0, // classname - 0, 0, // classinfo - 1, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: name, argc, parameters, tag, flags - 1, 0, 19, 2, 0x0a, - - // slots: parameters - QMetaType::Void, - - 0 // eod -}; - -void QSignalEventGenerator::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - QSignalEventGenerator *_t = static_cast(_o); - switch (_id) { - case 0: _t->execute(_a); break; // HAND EDIT: add the _a parameter - default: ; - } - } - Q_UNUSED(_a); -} - -const QMetaObject QSignalEventGenerator::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_QSignalEventGenerator.data, - qt_meta_data_QSignalEventGenerator, qt_static_metacall, 0, 0 } -}; - -const QMetaObject *QSignalEventGenerator::metaObject() const -{ - return &staticMetaObject; -} - -void *QSignalEventGenerator::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_QSignalEventGenerator.stringdata)) - return static_cast(const_cast< QSignalEventGenerator*>(this)); - return QObject::qt_metacast(_clname); -} - -int QSignalEventGenerator::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 1) - qt_static_metacall(this, _c, _id, _a); - _id -= 1; - } - return _id; -} -// End moc-generated code - -void QSignalEventGenerator::execute(void **_a) +void QSignalEventGenerator::execute(QMethodRawArguments a) { auto machinePrivate = QStateMachinePrivate::get(qobject_cast(parent())); if (machinePrivate->state != QStateMachinePrivate::Running) return; int signalIndex = senderSignalIndex(); Q_ASSERT(signalIndex != -1); - machinePrivate->handleTransitionSignal(sender(), signalIndex, _a); + machinePrivate->handleTransitionSignal(sender(), signalIndex, a.arguments); } QSignalEventGenerator::QSignalEventGenerator(QStateMachine *parent) diff --git a/src/dbus/qdbusabstractadaptor.cpp b/src/dbus/qdbusabstractadaptor.cpp index 993607a643..b7b291551d 100644 --- a/src/dbus/qdbusabstractadaptor.cpp +++ b/src/dbus/qdbusabstractadaptor.cpp @@ -276,11 +276,11 @@ void QDBusAdaptorConnector::polish() std::sort(adaptors.begin(), adaptors.end()); } -void QDBusAdaptorConnector::relaySlot(void **argv) +void QDBusAdaptorConnector::relaySlot(QMethodRawArguments argv) { QObject *sndr = sender(); if (Q_LIKELY(sndr)) { - relay(sndr, senderSignalIndex(), argv); + relay(sndr, senderSignalIndex(), argv.arguments); } else { qWarning("QtDBus: cannot relay signals from parent %s(%p \"%s\") unless they are emitted in the object's thread %s(%p \"%s\"). " "Current thread is %s(%p \"%s\").", @@ -333,120 +333,6 @@ void QDBusAdaptorConnector::relay(QObject *senderObj, int lastSignalIdx, void ** emit relaySignal(realObject, senderMetaObject, lastSignalIdx, args); } -// our Meta Object -// modify carefully: this has been hand-edited! -// the relaySlot slot gets called with the void** array - -struct qt_meta_stringdata_QDBusAdaptorConnector_t { - QByteArrayData data[10]; - char stringdata[96]; -}; -#define QT_MOC_LITERAL(idx, ofs, len) \ - Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \ - offsetof(qt_meta_stringdata_QDBusAdaptorConnector_t, stringdata) + ofs \ - - idx * sizeof(QByteArrayData) \ - ) -static const qt_meta_stringdata_QDBusAdaptorConnector_t qt_meta_stringdata_QDBusAdaptorConnector = { - { -QT_MOC_LITERAL(0, 0, 21), -QT_MOC_LITERAL(1, 22, 11), -QT_MOC_LITERAL(2, 34, 0), -QT_MOC_LITERAL(3, 35, 3), -QT_MOC_LITERAL(4, 39, 18), -QT_MOC_LITERAL(5, 58, 10), -QT_MOC_LITERAL(6, 69, 3), -QT_MOC_LITERAL(7, 73, 4), -QT_MOC_LITERAL(8, 78, 9), -QT_MOC_LITERAL(9, 88, 6) - }, - "QDBusAdaptorConnector\0relaySignal\0\0" - "obj\0const QMetaObject*\0metaObject\0sid\0" - "args\0relaySlot\0polish\0" -}; -#undef QT_MOC_LITERAL - -static const uint qt_meta_data_QDBusAdaptorConnector[] = { - - // content: - 7, // revision - 0, // classname - 0, 0, // classinfo - 3, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 1, // signalCount - - // signals: name, argc, parameters, tag, flags - 1, 4, 29, 2, 0x05, - - // slots: name, argc, parameters, tag, flags - 8, 0, 38, 2, 0x0a, - 9, 0, 39, 2, 0x0a, - - // signals: parameters - QMetaType::Void, QMetaType::QObjectStar, 0x80000000 | 4, QMetaType::Int, QMetaType::QVariantList, 3, 5, 6, 7, - - // slots: parameters - QMetaType::Void, - QMetaType::Void, - - 0 // eod -}; - -void QDBusAdaptorConnector::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - QDBusAdaptorConnector *_t = static_cast(_o); - switch (_id) { - case 0: _t->relaySignal((*reinterpret_cast< QObject*(*)>(_a[1])),(*reinterpret_cast< const QMetaObject*(*)>(_a[2])),(*reinterpret_cast< int(*)>(_a[3])),(*reinterpret_cast< const QVariantList(*)>(_a[4]))); break; - case 1: _t->relaySlot(_a); break; // HAND EDIT: add the _a parameter - case 2: _t->polish(); break; - default: ; - } - } -} - -const QMetaObject QDBusAdaptorConnector::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_QDBusAdaptorConnector.data, - qt_meta_data_QDBusAdaptorConnector, qt_static_metacall, 0, 0 } -}; - -const QMetaObject *QDBusAdaptorConnector::metaObject() const -{ - return &staticMetaObject; -} - -void *QDBusAdaptorConnector::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_QDBusAdaptorConnector.stringdata)) - return static_cast(const_cast< QDBusAdaptorConnector*>(this)); - return QObject::qt_metacast(_clname); -} - -int QDBusAdaptorConnector::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 3) - qt_static_metacall(this, _c, _id, _a); - _id -= 3; - } - return _id; -} - -// SIGNAL 0 -void QDBusAdaptorConnector::relaySignal(QObject * _t1, const QMetaObject * _t2, int _t3, const QVariantList & _t4) -{ - void *_a[] = { 0, const_cast(reinterpret_cast(&_t1)), const_cast(reinterpret_cast(&_t2)), const_cast(reinterpret_cast(&_t3)), const_cast(reinterpret_cast(&_t4)) }; - QMetaObject::activate(this, &staticMetaObject, 0, _a); -} - QT_END_NAMESPACE #endif // QT_NO_DBUS diff --git a/src/dbus/qdbusabstractadaptor_p.h b/src/dbus/qdbusabstractadaptor_p.h index 023b3b1be2..404901381b 100644 --- a/src/dbus/qdbusabstractadaptor_p.h +++ b/src/dbus/qdbusabstractadaptor_p.h @@ -92,7 +92,7 @@ public: class QDBusAdaptorConnector: public QObject { - Q_OBJECT_FAKE + Q_OBJECT public: // typedefs struct AdaptorData @@ -118,12 +118,11 @@ public: // methods void disconnectAllSignals(QObject *object); void relay(QObject *sender, int id, void **); -//public slots: - void relaySlot(void **); +public Q_SLOTS: + void relaySlot(QMethodRawArguments a); void polish(); -protected: -//signals: +Q_SIGNALS: void relaySignal(QObject *obj, const QMetaObject *metaObject, int sid, const QVariantList &args); public: // member variables diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 6a74e739e6..ace3a4c9f3 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -1217,18 +1217,22 @@ void Generator::generateStaticMetacall() fprintf(out, "%s(", f.name.constData()); int offset = 1; - int argsCount = f.arguments.count(); - for (int j = 0; j < argsCount; ++j) { - const ArgumentDef &a = f.arguments.at(j); - if (j) - fprintf(out, ","); - fprintf(out, "(*reinterpret_cast< %s>(_a[%d]))",a.typeNameForCast.constData(), offset++); - isUsed_a = true; - } - if (f.isPrivateSignal) { - if (argsCount > 0) - fprintf(out, ", "); - fprintf(out, "%s", "QPrivateSignal()"); + if (f.isRawSlot) { + fprintf(out, "QMethodRawArguments{ _a }"); + } else { + int argsCount = f.arguments.count(); + for (int j = 0; j < argsCount; ++j) { + const ArgumentDef &a = f.arguments.at(j); + if (j) + fprintf(out, ","); + fprintf(out, "(*reinterpret_cast< %s>(_a[%d]))",a.typeNameForCast.constData(), offset++); + isUsed_a = true; + } + if (f.isPrivateSignal) { + if (argsCount > 0) + fprintf(out, ", "); + fprintf(out, "%s", "QPrivateSignal()"); + } } fprintf(out, ");"); if (f.normalizedType != "void") { diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 8cc605fd8a..b98198d1d5 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -328,6 +328,11 @@ void Moc::parseFunctionArguments(FunctionDef *def) def->arguments.removeLast(); def->isPrivateSignal = true; } + if (def->arguments.size() == 1 + && def->arguments.constLast().normalizedType == "QMethodRawArguments") { + def->arguments.removeLast(); + def->isRawSlot = true; + } } bool Moc::testFunctionAttribute(FunctionDef *def) diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h index 687ea2552f..6785b7f9e8 100644 --- a/src/tools/moc/moc.h +++ b/src/tools/moc/moc.h @@ -115,6 +115,7 @@ struct FunctionDef bool isConstructor = false; bool isDestructor = false; bool isAbstract = false; + bool isRawSlot = false; QJsonObject toJson() const; static void accessToJson(QJsonObject *obj, Access acs);