diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2021-10-06 13:30:19 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2021-10-12 19:14:47 +0200 |
commit | 63865ebd75ede8122011a19e58dc56c19978c91a (patch) | |
tree | 90f250b1c692475ea4d17407d39c82b3c80a97e5 /src/qml/qml/qqmlpropertydata_p.h | |
parent | 852c8d1d8a953c626735f044838454a4d249c225 (diff) |
Avoid QAbstractDynamicMetaObject where possible
We don't want to copy metaobjects, but QAbstractDynamicMetaObject forces
us. Rather, use plain QDynamicMetaObjectData, and store a pointer to the
actual metaobject.
This requires us to drop the "isDirect()" optimization for property
access, as we realize that there can be dynamic meta objects which are
not QAbstractDynamicMetaObject. However, this optimization was
questionable anyway. What it did was cache the fact that an object might
have a dynamic metaobject in a flag. Checking this on the object itself
should not be much more expensive, though. On the other hand, an object
might receive a dynamic metaobject individually without us adjusting
flags for its type. In that case we would call the wrong method.
Furthermore, most property access can be done using the static metacall
function anyway.
Change-Id: I5897351253496309721bd38adf3e35a1f069b080
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlpropertydata_p.h')
-rw-r--r-- | src/qml/qml/qqmlpropertydata_p.h | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/src/qml/qml/qqmlpropertydata_p.h b/src/qml/qml/qqmlpropertydata_p.h index edf777ff18..24e2204b71 100644 --- a/src/qml/qml/qqmlpropertydata_p.h +++ b/src/qml/qml/qqmlpropertydata_p.h @@ -104,7 +104,7 @@ public: // Lastly, isDirect and isOverridden apply to both functions and non-functions private: unsigned isConst : 1; // Property: has CONST flag/Method: is const - unsigned isDirectOrVMEFunction : 1; // Exists on a C++ QMetaOBject OR Function was added by QML + unsigned isVMEFunction : 1; // Function was added by QML unsigned isWritableORhasArguments : 1; // Has WRITE function OR Function takes arguments unsigned isResettableORisSignal : 1; // Has RESET function OR Function is a signal unsigned isAliasORisVMESignal : 1; // Is a QML alias to another property OR Signal was added by QML @@ -159,11 +159,6 @@ public: isConstructorORisBindable = b; } - void setIsDirect(bool b) { - Q_ASSERT(type != FunctionType); - isDirectOrVMEFunction = b; - } - void setIsRequired(bool b) { Q_ASSERT(type != FunctionType); isRequiredORisCloned = b; @@ -171,7 +166,7 @@ public: void setIsVMEFunction(bool b) { Q_ASSERT(type == FunctionType); - isDirectOrVMEFunction = b; + isVMEFunction = b; } void setHasArguments(bool b) { Q_ASSERT(type == FunctionType); @@ -233,7 +228,6 @@ public: bool isAlias() const { return !isFunction() && m_flags.isAliasORisVMESignal; } bool isFinal() const { return !isFunction() && m_flags.isFinalORisV4Function; } bool isOverridden() const { return m_flags.isOverridden; } - bool isDirect() const { return !isFunction() && m_flags.isDirectOrVMEFunction; } bool isRequired() const { return !isFunction() && m_flags.isRequiredORisCloned; } bool hasStaticMetaCallFunction() const { return staticMetaCallFunction() != nullptr; } bool isFunction() const { return m_flags.type == Flags::FunctionType; } @@ -244,7 +238,7 @@ public: bool isQJSValue() const { return m_flags.type == Flags::QJSValueType; } bool isVarProperty() const { return m_flags.type == Flags::VarPropertyType; } bool isQVariant() const { return m_flags.type == Flags::QVariantType; } - bool isVMEFunction() const { return isFunction() && m_flags.isDirectOrVMEFunction; } + bool isVMEFunction() const { return isFunction() && m_flags.isVMEFunction; } bool hasArguments() const { return isFunction() && m_flags.isWritableORhasArguments; } bool isSignal() const { return isFunction() && m_flags.isResettableORisSignal; } bool isVMESignal() const { return isFunction() && m_flags.isAliasORisVMESignal; } @@ -353,14 +347,23 @@ public: readPropertyWithArgs(target, args); } - inline void readPropertyWithArgs(QObject *target, void *args[]) const + // This is the same as QMetaObject::metacall(), but inlined here to avoid a function call. + // And we ignore the return value. + template<QMetaObject::Call call> + void doMetacall(QObject *object, int idx, void **argv) const + { + if (QDynamicMetaObjectData *dynamicMetaObject = QObjectPrivate::get(object)->metaObject) + dynamicMetaObject->metaCall(object, call, idx, argv); + else + object->qt_metacall(call, idx, argv); + } + + void readPropertyWithArgs(QObject *target, void *args[]) const { if (hasStaticMetaCallFunction()) staticMetaCallFunction()(target, QMetaObject::ReadProperty, relativePropertyIndex(), args); - else if (isDirect()) - target->qt_metacall(QMetaObject::ReadProperty, coreIndex(), args); else - QMetaObject::metacall(target, QMetaObject::ReadProperty, coreIndex(), args); + doMetacall<QMetaObject::ReadProperty>(target, coreIndex(), args); } bool writeProperty(QObject *target, void *value, WriteFlags flags) const @@ -369,10 +372,8 @@ public: void *argv[] = { value, nullptr, &status, &flags }; if (flags.testFlag(BypassInterceptor) && hasStaticMetaCallFunction()) staticMetaCallFunction()(target, QMetaObject::WriteProperty, relativePropertyIndex(), argv); - else if (flags.testFlag(BypassInterceptor) && isDirect()) - target->qt_metacall(QMetaObject::WriteProperty, coreIndex(), argv); else - QMetaObject::metacall(target, QMetaObject::WriteProperty, coreIndex(), argv); + doMetacall<QMetaObject::WriteProperty>(target, coreIndex(), argv); return true; } @@ -437,7 +438,7 @@ bool QQmlPropertyData::operator==(const QQmlPropertyData &other) const QQmlPropertyData::Flags::Flags() : otherBits(0) , isConst(false) - , isDirectOrVMEFunction(false) + , isVMEFunction(false) , isWritableORhasArguments(false) , isResettableORisSignal(false) , isAliasORisVMESignal(false) @@ -454,7 +455,7 @@ QQmlPropertyData::Flags::Flags() bool QQmlPropertyData::Flags::operator==(const QQmlPropertyData::Flags &other) const { return isConst == other.isConst && - isDirectOrVMEFunction == other.isDirectOrVMEFunction && + isVMEFunction == other.isVMEFunction && isWritableORhasArguments == other.isWritableORhasArguments && isResettableORisSignal == other.isResettableORisSignal && isAliasORisVMESignal == other.isAliasORisVMESignal && |