diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2021-01-14 16:50:39 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-02-03 08:28:30 +0000 |
commit | 2951c124d3ff58abe1f84175e512ba26977f13d8 (patch) | |
tree | 681b5483e7a7be7c37924a31b6160fdf34e766cd | |
parent | 167f01e4be56440cb58e97510bc408f3476eb307 (diff) |
Mark dynamic state machines' metaobjects as fully dynamic
The memory is allocated using malloc() and will be free()'d eventually.
Client code cannot expect to keep string data from those metaobjects
around.
The QML engine will avoid the creation of property caches (which hold
string data from the metaobject) if the metaobject is fully dynamic.
Therefore, just create a QAbstractDynamicMetaObject that wraps the
original metaobject and pass that to QObjectPrivate in order to signal
the fully dynamic nature of the metaobject to QML.
Fixes: QTBUG-89521
Change-Id: I349dcb689be5674679237a551ed8595bd6b5b672
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 0e4c91654abff279b51238b46f880dd624ab9ec8)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/scxml/qscxmlcompiler.cpp | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/src/scxml/qscxmlcompiler.cpp b/src/scxml/qscxmlcompiler.cpp index 8583233..9bf3a92 100644 --- a/src/scxml/qscxmlcompiler.cpp +++ b/src/scxml/qscxmlcompiler.cpp @@ -485,9 +485,31 @@ private: class DynamicStateMachinePrivate : public QScxmlStateMachinePrivate { + struct DynamicMetaObject : public QAbstractDynamicMetaObject + { + QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *) override + { + return this; + } + + int metaCall(QObject *o, QMetaObject::Call c, int id, void **a) override + { + return o->qt_metacall(c, id, a); + } + }; + public: DynamicStateMachinePrivate() : - QScxmlStateMachinePrivate(&QScxmlStateMachine::staticMetaObject) {} + QScxmlStateMachinePrivate(&QScxmlStateMachine::staticMetaObject) + { + metaObject = new DynamicMetaObject; + } + + void setDynamicMetaObject(const QMetaObject *m) { + // Prevent the QML engine from creating a property cache for this thing. + static_cast<DynamicMetaObject *>(metaObject)->d = m->d; + m_metaObject = m; + } }; class DynamicStateMachine: public QScxmlStateMachine, public QScxmlInternal::GeneratedTableData @@ -544,7 +566,7 @@ private: b.setClassName("DynamicStateMachine"); b.setSuperClass(&QScxmlStateMachine::staticMetaObject); b.setStaticMetacallFunction(qt_static_metacall); - d->m_metaObject = b.toMetaObject(); + d->setDynamicMetaObject(b.toMetaObject()); } void initDynamicParts(const MetaDataInfo &info) @@ -553,7 +575,7 @@ private: // Release the temporary QMetaObject. Q_ASSERT(d->m_metaObject != &QScxmlStateMachine::staticMetaObject); free(const_cast<QMetaObject *>(d->m_metaObject)); - d->m_metaObject = &QScxmlStateMachine::staticMetaObject; + d->setDynamicMetaObject(&QScxmlStateMachine::staticMetaObject); // Build the real one. QMetaObjectBuilder b; @@ -579,7 +601,7 @@ private: } // And we're done - d->m_metaObject = b.toMetaObject(); + d->setDynamicMetaObject(b.toMetaObject()); } public: @@ -588,7 +610,7 @@ public: Q_D(DynamicStateMachine); if (d->m_metaObject != &QScxmlStateMachine::staticMetaObject) { free(const_cast<QMetaObject *>(d->m_metaObject)); - d->m_metaObject = &QScxmlStateMachine::staticMetaObject; + d->setDynamicMetaObject(&QScxmlStateMachine::staticMetaObject); } } |