diff options
Diffstat (limited to 'src/declarative/qml/qdeclarativepropertycache.cpp')
-rw-r--r-- | src/declarative/qml/qdeclarativepropertycache.cpp | 138 |
1 files changed, 60 insertions, 78 deletions
diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp index 9e1ceb8695..dd9a2247bd 100644 --- a/src/declarative/qml/qdeclarativepropertycache.cpp +++ b/src/declarative/qml/qdeclarativepropertycache.cpp @@ -93,6 +93,7 @@ void QDeclarativePropertyCache::Data::load(const QMetaProperty &p, QDeclarativeE void QDeclarativePropertyCache::Data::load(const QMetaMethod &m) { coreIndex = m.methodIndex(); + relatedIndex = -1; flags |= Data::IsFunction; if (m.methodType() == QMetaMethod::Signal) flags |= Data::IsSignal; @@ -140,15 +141,25 @@ void QDeclarativePropertyCache::clear() if (indexCache.at(ii)) indexCache.at(ii)->release(); } + for (int ii = 0; ii < methodIndexCache.count(); ++ii) { + RData *data = methodIndexCache.at(ii); + if (data) data->release(); + } + for (StringCache::ConstIterator iter = stringCache.begin(); - iter != stringCache.end(); ++iter) - (*iter)->release(); + iter != stringCache.end(); ++iter) { + RData *data = (*iter); + data->release(); + } for (IdentifierCache::ConstIterator iter = identifierCache.begin(); - iter != identifierCache.end(); ++iter) - (*iter)->release(); + iter != identifierCache.end(); ++iter) { + RData *data = (*iter); + data->release(); + } indexCache.clear(); + methodIndexCache.clear(); stringCache.clear(); identifierCache.clear(); } @@ -202,12 +213,16 @@ QDeclarativePropertyCache *QDeclarativePropertyCache::copy() const { QDeclarativePropertyCache *cache = new QDeclarativePropertyCache(engine); cache->indexCache = indexCache; + cache->methodIndexCache = methodIndexCache; cache->stringCache = stringCache; cache->identifierCache = identifierCache; for (int ii = 0; ii < indexCache.count(); ++ii) { if (indexCache.at(ii)) indexCache.at(ii)->addref(); } + for (int ii = 0; ii < methodIndexCache.count(); ++ii) { + if (methodIndexCache.at(ii)) methodIndexCache.at(ii)->addref(); + } for (StringCache::ConstIterator iter = stringCache.begin(); iter != stringCache.end(); ++iter) (*iter)->addref(); for (IdentifierCache::ConstIterator iter = identifierCache.begin(); iter != identifierCache.end(); ++iter) @@ -221,43 +236,14 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb { QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); - int propCount = metaObject->propertyCount(); - int propOffset = metaObject->propertyOffset(); - - indexCache.resize(propCount); - for (int ii = propOffset; ii < propCount; ++ii) { - QMetaProperty p = metaObject->property(ii); - if (!p.isScriptable()) - continue; - - QString propName = QString::fromUtf8(p.name()); - - RData *data = new RData; - data->identifier = enginePriv->objectClass->createPersistentIdentifier(propName); - - data->load(p, engine); - data->flags |= propertyFlags; - - indexCache[ii] = data; - - if (stringCache.contains(propName)) { - stringCache[propName]->release(); - identifierCache[data->identifier.identifier]->release(); - } - - stringCache.insert(propName, data); - identifierCache.insert(data->identifier.identifier, data); - data->addref(); - data->addref(); - } - int methodCount = metaObject->methodCount(); - int methodOffset = qMax(2, metaObject->methodOffset()); // 2 to block the destroyed signal + // 3 to block the destroyed signal and the deleteLater() slot + int methodOffset = qMax(3, metaObject->methodOffset()); methodIndexCache.resize(methodCount); for (int ii = methodOffset; ii < methodCount; ++ii) { QMetaMethod m = metaObject->method(ii); - if (m.access() == QMetaMethod::Private) + if (m.access() == QMetaMethod::Private) continue; QString methodName = QString::fromUtf8(m.signature()); @@ -267,11 +253,7 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb RData *data = new RData; data->identifier = enginePriv->objectClass->createPersistentIdentifier(methodName); - - if (stringCache.contains(methodName)) { - stringCache[methodName]->release(); - identifierCache[data->identifier.identifier]->release(); - } + methodIndexCache[ii] = data; data->load(m); if (m.methodType() == QMetaMethod::Slot || m.methodType() == QMetaMethod::Method) @@ -279,73 +261,73 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb else if (m.methodType() == QMetaMethod::Signal) data->flags |= signalFlags; - methodIndexCache[ii] = data; + if (stringCache.contains(methodName)) { + RData *old = stringCache[methodName]; + // We only overload methods in the same class, exactly like C++ + if (old->flags & Data::IsFunction && old->coreIndex >= methodOffset) + data->relatedIndex = old->coreIndex; + stringCache[methodName]->release(); + identifierCache[data->identifier.identifier]->release(); + } stringCache.insert(methodName, data); identifierCache.insert(data->identifier.identifier, data); data->addref(); + data->addref(); } -} - -void QDeclarativePropertyCache::update(QDeclarativeEngine *engine, const QMetaObject *metaObject) -{ - Q_ASSERT(engine); - Q_ASSERT(metaObject); - QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); - - clear(); - // ### The properties/methods should probably be spliced on a per-metaobject basis int propCount = metaObject->propertyCount(); + int propOffset = metaObject->propertyOffset(); indexCache.resize(propCount); - for (int ii = propCount - 1; ii >= 0; --ii) { + for (int ii = propOffset; ii < propCount; ++ii) { QMetaProperty p = metaObject->property(ii); - if (!p.isScriptable()) { - indexCache[ii] = 0; + if (!p.isScriptable()) continue; - } + QString propName = QString::fromUtf8(p.name()); RData *data = new RData; data->identifier = enginePriv->objectClass->createPersistentIdentifier(propName); + indexCache[ii] = data; data->load(p, engine); + data->flags |= propertyFlags; - indexCache[ii] = data; - - if (stringCache.contains(propName)) - continue; + if (stringCache.contains(propName)) { + stringCache[propName]->release(); + identifierCache[data->identifier.identifier]->release(); + } stringCache.insert(propName, data); identifierCache.insert(data->identifier.identifier, data); data->addref(); data->addref(); } +} - int methodCount = metaObject->methodCount(); - for (int ii = methodCount - 1; ii >= 3; --ii) { // >=3 to block the destroyed signal and deleteLater() slot - QMetaMethod m = metaObject->method(ii); - if (m.access() == QMetaMethod::Private) - continue; - QString methodName = QString::fromUtf8(m.signature()); +void QDeclarativePropertyCache::updateRecur(QDeclarativeEngine *engine, const QMetaObject *metaObject) +{ + if (!metaObject) + return; - int parenIdx = methodName.indexOf(QLatin1Char('(')); - Q_ASSERT(parenIdx != -1); - methodName = methodName.left(parenIdx); + updateRecur(engine, metaObject->superClass()); - if (stringCache.contains(methodName)) - continue; + append(engine, metaObject); +} - RData *data = new RData; - data->identifier = enginePriv->objectClass->createPersistentIdentifier(methodName); +void QDeclarativePropertyCache::update(QDeclarativeEngine *engine, const QMetaObject *metaObject) +{ + Q_ASSERT(engine); + Q_ASSERT(metaObject); - data->load(m); + clear(); - stringCache.insert(methodName, data); - identifierCache.insert(data->identifier.identifier, data); - data->addref(); - } + // Optimization to prevent unnecessary reallocation of lists + indexCache.reserve(metaObject->propertyCount()); + methodIndexCache.reserve(metaObject->methodCount()); + + updateRecur(engine,metaObject); } QDeclarativePropertyCache::Data * |