diff options
-rw-r--r-- | src/webchannel/qmetaobjectpublisher.cpp | 36 | ||||
-rw-r--r-- | src/webchannel/qmetaobjectpublisher_p.h | 4 | ||||
-rw-r--r-- | src/webchannel/qobject.js | 19 | ||||
-rw-r--r-- | tests/webchannel/tst_webchannel.cpp | 4 |
4 files changed, 33 insertions, 30 deletions
diff --git a/src/webchannel/qmetaobjectpublisher.cpp b/src/webchannel/qmetaobjectpublisher.cpp index 3621fca..27c7d70 100644 --- a/src/webchannel/qmetaobjectpublisher.cpp +++ b/src/webchannel/qmetaobjectpublisher.cpp @@ -140,8 +140,8 @@ void QMetaObjectPublisherPrivate::initializePropertyUpdates(const QObject *const qWarning() << "Invalid property info encountered:" << propertyInfoVar; continue; } - const QString &propertyName = propertyInfo.at(0).toString(); - const QJsonArray &signalData = propertyInfo.at(1).toArray(); + const int propertyIndex = propertyInfo.at(0).toInt(); + const QJsonArray &signalData = propertyInfo.at(2).toArray(); if (signalData.isEmpty()) { // Property without NOTIFY signal @@ -150,14 +150,14 @@ void QMetaObjectPublisherPrivate::initializePropertyUpdates(const QObject *const const int signalIndex = signalData.at(1).toInt(); - QSet<QString> &connectedProperties = signalToPropertyMap[object][signalIndex]; + QSet<int> &connectedProperties = signalToPropertyMap[object][signalIndex]; // Only connect for a property update once if (connectedProperties.isEmpty()) { signalHandler.connectTo(object, signalIndex); } - connectedProperties.insert(propertyName); + connectedProperties.insert(propertyIndex); } // also always connect to destroyed signal @@ -184,17 +184,12 @@ void QMetaObjectPublisherPrivate::sendPendingPropertyUpdates() QJsonObject sigs; const SignalToArgumentsMap::const_iterator sigEnd = it.value().constEnd(); for (SignalToArgumentsMap::const_iterator sigIt = it.value().constBegin(); sigIt != sigEnd; ++sigIt) { - // TODO: use property indices - foreach (const QString &propertyName, objectsSignalToPropertyMap.value(sigIt.key())) { - int propertyIndex = metaObject->indexOfProperty(qPrintable(propertyName)); - if (propertyIndex == -1) { - qWarning("Unknown property %d encountered", propertyIndex); - continue; - } + // TODO: can we get rid of the int <-> string conversions here? + foreach (const int propertyIndex, objectsSignalToPropertyMap.value(sigIt.key())) { const QMetaProperty &property = metaObject->property(propertyIndex); - properties[QString::fromLatin1(property.name())] = QJsonValue::fromVariant(property.read(object)); + Q_ASSERT(property.isValid()); + properties[QString::number(propertyIndex)] = QJsonValue::fromVariant(property.read(object)); } - // TODO: can we get rid of the int <-> string conversions here? sigs[QString::number(sigIt.key())] = QJsonArray::fromVariantList(sigIt.value()); } QJsonObject obj; @@ -390,6 +385,7 @@ QJsonObject QMetaObjectPublisher::classInfoForObject(QObject *object) const const QMetaProperty &prop = metaObject->property(i); QJsonArray propertyInfo; const QString &propertyName = QString::fromLatin1(prop.name()); + propertyInfo.append(i); propertyInfo.append(propertyName); identifiers << propertyName; QJsonArray signalInfo; @@ -520,14 +516,16 @@ bool QMetaObjectPublisher::handleRequest(const QJsonObject &message) d->signalHandler.disconnectFrom(object, payload.value(KEY_SIGNAL).toInt(-1)); return true; } else if (type == TYPE_SET_PROPERTY) { - // TODO: use property indices - const QString &propertyName = payload.value(KEY_PROPERTY).toString(); - const int propertyIdx = object->metaObject()->indexOfProperty(qPrintable(propertyName)); - if (propertyIdx == -1) { - qWarning() << "Cannot set unknown property" << propertyName << "of object" << objectName; + const int propertyIdx = payload.value(KEY_PROPERTY).toInt(-1); + QMetaProperty property = object->metaObject()->property(propertyIdx); + if (!property.isValid()) { + qWarning() << "Cannot set unknown property" << payload.value(KEY_PROPERTY) << "of object" << objectName; + return false; + } else if (!object->metaObject()->property(propertyIdx).write(object, payload.value(KEY_VALUE).toVariant())) { + qWarning() << "Could not write value " << payload.value(KEY_VALUE) + << "to property" << property.name() << "of object" << objectName; return false; } - object->metaObject()->property(propertyIdx).write(object, payload.value(KEY_VALUE).toVariant()); return true; } } diff --git a/src/webchannel/qmetaobjectpublisher_p.h b/src/webchannel/qmetaobjectpublisher_p.h index 969421a..4df5b38 100644 --- a/src/webchannel/qmetaobjectpublisher_p.h +++ b/src/webchannel/qmetaobjectpublisher_p.h @@ -153,9 +153,9 @@ struct Q_WEBCHANNEL_EXPORT QMetaObjectPublisherPrivate // Map the registered objects to their id. QHash<const QObject *, QString> registeredObjectIds; - // Map of object names to maps of signal indices to a set of all their properties. + // Map of objects to maps of signal indices to a set of all their property indices. // The last value is a set as a signal can be the notify signal of multiple properties. - typedef QHash<int, QSet<QString> > SignalToPropertyNameMap; + typedef QHash<int, QSet<int> > SignalToPropertyNameMap; QHash<const QObject *, SignalToPropertyNameMap> signalToPropertyMap; // Objects that changed their properties and are waiting for idle client. diff --git a/src/webchannel/qobject.js b/src/webchannel/qobject.js index da8b3de..5fae44c 100644 --- a/src/webchannel/qobject.js +++ b/src/webchannel/qobject.js @@ -146,9 +146,9 @@ function QObject(name, data, webChannel) this.propertyUpdate = function(signals, propertyMap) { // update property cache - for (var propertyName in propertyMap) { - var propertyValue = propertyMap[propertyName]; - object.__propertyCache__[propertyName] = propertyValue; + for (var propertyIndex in propertyMap) { + var propertyValue = propertyMap[propertyIndex]; + object.__propertyCache__[propertyIndex] = propertyValue; } for (var signalName in signals) { @@ -187,10 +187,11 @@ function QObject(name, data, webChannel) function bindGetterSetter(propertyInfo) { - var propertyName = propertyInfo[0]; - var notifySignalData = propertyInfo[1]; + var propertyIndex = propertyInfo[0]; + var propertyName = propertyInfo[1]; + var notifySignalData = propertyInfo[2]; // initialize property cache with current value - object.__propertyCache__[propertyName] = propertyInfo[2] + object.__propertyCache__[propertyIndex] = propertyInfo[3]; if (notifySignalData) { if (notifySignalData[0] === 1) { @@ -205,13 +206,13 @@ function QObject(name, data, webChannel) console.warn("Property setter for " + propertyName + " called with undefined value!"); return; } - object.__propertyCache__[propertyName] = value; - webChannel.exec({"type": "Qt.setProperty", "object": object.__id__, "property": propertyName, "value": value }); + object.__propertyCache__[propertyIndex] = value; + webChannel.exec({"type": "Qt.setProperty", "object": object.__id__, "property": propertyIndex, "value": value }); }); object.__defineGetter__(propertyName, function () { return (function (callback) { - var propertyValue = object.__propertyCache__[propertyName]; + var propertyValue = object.__propertyCache__[propertyIndex]; if (propertyValue === undefined) { // This shouldn't happen console.warn("Undefined value in property cache for property \"" + propertyName + "\" in object " + object.__id__); diff --git a/tests/webchannel/tst_webchannel.cpp b/tests/webchannel/tst_webchannel.cpp index 698b5e2..3b90744 100644 --- a/tests/webchannel/tst_webchannel.cpp +++ b/tests/webchannel/tst_webchannel.cpp @@ -164,6 +164,7 @@ void TestWebChannel::testInfoForObject() QJsonArray expected; { QJsonArray property; + property.append(obj.metaObject()->indexOfProperty("objectName")); property.append(QStringLiteral("objectName")); { QJsonArray signal; @@ -176,6 +177,7 @@ void TestWebChannel::testInfoForObject() } { QJsonArray property; + property.append(obj.metaObject()->indexOfProperty("foo")); property.append(QStringLiteral("foo")); { QJsonArray signal; @@ -186,6 +188,7 @@ void TestWebChannel::testInfoForObject() } { QJsonArray property; + property.append(obj.metaObject()->indexOfProperty("asdf")); property.append(QStringLiteral("asdf")); { QJsonArray signal; @@ -198,6 +201,7 @@ void TestWebChannel::testInfoForObject() } { QJsonArray property; + property.append(obj.metaObject()->indexOfProperty("bar")); property.append(QStringLiteral("bar")); { QJsonArray signal; |