aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorMaximilian Goldstein <max.goldstein@qt.io>2021-02-05 15:14:42 +0100
committerMaximilian Goldstein <max.goldstein@qt.io>2021-02-05 17:19:54 +0100
commit33f3d70c74564fb1e296537e14d1e0bddb4bb944 (patch)
tree3def672f5eb1fb2b004d59eed4ec37423f56c4ae /src/qml
parent4938984f9a779192264757a06e6ca555fc8f5e91 (diff)
qqmlproxymetaobject: Support invoking methods and slots
Previously this just failed silently and returned garbage data. Change-Id: Ia8b72836aa0ccfd50fd18b0f813c2bf3a00801c5 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/qml/qqmlproxymetaobject.cpp84
-rw-r--r--src/qml/qml/qqmlproxymetaobject_p.h2
2 files changed, 55 insertions, 31 deletions
diff --git a/src/qml/qml/qqmlproxymetaobject.cpp b/src/qml/qml/qqmlproxymetaobject.cpp
index c5cb2ec059..21d3c7ed05 100644
--- a/src/qml/qml/qqmlproxymetaobject.cpp
+++ b/src/qml/qml/qqmlproxymetaobject.cpp
@@ -65,6 +65,41 @@ QQmlProxyMetaObject::~QQmlProxyMetaObject()
proxies = nullptr;
}
+QObject *QQmlProxyMetaObject::getProxy(int index)
+{
+ if (!proxies) {
+ if (!proxies) {
+ proxies = new QObject*[metaObjects->count()];
+ ::memset(proxies, 0,
+ sizeof(QObject *) * metaObjects->count());
+ }
+ }
+
+ if (!proxies[index]) {
+ const ProxyData &data = metaObjects->at(index);
+ if (!data.createFunc)
+ return nullptr;
+
+ QObject *proxy = data.createFunc(object);
+ const QMetaObject *metaObject = proxy->metaObject();
+ proxies[index] = proxy;
+
+ int localOffset = data.metaObject->methodOffset();
+ int methodOffset = metaObject->methodOffset();
+ int methods = metaObject->methodCount() - methodOffset;
+
+ // ### - Can this be done more optimally?
+ for (int jj = 0; jj < methods; ++jj) {
+ QMetaMethod method =
+ metaObject->method(jj + methodOffset);
+ if (method.methodType() == QMetaMethod::Signal)
+ QQmlPropertyPrivate::connect(proxy, methodOffset + jj, object, localOffset + jj);
+ }
+ }
+
+ return proxies[index];
+}
+
int QQmlProxyMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void **a)
{
Q_ASSERT(object == o);
@@ -74,38 +109,13 @@ int QQmlProxyMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void
id >= metaObjects->constLast().propertyOffset) {
for (int ii = 0; ii < metaObjects->count(); ++ii) {
- const ProxyData &data = metaObjects->at(ii);
- if (id >= data.propertyOffset) {
- if (!proxies) {
- proxies = new QObject*[metaObjects->count()];
- ::memset(proxies, 0,
- sizeof(QObject *) * metaObjects->count());
- }
-
- if (!proxies[ii]) {
- if (!data.createFunc)
- continue;
- QObject *proxy = data.createFunc(object);
- const QMetaObject *metaObject = proxy->metaObject();
- proxies[ii] = proxy;
-
- int localOffset = data.metaObject->methodOffset();
- int methodOffset = metaObject->methodOffset();
- int methods = metaObject->methodCount() - methodOffset;
-
- // ### - Can this be done more optimally?
- for (int jj = 0; jj < methods; ++jj) {
- QMetaMethod method =
- metaObject->method(jj + methodOffset);
- if (method.methodType() == QMetaMethod::Signal)
- QQmlPropertyPrivate::connect(proxy, methodOffset + jj, object, localOffset + jj);
- }
- }
-
- int proxyOffset = proxies[ii]->metaObject()->propertyOffset();
- int proxyId = id - data.propertyOffset + proxyOffset;
+ const int globalPropertyOffset = metaObjects->at(ii).propertyOffset;
+ if (id >= globalPropertyOffset) {
+ QObject *proxy = getProxy(ii);
+ const int localProxyOffset = proxy->metaObject()->propertyOffset();
+ const int localProxyId = id - globalPropertyOffset + localProxyOffset;
- return proxies[ii]->qt_metacall(c, proxyId, a);
+ return proxy->qt_metacall(c, localProxyId, a);
}
}
} else if (c == QMetaObject::InvokeMetaMethod &&
@@ -114,6 +124,18 @@ int QQmlProxyMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void
if (m.methodType() == QMetaMethod::Signal) {
QMetaObject::activate(object, id, a);
return -1;
+ } else {
+ for (int ii = 0; ii < metaObjects->count(); ++ii) {
+ const int globalMethodOffset = metaObjects->at(ii).methodOffset;
+ if (id >= globalMethodOffset) {
+ QObject *proxy = getProxy(ii);
+
+ const int localMethodOffset = proxy->metaObject()->methodOffset();
+ const int localMethodId = id - globalMethodOffset + localMethodOffset;
+
+ return proxy->qt_metacall(c, localMethodId, a);
+ }
+ }
}
}
diff --git a/src/qml/qml/qqmlproxymetaobject_p.h b/src/qml/qml/qqmlproxymetaobject_p.h
index 2b7a980361..dfa5d44059 100644
--- a/src/qml/qml/qqmlproxymetaobject_p.h
+++ b/src/qml/qml/qqmlproxymetaobject_p.h
@@ -80,6 +80,8 @@ protected:
int metaCall(QObject *o, QMetaObject::Call _c, int _id, void **_a) override;
private:
+ QObject *getProxy(int index);
+
QList<ProxyData> *metaObjects;
QObject **proxies;