diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2016-06-14 15:44:09 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2016-06-16 18:00:35 +0000 |
commit | 0058ac5f28c64979f359972e03ee91ae146b0cd3 (patch) | |
tree | b9063a18a2182668424ce22e5a3cd95f4e1e2b15 /src/qml/qml | |
parent | c2c13cacd450d866e60c58c87ff1ab16ae736804 (diff) |
Clean up property cache array handling
The QQmlPropertyCacheVector in the CompilationUnit encapsulates the
property caches for the objects declared in the QML tree as well as the
bits indicating whether a VME meta-object is needed. The ref-counting
for the caches in that vector was done "manually" and thus error prone.
This patch replaces the vector with a wrapper container that has
explicit move semantics and takes care of the addref() and release()
calls upon insertion, replacement and destruction.
Change-Id: If805fe016f1a1c70e56f8a90909ab87b653ea026
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 11 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycache_p.h | 43 |
3 files changed, 49 insertions, 7 deletions
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 9e2040469b..6a54555f3f 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -73,7 +73,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QV4::Compil : phase(Startup) , compilationUnit(compilationUnit) , resolvedTypes(compilationUnit->resolvedTypes) - , propertyCaches(compilationUnit->propertyCaches) + , propertyCaches(&compilationUnit->propertyCaches) , activeVMEDataForRootContext(activeVMEDataForRootContext) { init(parentContext); @@ -97,7 +97,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QV4::Compil : phase(Startup) , compilationUnit(compilationUnit) , resolvedTypes(compilationUnit->resolvedTypes) - , propertyCaches(compilationUnit->propertyCaches) + , propertyCaches(&compilationUnit->propertyCaches) , activeVMEDataForRootContext(0) { init(parentContext); @@ -1147,7 +1147,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo return instance; } - QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches.at(index).data(); + QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches->at(index); Q_ASSERT(!cache.isNull()); if (installPropertyCache) { if (ddata->propertyCache) @@ -1278,11 +1278,10 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * QV4::Scope valueScope(v4); QV4::ScopedValue scopeObjectProtector(valueScope); - QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches.at(_compiledObjectIndex).data(); + QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches->at(_compiledObjectIndex); QQmlVMEMetaObject *vmeMetaObject = 0; - const bool needVMEMetaObject = propertyCaches.at(_compiledObjectIndex).flag(); - if (needVMEMetaObject) { + if (propertyCaches->needsVMEMetaObject(_compiledObjectIndex)) { Q_ASSERT(!cache.isNull()); // install on _object vmeMetaObject = new QQmlVMEMetaObject(_qobject, cache, compilationUnit, _compiledObjectIndex); diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index b4e706941b..2320edf809 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -140,7 +140,7 @@ private: QQmlGuardedContextData parentContext; QQmlContextData *context; const QHash<int, QV4::CompiledData::CompilationUnit::ResolvedTypeReference*> &resolvedTypes; - const QQmlPropertyCacheVector &propertyCaches; + const QQmlPropertyCacheVector *propertyCaches; QExplicitlySharedDataPointer<QQmlObjectCreatorSharedState> sharedState; bool topLevelCreator; void *activeVMEDataForRootContext; diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index 3e84fb3070..34b6b96ebe 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -655,6 +655,49 @@ const QMetaObject *QQmlMetaObject::metaObject() const else return _m.asT2(); } +class QQmlPropertyCacheVector +{ +public: + QQmlPropertyCacheVector() {} + QQmlPropertyCacheVector(QQmlPropertyCacheVector &&other) + : data(std::move(other.data)) {} + QQmlPropertyCacheVector &operator=(QQmlPropertyCacheVector &&other) { + QVector<QFlagPointer<QQmlPropertyCache>> moved(std::move(other.data)); + data.swap(moved); + return *this; + } + + ~QQmlPropertyCacheVector() { clear(); } + void resize(int size) { return data.resize(size); } + int count() const { return data.count(); } + void clear() + { + for (int i = 0; i < data.count(); ++i) { + if (QQmlPropertyCache *cache = data.at(i).data()) + cache->release(); + } + data.clear(); + } + + void append(QQmlPropertyCache *cache) { cache->addref(); data.append(cache); } + QQmlPropertyCache *at(int index) const { return data.at(index).data(); } + void set(int index, QQmlPropertyCache *replacement) { + if (QQmlPropertyCache *oldCache = data.at(index).data()) { + if (replacement == oldCache) + return; + oldCache->release(); + } + data[index] = replacement; + replacement->addref(); + } + + void setNeedsVMEMetaObject(int index) { data[index].setFlag(); } + bool needsVMEMetaObject(int index) const { return data.at(index).flag(); } +private: + Q_DISABLE_COPY(QQmlPropertyCacheVector) + QVector<QFlagPointer<QQmlPropertyCache>> data; +}; + QT_END_NAMESPACE #endif // QQMLPROPERTYCACHE_P_H |