diff options
-rw-r--r-- | src/webchannel/qmetaobjectpublisher.cpp | 71 | ||||
-rw-r--r-- | src/webchannel/qmetaobjectpublisher.h | 5 | ||||
-rw-r--r-- | src/webchannel/qmetaobjectpublisher_p.h | 6 | ||||
-rw-r--r-- | tests/webchannel/tst_webchannel.cpp | 132 |
4 files changed, 143 insertions, 71 deletions
diff --git a/src/webchannel/qmetaobjectpublisher.cpp b/src/webchannel/qmetaobjectpublisher.cpp index 375cf1b..0de25c5 100644 --- a/src/webchannel/qmetaobjectpublisher.cpp +++ b/src/webchannel/qmetaobjectpublisher.cpp @@ -122,11 +122,11 @@ void QMetaObjectPublisherPrivate::initializeClients() { const QHash<QString, QObject *>::const_iterator end = registeredObjects.constEnd(); for (QHash<QString, QObject *>::const_iterator it = registeredObjects.constBegin(); it != end; ++it) { - const QVariantMap &info = q->classInfoForObject(it.value()); + const QJsonObject &info = q->classInfoForObject(it.value()); if (!propertyUpdatesInitialized) { initializePropertyUpdates(it.value(), info); } - objectInfos[it.key()] = QJsonObject::fromVariantMap(info); + objectInfos[it.key()] = info; } } webChannel->sendMessage(TYPE_INIT, objectInfos); @@ -134,16 +134,16 @@ void QMetaObjectPublisherPrivate::initializeClients() pendingInit = false; } -void QMetaObjectPublisherPrivate::initializePropertyUpdates(const QObject *const object, const QVariantMap &objectInfo) +void QMetaObjectPublisherPrivate::initializePropertyUpdates(const QObject *const object, const QJsonObject &objectInfo) { - foreach (const QVariant &propertyInfoVar, objectInfo[KEY_PROPERTIES].toList()) { - const QVariantList &propertyInfo = propertyInfoVar.toList(); + foreach (const QJsonValue &propertyInfoVar, objectInfo[KEY_PROPERTIES].toArray()) { + const QJsonArray &propertyInfo = propertyInfoVar.toArray(); if (propertyInfo.size() < 2) { qWarning() << "Invalid property info encountered:" << propertyInfoVar; continue; } const QString &propertyName = propertyInfo.at(0).toString(); - const QVariantList &signalData = propertyInfo.at(1).toList(); + const QJsonArray &signalData = propertyInfo.at(1).toArray(); if (signalData.isEmpty()) { // Property without NOTIFY signal @@ -259,7 +259,7 @@ bool QMetaObjectPublisherPrivate::invokeMethod(QObject *const object, const int arguments[5], arguments[6], arguments[7], arguments[8], arguments[9]); // and send the return value to the client - webChannel->respond(id, QJsonValue::fromVariant(wrapResult(returnValue))); + webChannel->respond(id, wrapResult(returnValue)); return true; } @@ -305,10 +305,10 @@ void QMetaObjectPublisherPrivate::objectDestroyed(const QObject *object) wrappedObjects.remove(object); } -QVariant QMetaObjectPublisherPrivate::wrapResult(const QVariant &result) +QJsonValue QMetaObjectPublisherPrivate::wrapResult(const QVariant &result) { if (QObject *object = result.value<QObject *>()) { - QVariantMap &objectInfo = wrappedObjects[object]; + QJsonObject &objectInfo = wrappedObjects[object]; if (!objectInfo.isEmpty()) { // already registered, use cached information Q_ASSERT(registeredObjectIds.contains(object)); @@ -332,7 +332,7 @@ QVariant QMetaObjectPublisherPrivate::wrapResult(const QVariant &result) } // no need to wrap this - return result; + return QJsonValue::fromVariant(result); } void QMetaObjectPublisherPrivate::deleteWrappedObject(QObject *object) const @@ -355,14 +355,14 @@ QMetaObjectPublisher::~QMetaObjectPublisher() } -QVariantMap QMetaObjectPublisher::classInfoForObjects(const QVariantMap &objectMap) const +QJsonObject QMetaObjectPublisher::classInfoForObjects(const QVariantMap &objectMap) const { - QVariantMap ret; + QJsonObject ret; QMap<QString, QVariant>::const_iterator it = objectMap.constBegin(); while (it != objectMap.constEnd()) { QObject *object = it.value().value<QObject *>(); if (object) { - const QVariantMap &info = classInfoForObject(object); + const QJsonObject &info = classInfoForObject(object); if (!info.isEmpty()) { ret[it.key()] = info; } @@ -372,25 +372,29 @@ QVariantMap QMetaObjectPublisher::classInfoForObjects(const QVariantMap &objectM return ret; } -QVariantMap QMetaObjectPublisher::classInfoForObject(QObject *object) const +QJsonObject QMetaObjectPublisher::classInfoForObject(QObject *object) const { - QVariantMap data; + QJsonObject data; if (!object) { qWarning("null object given to MetaObjectPublisher - bad API usage?"); return data; } - QVariantList qtSignals, qtMethods; - QVariantList qtProperties; - QVariantMap qtEnums; + + QJsonArray qtSignals; + QJsonArray qtMethods; + QJsonArray qtProperties; + QJsonObject qtEnums; + const QMetaObject *metaObject = object->metaObject(); QSet<int> notifySignals; QSet<QString> identifiers; for (int i = 0; i < metaObject->propertyCount(); ++i) { const QMetaProperty &prop = metaObject->property(i); - QVariantList propertyInfo; + QJsonArray propertyInfo; const QString &propertyName = QString::fromLatin1(prop.name()); propertyInfo.append(propertyName); identifiers << propertyName; + QJsonArray signalInfo; if (prop.hasNotifySignal()) { notifySignals << prop.notifySignalIndex(); const int numParams = prop.notifySignal().parameterCount(); @@ -404,20 +408,19 @@ QVariantMap QMetaObjectPublisher::classInfoForObject(QObject *object) const if (notifySignal.length() == changedSuffix.length() + propertyName.length() && notifySignal.endsWith(changedSuffix) && notifySignal.startsWith(prop.name())) { - propertyInfo.append(QVariant::fromValue(QVariantList() << 1 << prop.notifySignalIndex())); + signalInfo.append(1); } else { - propertyInfo.append(QVariant::fromValue(QVariantList() << QString::fromLatin1(notifySignal) << prop.notifySignalIndex())); - } - } else { - if (!prop.isConstant()) { - qWarning("Property '%s'' of object '%s' has no notify signal and is not constant, " - "value updates in HTML will be broken!", - prop.name(), object->metaObject()->className()); + signalInfo.append(QString::fromLatin1(notifySignal)); } - propertyInfo.append(QVariant::fromValue(QVariantList())); + signalInfo.append(prop.notifySignalIndex()); + } else if (!prop.isConstant()) { + qWarning("Property '%s'' of object '%s' has no notify signal and is not constant, " + "value updates in HTML will be broken!", + prop.name(), object->metaObject()->className()); } - propertyInfo.append(prop.read(object)); - qtProperties.append(QVariant::fromValue(propertyInfo)); + propertyInfo.append(signalInfo); + propertyInfo.append(QJsonValue::fromVariant(prop.read(object))); + qtProperties.append(propertyInfo); } for (int i = 0; i < metaObject->methodCount(); ++i) { if (notifySignals.contains(i)) { @@ -434,7 +437,9 @@ QVariantMap QMetaObjectPublisher::classInfoForObject(QObject *object) const } identifiers << name; // send data as array to client with format: [name, index] - const QVariant data = QVariant::fromValue(QVariantList() << name << i); + QJsonArray data; + data.append(name); + data.append(i); if (method.methodType() == QMetaMethod::Signal) { qtSignals.append(data); } else if (method.access() == QMetaMethod::Public) { @@ -443,7 +448,7 @@ QVariantMap QMetaObjectPublisher::classInfoForObject(QObject *object) const } for (int i = 0; i < metaObject->enumeratorCount(); ++i) { QMetaEnum enumerator = metaObject->enumerator(i); - QVariantMap values; + QJsonObject values; for (int k = 0; k < enumerator.keyCount(); ++k) { values[QString::fromLatin1(enumerator.key(k))] = enumerator.value(k); } @@ -451,7 +456,7 @@ QVariantMap QMetaObjectPublisher::classInfoForObject(QObject *object) const } data[KEY_SIGNALS] = qtSignals; data[KEY_METHODS] = qtMethods; - data[KEY_PROPERTIES] = QVariant::fromValue(qtProperties); + data[KEY_PROPERTIES] = qtProperties; data[KEY_ENUMS] = qtEnums; return data; } diff --git a/src/webchannel/qmetaobjectpublisher.h b/src/webchannel/qmetaobjectpublisher.h index f4763a7..9d17aff 100644 --- a/src/webchannel/qmetaobjectpublisher.h +++ b/src/webchannel/qmetaobjectpublisher.h @@ -45,6 +45,7 @@ #include <QObject> #include <QVariant> +#include <QJsonObject> #include "qwebchannelglobal.h" @@ -62,8 +63,8 @@ public: explicit QMetaObjectPublisher(QObject *parent = 0); virtual ~QMetaObjectPublisher(); - Q_INVOKABLE QVariantMap classInfoForObjects(const QVariantMap &objects) const; - Q_INVOKABLE QVariantMap classInfoForObject(QObject *object) const; + Q_INVOKABLE QJsonObject classInfoForObjects(const QVariantMap &objects) const; + Q_INVOKABLE QJsonObject classInfoForObject(QObject *object) const; /** * Register a map of string ID to QObject* objects. diff --git a/src/webchannel/qmetaobjectpublisher_p.h b/src/webchannel/qmetaobjectpublisher_p.h index e364510..969421a 100644 --- a/src/webchannel/qmetaobjectpublisher_p.h +++ b/src/webchannel/qmetaobjectpublisher_p.h @@ -80,7 +80,7 @@ struct Q_WEBCHANNEL_EXPORT QMetaObjectPublisherPrivate * When receiving a notify signal, it will store the information in pendingPropertyUpdates which * gets send via a Qt.propertyUpdate message to the server when the grouping timer timeouts. */ - void initializePropertyUpdates(const QObject *const object, const QVariantMap &objectInfo); + void initializePropertyUpdates(const QObject *const object, const QJsonObject &objectInfo); /** * Send the clients the new property values since the last time this function was invoked. @@ -121,7 +121,7 @@ struct Q_WEBCHANNEL_EXPORT QMetaObjectPublisherPrivate * * TODO: support wrapping of initially-registered objects */ - QVariant wrapResult(const QVariant &result); + QJsonValue wrapResult(const QVariant &result); /** * Invoke delete later on @p object. @@ -165,7 +165,7 @@ struct Q_WEBCHANNEL_EXPORT QMetaObjectPublisherPrivate PendingPropertyUpdates pendingPropertyUpdates; // Maps wrapped object to class info - QHash<const QObject *, QVariantMap> wrappedObjects; + QHash<const QObject *, QJsonObject> wrappedObjects; // Aggregate property updates since we get multiple Qt.idle message when we have multiple // clients. They all share the same QWebProcess though so we must take special care to diff --git a/tests/webchannel/tst_webchannel.cpp b/tests/webchannel/tst_webchannel.cpp index e997bd7..698b5e2 100644 --- a/tests/webchannel/tst_webchannel.cpp +++ b/tests/webchannel/tst_webchannel.cpp @@ -95,54 +95,120 @@ void TestWebChannel::testInfoForObject() TestObject obj; obj.setObjectName("myTestObject"); QMetaObjectPublisher publisher; - const QVariantMap info = publisher.classInfoForObject(&obj); + const QJsonObject info = publisher.classInfoForObject(&obj); - QCOMPARE(info.keys(), QList<QString>() << "enums" << "methods" << "properties" << "signals"); + QCOMPARE(info.keys(), QStringList() << "enums" << "methods" << "properties" << "signals"); { // enums - QVariantMap expected; - QVariantMap fooEnum; + QJsonObject fooEnum; fooEnum["Asdf"] = TestObject::Asdf; fooEnum["Bar"] = TestObject::Bar; + QJsonObject expected; expected["Foo"] = fooEnum; - QCOMPARE(info["enums"].toMap(), expected); + QCOMPARE(info["enums"].toObject(), expected); } { // methods & slots - QVariantList expected; - expected << QVariant::fromValue(QVariantList() << "deleteLater" << obj.metaObject()->indexOfMethod("deleteLater()")); - expected << QVariant::fromValue(QVariantList() << "slot1" << obj.metaObject()->indexOfMethod("slot1()")); - expected << QVariant::fromValue(QVariantList() << "slot2" << obj.metaObject()->indexOfMethod("slot2(QString)")); - expected << QVariant::fromValue(QVariantList() << "method1" << obj.metaObject()->indexOfMethod("method1()")); - QCOMPARE(info["methods"].toList(), expected); + QJsonArray expected; + { + QJsonArray method; + method.append(QStringLiteral("deleteLater")); + method.append(obj.metaObject()->indexOfMethod("deleteLater()")); + expected.append(method); + } + { + QJsonArray method; + method.append(QStringLiteral("slot1")); + method.append(obj.metaObject()->indexOfMethod("slot1()")); + expected.append(method); + } + { + QJsonArray method; + method.append(QStringLiteral("slot2")); + method.append(obj.metaObject()->indexOfMethod("slot2(QString)")); + expected.append(method); + } + { + QJsonArray method; + method.append(QStringLiteral("method1")); + method.append(obj.metaObject()->indexOfMethod("method1()")); + expected.append(method); + } + QCOMPARE(info["methods"].toArray(), expected); } { // signals - QVariantList expected; - expected << QVariant::fromValue(QVariantList() << "destroyed" << obj.metaObject()->indexOfMethod("destroyed(QObject*)")); - expected << QVariant::fromValue(QVariantList() << "sig1" << obj.metaObject()->indexOfMethod("sig1()")); - expected << QVariant::fromValue(QVariantList() << "sig2" << obj.metaObject()->indexOfMethod("sig2(QString)")); - QCOMPARE(info["signals"].toList(), expected); + QJsonArray expected; + { + QJsonArray signal; + signal.append(QStringLiteral("destroyed")); + signal.append(obj.metaObject()->indexOfMethod("destroyed(QObject*)")); + expected.append(signal); + } + { + QJsonArray signal; + signal.append(QStringLiteral("sig1")); + signal.append(obj.metaObject()->indexOfMethod("sig1()")); + expected.append(signal); + } + { + QJsonArray signal; + signal.append(QStringLiteral("sig2")); + signal.append(obj.metaObject()->indexOfMethod("sig2(QString)")); + expected.append(signal); + } + QCOMPARE(info["signals"].toArray(), expected); } { // properties - QVariantList expected; - expected << QVariant::fromValue(QVariantList() << "objectName" - << QVariant::fromValue(QVariantList() - << 1 << obj.metaObject()->indexOfMethod("objectNameChanged(QString)")) - << obj.objectName()); - expected << QVariant::fromValue(QVariantList() << "foo" - << QVariant::fromValue(QVariantList()) - << obj.foo()); - expected << QVariant::fromValue(QVariantList() << "asdf" - << QVariant::fromValue(QVariantList() - << 1 << obj.metaObject()->indexOfMethod("asdfChanged()")) - << obj.asdf()); - expected << QVariant::fromValue(QVariantList() << "bar" - << QVariant::fromValue(QVariantList() - << "theBarHasChanged" << obj.metaObject()->indexOfMethod("theBarHasChanged()")) - << obj.bar()); - QCOMPARE(info["properties"].toList(), expected); + QJsonArray expected; + { + QJsonArray property; + property.append(QStringLiteral("objectName")); + { + QJsonArray signal; + signal.append(1); + signal.append(obj.metaObject()->indexOfMethod("objectNameChanged(QString)")); + property.append(signal); + } + property.append(obj.objectName()); + expected.append(property); + } + { + QJsonArray property; + property.append(QStringLiteral("foo")); + { + QJsonArray signal; + property.append(signal); + } + property.append(obj.foo()); + expected.append(property); + } + { + QJsonArray property; + property.append(QStringLiteral("asdf")); + { + QJsonArray signal; + signal.append(1); + signal.append(obj.metaObject()->indexOfMethod("asdfChanged()")); + property.append(signal); + } + property.append(obj.asdf()); + expected.append(property); + } + { + QJsonArray property; + property.append(QStringLiteral("bar")); + { + QJsonArray signal; + signal.append(QStringLiteral("theBarHasChanged")); + signal.append(obj.metaObject()->indexOfMethod("theBarHasChanged()")); + property.append(signal); + } + property.append(obj.bar()); + expected.append(property); + } + QCOMPARE(info["properties"].toArray(), expected); } } |