aboutsummaryrefslogtreecommitdiffstats
path: root/src/webchannel/qmetaobjectpublisher.cpp
diff options
context:
space:
mode:
authorMilian Wolff <milian.wolff@kdab.com>2019-03-22 11:03:43 +0100
committerMilian Wolff <milian.wolff@kdab.com>2019-03-25 14:07:36 +0000
commit7a673eb1a6902ef6f2eb03d6beab139282b1e4a5 (patch)
treeaaa3e1c31152327b9662bee7a00c0249b916eb66 /src/webchannel/qmetaobjectpublisher.cpp
parent857cfc1adecd72750cea26d4c91371f4aaf9a68f (diff)
Publish overloaded methods and signals to JavaScript
Previously, we only published the first method or signal of any given name. We keep this behavior for the nice JavaScript notation that looks like a normal JavaScript method call `foo.bar(...)`. When you need to call a different overloaded method, this patch offers you to specify the explicit signature on the JavaScript side. I.e. when we have an object with `foo(int i)` and `foo(const QString &str, int i)`, then on the JavaScript a call to `obj.foo(...)` will always call the first method like before. But now you can specify the full QMetaMethod signature and call matching methods explicitly via `obj["foo(int)"]` or `obj["foo(QString,int)"]`. Automatic overload resolution on the C++ side for the nice notation cannot easily be implemented: We need to know the return value of the called function, otherwise we cannot construct a valid QGenericReturnArgument. Furthermore, we wouldn't be able to differentiate between e.g. any numeric types on the C++ side, since JavaScript only has a single `double` type internally. [ChangeLog][QWebChannel][General] It is now possible to explicitly call overloaded methods or connect to overloaded signals by specifying the full method or signal signature in string form on the JavaScript side. Fixes: QTBUG-73010 Change-Id: I4645edee97af56fd8d126e77d70dc33ed3513deb Reviewed-by: Arno Rehn <a.rehn@menlosystems.com> Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io> Reviewed-by: Milian Wolff <milian.wolff@kdab.com>
Diffstat (limited to 'src/webchannel/qmetaobjectpublisher.cpp')
-rw-r--r--src/webchannel/qmetaobjectpublisher.cpp29
1 files changed, 16 insertions, 13 deletions
diff --git a/src/webchannel/qmetaobjectpublisher.cpp b/src/webchannel/qmetaobjectpublisher.cpp
index 3c96126..3c1d030 100644
--- a/src/webchannel/qmetaobjectpublisher.cpp
+++ b/src/webchannel/qmetaobjectpublisher.cpp
@@ -196,19 +196,13 @@ QJsonObject QMetaObjectPublisher::classInfoForObject(const QObject *object, QWeb
propertyInfo.append(wrapResult(prop.read(object), transport));
qtProperties.append(propertyInfo);
}
- for (int i = 0; i < metaObject->methodCount(); ++i) {
- if (notifySignals.contains(i)) {
- continue;
- }
- const QMetaMethod &method = metaObject->method(i);
- //NOTE: this must be a string, otherwise it will be converted to '{}' in QML
- const QString &name = QString::fromLatin1(method.name());
- // optimize: skip overloaded methods/signals or property getters, on the JS side we can only
- // call one of them anyways
- // TODO: basic support for overloaded signals, methods
- if (identifiers.contains(name)) {
- continue;
- }
+ auto addMethod = [&qtSignals, &qtMethods, &identifiers](int i, const QMetaMethod &method, const QByteArray &rawName) {
+ //NOTE: the name must be a string, otherwise it will be converted to '{}' in QML
+ const auto name = QString::fromLatin1(rawName);
+ // only the first method gets called with its name directly
+ // others must be called by explicitly passing the method signature
+ if (identifiers.contains(name))
+ return;
identifiers << name;
// send data as array to client with format: [name, index]
QJsonArray data;
@@ -219,6 +213,15 @@ QJsonObject QMetaObjectPublisher::classInfoForObject(const QObject *object, QWeb
} else if (method.access() == QMetaMethod::Public) {
qtMethods.append(data);
}
+ };
+ for (int i = 0; i < metaObject->methodCount(); ++i) {
+ if (notifySignals.contains(i)) {
+ continue;
+ }
+ const QMetaMethod &method = metaObject->method(i);
+ addMethod(i, method, method.name());
+ // for overload resolution also pass full method signature
+ addMethod(i, method, method.methodSignature());
}
for (int i = 0; i < metaObject->enumeratorCount(); ++i) {
QMetaEnum enumerator = metaObject->enumerator(i);