summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/qml/qmlengine.cpp2
-rw-r--r--src/declarative/qml/qmlengine_p.h2
-rw-r--r--src/declarative/qml/qmlmetaproperty.cpp156
-rw-r--r--src/declarative/qml/qmlmetaproperty.h2
-rw-r--r--src/declarative/qml/qmlmetaproperty_p.h16
-rw-r--r--tests/benchmarks/declarative/qmlcomponent/myqmlobject.txt2
-rw-r--r--tests/benchmarks/declarative/qmlcomponent/myqmlobject_binding.txt2
-rw-r--r--tests/benchmarks/declarative/qmlcomponent/object.txt2
-rw-r--r--tests/benchmarks/declarative/qmlcomponent/synthesized_properties.2.txt2
-rw-r--r--tests/benchmarks/declarative/qmlcomponent/synthesized_properties.txt2
-rw-r--r--tests/benchmarks/declarative/qmlcomponent/testtypes.cpp2
-rw-r--r--tests/benchmarks/declarative/qmlmetaproperty/object.txt3
-rw-r--r--tests/benchmarks/declarative/qmlmetaproperty/qmlmetaproperty.pro7
-rw-r--r--tests/benchmarks/declarative/qmlmetaproperty/synthesized_object.txt6
-rw-r--r--tests/benchmarks/declarative/qmlmetaproperty/tst_qmlmetaproperty.cpp79
15 files changed, 200 insertions, 85 deletions
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index 321feb9..c331f56 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -196,7 +196,7 @@ QmlEnginePrivate::queryObject(const QString &propName,
{
QScriptClass::QueryFlags rv = 0;
- QmlMetaProperty prop(obj, propName);
+ QmlMetaProperty prop(obj, propName, rootContext);
if (prop.type() == QmlMetaProperty::Invalid) {
QPair<const QMetaObject *, QString> key =
qMakePair(obj->metaObject(), propName);
diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h
index 18cdd83..dffae6c 100644
--- a/src/declarative/qml/qmlengine_p.h
+++ b/src/declarative/qml/qmlengine_p.h
@@ -71,6 +71,7 @@
#include <QtDeclarative/qmlengine.h>
#include <QtDeclarative/qmlexpression.h>
#include <QtScript/qscriptengine.h>
+#include <private/qmlmetaproperty_p.h>
QT_BEGIN_NAMESPACE
@@ -177,6 +178,7 @@ public:
}
QmlValueTypeFactory valueTypes;
+ QHash<const QMetaObject *, QmlMetaObjectCache> propertyCache;
struct Imports {
Imports();
diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp
index 3d040e5..e6ffd50 100644
--- a/src/declarative/qml/qmlmetaproperty.cpp
+++ b/src/declarative/qml/qmlmetaproperty.cpp
@@ -56,31 +56,27 @@ Q_DECLARE_METATYPE(QList<QObject *>);
QT_BEGIN_NAMESPACE
-class QMetaPropertyEx : public QMetaProperty
+QmlMetaObjectCache::Data
+QmlMetaObjectCache::property(const QString &name, const QMetaObject *metaObject)
{
-public:
- QMetaPropertyEx()
- : propertyType(-1) {}
-
- QMetaPropertyEx(const QMetaProperty &p)
- : QMetaProperty(p), propertyType(p.userType()) {}
-
- QMetaPropertyEx(const QMetaPropertyEx &o)
- : QMetaProperty(o),
- propertyType(o.propertyType) {}
-
- QMetaPropertyEx &operator=(const QMetaPropertyEx &o)
- {
- static_cast<QMetaProperty *>(this)->operator=(o);
- propertyType = o.propertyType;
- return *this;
- }
+ QHash<QString, Data>::ConstIterator iter = properties.find(name);
+ if (iter != properties.end()) {
+ return *iter;
+ } else {
+ Data cacheData = { -1, -1 };
- private:
- friend class QmlMetaProperty;
- int propertyType;
-};
+ int idx = metaObject->indexOfProperty(name.toUtf8().constData());
+ if (idx == -1)
+ return cacheData;
+ QMetaProperty property = metaObject->property(idx);
+ cacheData.propType = property.userType();
+ cacheData.coreIndex = idx;
+ properties.insert(name, cacheData);
+
+ return cacheData;
+ }
+}
/*!
\class QmlMetaProperty
@@ -111,16 +107,13 @@ struct CachedPropertyData {
int coreIdx;
};
-// ### not thread safe
-static QHash<const QMetaObject *, CachedPropertyData> qmlCacheDefProp;
-
/*!
Creates a QmlMetaProperty for the default property of \a obj. If there is no
default property, an invalid QmlMetaProperty will be created.
*/
QmlMetaProperty::QmlMetaProperty(QObject *obj)
{
- initDefault(obj);
+ d->initDefault(obj);
}
/*!
@@ -132,32 +125,24 @@ QmlMetaProperty::QmlMetaProperty(QObject *obj, QmlContext *ctxt)
: d(new QmlMetaPropertyPrivate)
{
d->context = ctxt;
- initDefault(obj);
+ d->initDefault(obj);
}
-void QmlMetaProperty::initDefault(QObject *obj)
+/*!
+ Initialize from the default property of \a obj
+*/
+void QmlMetaPropertyPrivate::initDefault(QObject *obj)
{
if (!obj)
return;
- d->object = obj;
- QHash<const QMetaObject *, CachedPropertyData>::ConstIterator iter =
- qmlCacheDefProp.find(obj->metaObject());
- if (iter != qmlCacheDefProp.end()) {
- d->name = iter->name;
- d->propType = iter->propType;
- d->coreIdx = iter->coreIdx;
- } else {
- QMetaPropertyEx p(QmlMetaType::defaultProperty(obj));
- d->name = QLatin1String(p.name());
- d->propType = p.propertyType;
- d->coreIdx = p.propertyIndex();
- if (!QObjectPrivate::get(obj)->metaObject)
- qmlCacheDefProp.insert(obj->metaObject(), CachedPropertyData(d->name, d->propType, d->coreIdx));
- }
- if (!d->name.isEmpty()) {
- d->type = Property | Default;
- }
+ object = obj;
+ QMetaProperty p = QmlMetaType::defaultProperty(obj);
+ name = QLatin1String(p.name());
+ propType = p.userType();;
+ coreIdx = p.propertyIndex();
+ if (!name.isEmpty())
+ type = QmlMetaProperty::Property | QmlMetaProperty::Default;
}
/*!
@@ -171,22 +156,20 @@ QmlMetaProperty::QmlMetaProperty(QObject *obj, int idx, QmlContext *ctxt)
d->context = ctxt;
d->object = obj;
d->type = Property;
- QMetaPropertyEx p(obj->metaObject()->property(idx));
- d->propType = p.propertyType;
+ QMetaProperty p = obj->metaObject()->property(idx);
+ d->propType = p.userType();
d->coreIdx = idx;
if (p.name() != 0)
d->name = QLatin1String(p.name());
}
-// ### Not thread safe!!!!
-static QHash<const QMetaObject *, QHash<QString, CachedPropertyData> > qmlCacheProps;
/*!
Creates a QmlMetaProperty for the property \a name of \a obj.
*/
QmlMetaProperty::QmlMetaProperty(QObject *obj, const QString &name)
: d(new QmlMetaPropertyPrivate)
{
- initProperty(obj, name);
+ d->initProperty(obj, name);
}
/*!
@@ -197,51 +180,62 @@ QmlMetaProperty::QmlMetaProperty(QObject *obj, const QString &name, QmlContext *
: d(new QmlMetaPropertyPrivate)
{
d->context = ctxt;
- initProperty(obj, name);
+ d->initProperty(obj, name);
}
-void QmlMetaProperty::initProperty(QObject *obj, const QString &name)
+void QmlMetaPropertyPrivate::initProperty(QObject *obj, const QString &name)
{
- d->name = name;
- d->object = obj;
+ QmlEnginePrivate *enginePrivate = 0;
+ if (context && context->engine())
+ enginePrivate = QmlEnginePrivate::get(context->engine());
+
+ this->name = name;
+ object = obj;
+
if (name.isEmpty() || !obj)
return;
if (name.at(0).isUpper()) {
// Attached property
- d->attachedFunc = QmlMetaType::attachedPropertiesFuncId(name.toLatin1());
- if (d->attachedFunc != -1)
- d->type = Property | Attached;
+ attachedFunc = QmlMetaType::attachedPropertiesFuncId(name.toLatin1());
+ if (attachedFunc != -1)
+ type = QmlMetaProperty::Property | QmlMetaProperty::Attached;
return;
- } else if (name.count() >= 3 && name.startsWith(QLatin1String("on")) && name.at(2).isUpper()) {
+
+ } else if (name.count() >= 3 &&
+ name.at(0) == QChar(QLatin1Char('o')) &&
+ name.at(1) == QChar(QLatin1Char('n')) &&
+ name.at(2).isUpper()) {
// Signal
QString signalName = name.mid(2);
signalName[0] = signalName.at(0).toLower();
- d->findSignalInt(obj, signalName);
- if (d->signal.signature() != 0) {
- d->type = SignalProperty;
+ findSignalInt(obj, signalName);
+ if (signal.signature() != 0) {
+ type = QmlMetaProperty::SignalProperty;
return;
}
}
// Property
- QHash<QString, CachedPropertyData> &props = qmlCacheProps[obj->metaObject()];
- QHash<QString, CachedPropertyData>::ConstIterator iter = props.find(name);
- if (iter != props.end()) {
- d->name = iter->name;
- d->propType = iter->propType;
- d->coreIdx = iter->coreIdx;
+ if (!QObjectPrivate::get(obj)->metaObject && enginePrivate) {
+ // Can cache
+ QmlMetaObjectCache &cache =
+ enginePrivate->propertyCache[obj->metaObject()];
+ QmlMetaObjectCache::Data data = cache.property(name, obj->metaObject());
+ if (data.coreIndex != -1) {
+ type = QmlMetaProperty::Property;
+ propType = data.propType;
+ coreIdx = data.coreIndex;
+ }
} else {
- QMetaPropertyEx p = QmlMetaType::property(obj, name.toLatin1().constData());
- d->name = QLatin1String(p.name());
- d->propType = p.propertyType;
- d->coreIdx = p.propertyIndex();
- if (!QObjectPrivate::get(obj)->metaObject)
- props.insert(name, CachedPropertyData(d->name, d->propType, d->coreIdx));
+ // Can't cache
+ QMetaProperty p = QmlMetaType::property(obj, name.toUtf8().constData());
+ propType = p.userType();
+ coreIdx = p.propertyIndex();
+ if (p.name())
+ type = QmlMetaProperty::Property;
}
- if (!d->name.isEmpty())
- d->type = Property;
}
/*!
@@ -1037,18 +1031,18 @@ void QmlMetaProperty::restore(quint32 id, QObject *obj, QmlContext *ctxt)
QmlValueType *valueType = qmlValueTypes()->valueTypes[p.type()];
- QMetaPropertyEx p2(valueType->metaObject()->property(valueTypeIdx));
+ QMetaProperty p2(valueType->metaObject()->property(valueTypeIdx));
d->name = QLatin1String(p2.name());
- d->propType = p2.propertyType;
+ d->propType = p2.userType();
d->coreIdx = coreIdx;
d->valueTypeIdx = valueTypeIdx;
d->valueTypeId = p.type();
} else if (d->type & Property) {
- QMetaPropertyEx p(obj->metaObject()->property(id));
+ QMetaProperty p(obj->metaObject()->property(id));
d->name = QLatin1String(p.name());
- d->propType = p.propertyType;
+ d->propType = p.userType();
d->coreIdx = id;
} else if (d->type & SignalProperty) {
d->signal = obj->metaObject()->method(id);
@@ -1086,7 +1080,7 @@ QmlMetaProperty QmlMetaProperty::createProperty(QObject *obj,
QmlMetaProperty prop(object, pathName);
if (jj == path.count() - 2 &&
- prop.propertyType() < QVariant::UserType &&
+ prop.propertyType() < (int)QVariant::UserType &&
qmlValueTypes()->valueTypes[prop.propertyType()]) {
// We're now at a value type property
QObject *typeObject =
diff --git a/src/declarative/qml/qmlmetaproperty.h b/src/declarative/qml/qmlmetaproperty.h
index 2470d5d..434ff55 100644
--- a/src/declarative/qml/qmlmetaproperty.h
+++ b/src/declarative/qml/qmlmetaproperty.h
@@ -129,8 +129,6 @@ public:
int coreIndex() const;
private:
- void initDefault(QObject *obj);
- void initProperty(QObject *obj, const QString &name);
friend class QmlEnginePrivate;
QmlMetaPropertyPrivate *d;
};
diff --git a/src/declarative/qml/qmlmetaproperty_p.h b/src/declarative/qml/qmlmetaproperty_p.h
index 64cdbae..0410dd6 100644
--- a/src/declarative/qml/qmlmetaproperty_p.h
+++ b/src/declarative/qml/qmlmetaproperty_p.h
@@ -58,6 +58,19 @@
QT_BEGIN_NAMESPACE
+class QmlMetaObjectCache
+{
+public:
+ struct Data {
+ int propType;
+ int coreIndex;
+ };
+
+ QHash<QString, Data> properties;
+
+ Data property(const QString &, const QMetaObject *);
+};
+
class QmlContext;
class QmlMetaPropertyPrivate
{
@@ -86,6 +99,9 @@ public:
mutable QmlMetaProperty::PropertyCategory category;
+ void initProperty(QObject *obj, const QString &name);
+ void initDefault(QObject *obj);
+
QObject *attachedObject() const;
void findSignalInt(QObject *, const QString &);
diff --git a/tests/benchmarks/declarative/qmlcomponent/myqmlobject.txt b/tests/benchmarks/declarative/qmlcomponent/myqmlobject.txt
index 05ed87a..9c3f7f8 100644
--- a/tests/benchmarks/declarative/qmlcomponent/myqmlobject.txt
+++ b/tests/benchmarks/declarative/qmlcomponent/myqmlobject.txt
@@ -1 +1,3 @@
+import Qt.test 4.6
+
MyQmlObject {}
diff --git a/tests/benchmarks/declarative/qmlcomponent/myqmlobject_binding.txt b/tests/benchmarks/declarative/qmlcomponent/myqmlobject_binding.txt
index 4dfa7c3..e6cc4cf 100644
--- a/tests/benchmarks/declarative/qmlcomponent/myqmlobject_binding.txt
+++ b/tests/benchmarks/declarative/qmlcomponent/myqmlobject_binding.txt
@@ -1,3 +1,5 @@
+import Qt.test 4.6
+
MyQmlObject {
result: value
}
diff --git a/tests/benchmarks/declarative/qmlcomponent/object.txt b/tests/benchmarks/declarative/qmlcomponent/object.txt
index 7dc75192..85e74b9 100644
--- a/tests/benchmarks/declarative/qmlcomponent/object.txt
+++ b/tests/benchmarks/declarative/qmlcomponent/object.txt
@@ -1 +1,3 @@
+import Qt 4.6
+
Object {}
diff --git a/tests/benchmarks/declarative/qmlcomponent/synthesized_properties.2.txt b/tests/benchmarks/declarative/qmlcomponent/synthesized_properties.2.txt
index d59104d..90db37c 100644
--- a/tests/benchmarks/declarative/qmlcomponent/synthesized_properties.2.txt
+++ b/tests/benchmarks/declarative/qmlcomponent/synthesized_properties.2.txt
@@ -1,3 +1,5 @@
+import Qt 4.6
+
Object {
property int a
property bool b
diff --git a/tests/benchmarks/declarative/qmlcomponent/synthesized_properties.txt b/tests/benchmarks/declarative/qmlcomponent/synthesized_properties.txt
index d9eb708..bb5469a 100644
--- a/tests/benchmarks/declarative/qmlcomponent/synthesized_properties.txt
+++ b/tests/benchmarks/declarative/qmlcomponent/synthesized_properties.txt
@@ -1,3 +1,5 @@
+import Qt 4.6
+
Object {
property int a
}
diff --git a/tests/benchmarks/declarative/qmlcomponent/testtypes.cpp b/tests/benchmarks/declarative/qmlcomponent/testtypes.cpp
index 60e69e2..5021bf3 100644
--- a/tests/benchmarks/declarative/qmlcomponent/testtypes.cpp
+++ b/tests/benchmarks/declarative/qmlcomponent/testtypes.cpp
@@ -1,3 +1,3 @@
#include "testtypes.h"
-QML_DEFINE_TYPE(MyQmlObject, MyQmlObject);
+QML_DEFINE_TYPE(Qt/test, 4, 6, 6, MyQmlObject, MyQmlObject);
diff --git a/tests/benchmarks/declarative/qmlmetaproperty/object.txt b/tests/benchmarks/declarative/qmlmetaproperty/object.txt
new file mode 100644
index 0000000..11b95e1
--- /dev/null
+++ b/tests/benchmarks/declarative/qmlmetaproperty/object.txt
@@ -0,0 +1,3 @@
+import Qt 4.6
+
+Item {}
diff --git a/tests/benchmarks/declarative/qmlmetaproperty/qmlmetaproperty.pro b/tests/benchmarks/declarative/qmlmetaproperty/qmlmetaproperty.pro
new file mode 100644
index 0000000..b4e83d7
--- /dev/null
+++ b/tests/benchmarks/declarative/qmlmetaproperty/qmlmetaproperty.pro
@@ -0,0 +1,7 @@
+load(qttest_p4)
+TEMPLATE = app
+TARGET = tst_qmlmetaproperty
+QT += declarative
+
+SOURCES += tst_qmlmetaproperty.cpp
+
diff --git a/tests/benchmarks/declarative/qmlmetaproperty/synthesized_object.txt b/tests/benchmarks/declarative/qmlmetaproperty/synthesized_object.txt
new file mode 100644
index 0000000..a923a0a
--- /dev/null
+++ b/tests/benchmarks/declarative/qmlmetaproperty/synthesized_object.txt
@@ -0,0 +1,6 @@
+import Qt 4.6
+
+Item {
+ property int blah
+}
+
diff --git a/tests/benchmarks/declarative/qmlmetaproperty/tst_qmlmetaproperty.cpp b/tests/benchmarks/declarative/qmlmetaproperty/tst_qmlmetaproperty.cpp
new file mode 100644
index 0000000..c22af03
--- /dev/null
+++ b/tests/benchmarks/declarative/qmlmetaproperty/tst_qmlmetaproperty.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+****************************************************************************/
+
+#include <qtest.h>
+#include <QmlEngine>
+#include <QmlComponent>
+#include <QmlMetaProperty>
+#include <QFile>
+#include <QDebug>
+
+//TESTED_FILES=
+
+
+class tst_qmlmetaproperty : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_qmlmetaproperty();
+ virtual ~tst_qmlmetaproperty();
+
+public slots:
+ void init();
+ void cleanup();
+
+private slots:
+ void lookup_data();
+ void lookup();
+
+private:
+ QmlEngine engine;
+};
+
+tst_qmlmetaproperty::tst_qmlmetaproperty()
+{
+}
+
+tst_qmlmetaproperty::~tst_qmlmetaproperty()
+{
+}
+
+void tst_qmlmetaproperty::init()
+{
+}
+
+void tst_qmlmetaproperty::cleanup()
+{
+}
+
+void tst_qmlmetaproperty::lookup_data()
+{
+ QTest::addColumn<QString>("file");
+
+ QTest::newRow("Simple Object") << "object.txt";
+ QTest::newRow("Synthesized Object") << "synthesized_object.txt";
+}
+
+void tst_qmlmetaproperty::lookup()
+{
+ QFETCH(QString, file);
+
+ QmlComponent c(&engine, file);
+ QVERIFY(c.isReady());
+
+ QObject *obj = c.create();
+
+ QBENCHMARK {
+ QmlMetaProperty p(obj, "x");
+ }
+
+ delete obj;
+}
+
+QTEST_MAIN(tst_qmlmetaproperty)
+#include "tst_qmlmetaproperty.moc"