aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
authorAndrei Golubev <andrei.golubev@qt.io>2022-05-09 17:35:35 +0200
committerAndrei Golubev <andrei.golubev@qt.io>2022-05-12 17:36:12 +0200
commit5cd59bff0c2f077ab47c40710a5267c06d3d2aa9 (patch)
treeb3a1f34ce103f1834f20f5921c33f02ad646cff4 /src/qml/qml
parentc8f9cb050df690696422df2f79f1124340037547 (diff)
Support querying indirect extensions for a given object
Introduce a private version of qmlExtendedObject() that returns an index-based extension (where 0 represents an extension on the leaf type and N represents a (N - 1)th base type's extension) Teach QQmlProxyMetaObject to distinguish different extension proxies. Its custom metaCall can now query up to 128 extensions (should be enough for the user needs) Change-Id: I5520a1e84501f1f9fe6a8e77d8269009a12c255c Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/qqml.cpp9
-rw-r--r--src/qml/qml/qqmlprivate.h2
-rw-r--r--src/qml/qml/qqmlproxymetaobject.cpp10
-rw-r--r--src/qml/qml/qqmlproxymetaobject_p.h18
4 files changed, 32 insertions, 7 deletions
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp
index 728250dcf2..3c9f930eb9 100644
--- a/src/qml/qml/qqml.cpp
+++ b/src/qml/qml/qqml.cpp
@@ -151,6 +151,11 @@ QObject *qmlAttachedPropertiesObject(QObject *object, QQmlAttachedPropertiesFunc
QObject *qmlExtendedObject(QObject *object)
{
+ return QQmlPrivate::qmlExtendedObject(object, 0);
+}
+
+QObject *QQmlPrivate::qmlExtendedObject(QObject *object, int index)
+{
if (!object)
return nullptr;
@@ -161,8 +166,8 @@ QObject *qmlExtendedObject(QObject *object)
const int id = d->metaObject->metaCall(
object, QMetaObject::CustomCall,
- QQmlProxyMetaObject::ExtensionObjectId, &result);
- if (id != QQmlProxyMetaObject::ExtensionObjectId)
+ QQmlProxyMetaObject::extensionObjectId(index), &result);
+ if (id != QQmlProxyMetaObject::extensionObjectId(index))
return nullptr;
return static_cast<QObject *>(result);
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index 817f25c112..9754f9dcf3 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -1087,6 +1087,8 @@ namespace QQmlPrivate
};
}
+ Q_QML_EXPORT QObject *qmlExtendedObject(QObject *, int);
+
} // namespace QQmlPrivate
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlproxymetaobject.cpp b/src/qml/qml/qqmlproxymetaobject.cpp
index e05c63794c..4844ca3720 100644
--- a/src/qml/qml/qqmlproxymetaobject.cpp
+++ b/src/qml/qml/qqmlproxymetaobject.cpp
@@ -144,11 +144,15 @@ int QQmlProxyMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void
break;
}
- case QMetaObject::CustomCall:
- if (id != ExtensionObjectId)
+ case QMetaObject::CustomCall: {
+ if ((id & ~MaxExtensionCount) != ExtensionObjectId)
break;
- a[0] = getProxy(0);
+ int index = id & MaxExtensionCount;
+ if (qsizetype(index) >= metaObjects->size())
+ break;
+ a[0] = getProxy(index);
return id;
+ }
default:
break;
}
diff --git a/src/qml/qml/qqmlproxymetaobject_p.h b/src/qml/qml/qqmlproxymetaobject_p.h
index a58818f22a..965d86c70f 100644
--- a/src/qml/qml/qqmlproxymetaobject_p.h
+++ b/src/qml/qml/qqmlproxymetaobject_p.h
@@ -65,8 +65,6 @@ QT_BEGIN_NAMESPACE
class QQmlProxyMetaObject : public QDynamicMetaObjectData
{
public:
- enum { ExtensionObjectId = std::numeric_limits<int>::min() };
-
struct ProxyData {
typedef QObject *(*CreateFunc)(QObject *);
QMetaObject *metaObject;
@@ -78,6 +76,13 @@ public:
QQmlProxyMetaObject(QObject *, QList<ProxyData> *);
~QQmlProxyMetaObject();
+ static constexpr int extensionObjectId(int id) noexcept
+ {
+ Q_ASSERT(id >= 0);
+ Q_ASSERT(id <= MaxExtensionCount); // MaxExtensionCount is a valid index
+ return ExtensionObjectId | id;
+ }
+
protected:
int metaCall(QObject *o, QMetaObject::Call _c, int _id, void **_a) override;
QMetaObject *toDynamicMetaObject(QObject *) override;
@@ -91,6 +96,15 @@ private:
QDynamicMetaObjectData *parent;
QMetaObject *metaObject;
QObject *object;
+
+ // ExtensionObjectId acts as a flag for whether we should interpret a
+ // QMetaObject::CustomCall as a call to fetch the extension object (see
+ // QQmlProxyMetaObject::metaCall()). MaxExtensionCount is a limit on how
+ // many extensions we can query via such mechanism
+ enum : int {
+ MaxExtensionCount = 127, // magic number so that low bits are all '1'
+ ExtensionObjectId = ~MaxExtensionCount,
+ };
};
QT_END_NAMESPACE