aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2011-11-28 16:04:33 +0000
committerQt by Nokia <qt-info@nokia.com>2011-12-05 15:33:30 +0100
commit5ac2990688c7da6ce872bccc5c08129267887d68 (patch)
tree4099c1f9e415dc3efda5ea97385a5a76824375c6 /src
parent5c9179b19776808acecab4805b10932dc4f9511a (diff)
Introduce more generic fast property handling
Also reduce the number of direct calls to qt_metacall(). Change-Id: I04cd6e516a3e61058548309a19fe0b830f15c93f Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/declarative/qml/qdeclarativeaccessors.cpp127
-rw-r--r--src/declarative/qml/qdeclarativeaccessors_p.h164
-rw-r--r--src/declarative/qml/qdeclarativebinding.cpp10
-rw-r--r--src/declarative/qml/qdeclarativebinding_p.h1
-rw-r--r--src/declarative/qml/qdeclarativefastproperties.cpp109
-rw-r--r--src/declarative/qml/qdeclarativefastproperties_p.h78
-rw-r--r--src/declarative/qml/qdeclarativeproperty.cpp9
-rw-r--r--src/declarative/qml/qdeclarativeproperty_p.h30
-rw-r--r--src/declarative/qml/qdeclarativepropertycache.cpp232
-rw-r--r--src/declarative/qml/qdeclarativepropertycache_p.h73
-rw-r--r--src/declarative/qml/qdeclarativevaluetype.cpp504
-rw-r--r--src/declarative/qml/qdeclarativevaluetype_p.h37
-rw-r--r--src/declarative/qml/qdeclarativevme.cpp481
-rw-r--r--src/declarative/qml/qml.pri4
-rw-r--r--src/declarative/qml/v4/qv4bindings.cpp14
-rw-r--r--src/declarative/qml/v4/qv4compiler.cpp7
-rw-r--r--src/declarative/qml/v4/qv4instruction.cpp2
-rw-r--r--src/declarative/qml/v4/qv4instruction_p.h7
-rw-r--r--src/declarative/qml/v8/qv8bindings.cpp2
-rw-r--r--src/declarative/qml/v8/qv8qobjectwrapper.cpp395
-rw-r--r--src/declarative/qml/v8/qv8sequencewrapper_p_p.h45
-rw-r--r--src/declarative/qml/v8/qv8valuetypewrapper.cpp6
-rw-r--r--src/qtquick1/graphicsitems/qdeclarativeitem.cpp9
-rw-r--r--src/qtquick1/graphicsitems/qdeclarativeitem_p.h4
-rw-r--r--src/qtquick1/qtquick1.cpp4
-rw-r--r--src/quick/items/qquickitem.cpp34
-rw-r--r--src/quick/items/qquickitem.h1
-rw-r--r--src/quick/items/qquickitem_p.h4
-rw-r--r--src/quick/items/qquickitemsmodule.cpp1
29 files changed, 991 insertions, 1403 deletions
diff --git a/src/declarative/qml/qdeclarativeaccessors.cpp b/src/declarative/qml/qdeclarativeaccessors.cpp
new file mode 100644
index 0000000000..96521033b2
--- /dev/null
+++ b/src/declarative/qml/qdeclarativeaccessors.cpp
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativeaccessors_p.h"
+
+#include "qdeclarativedata_p.h"
+#include "qdeclarativenotifier_p.h"
+
+QT_BEGIN_NAMESPACE
+
+struct AccessorProperties {
+ AccessorProperties();
+
+ QReadWriteLock lock;
+ QHash<const QMetaObject *, QDeclarativeAccessorProperties::Properties> properties;
+};
+
+Q_GLOBAL_STATIC(AccessorProperties, accessorProperties)
+
+QML_PRIVATE_ACCESSOR(QObject, QString, objectName, objectName)
+
+static void QObject_objectNameNotifier(QObject *object, intptr_t, QDeclarativeNotifier **notifier)
+{
+ *notifier = QDeclarativeData::get(object, true)->objectNameNotifier();
+}
+
+static QDeclarativeAccessors QObject_objectName = { QObject_objectNameRead,
+ QObject_objectNameNotifier };
+
+QML_DECLARE_PROPERTIES(QObject) {
+ { QML_PROPERTY_NAME(objectName), 0, &QObject_objectName }
+};
+
+static void buildNameMask(QDeclarativeAccessorProperties::Properties &properties)
+{
+ quint32 mask = 0;
+
+ for (int ii = 0; ii < properties.count; ++ii) {
+ Q_ASSERT(strlen(properties.properties[ii].name) == properties.properties[ii].nameLength);
+ Q_ASSERT(properties.properties[ii].nameLength > 0);
+
+ mask |= (1 << qMin(31U, properties.properties[ii].nameLength - 1));
+ }
+
+ properties.nameMask = mask;
+}
+
+AccessorProperties::AccessorProperties()
+{
+ // Pre-seed QObject::objectName accessor
+ typedef QDeclarativeAccessorProperties::Properties P;
+ properties.insert(&QObject::staticMetaObject,
+ P(qdeclarative_accessor_properties_QObject,
+ sizeof(qdeclarative_accessor_properties_QObject) /
+ sizeof(QDeclarativeAccessorProperties::Property)));
+}
+
+QDeclarativeAccessorProperties::Properties::Properties(Property *properties, int count)
+: count(count), properties(properties)
+{
+ buildNameMask(*this);
+}
+
+QDeclarativeAccessorProperties::Properties
+QDeclarativeAccessorProperties::properties(const QMetaObject *mo)
+{
+ AccessorProperties *This = accessorProperties();
+
+ QReadLocker lock(&This->lock);
+ return This->properties.value(mo);
+}
+
+void QDeclarativeAccessorProperties::registerProperties(const QMetaObject *mo, int count,
+ Property *props)
+{
+ Q_ASSERT(count > 0);
+
+ Properties properties(props, count);
+
+ AccessorProperties *This = accessorProperties();
+
+ QWriteLocker lock(&This->lock);
+
+ Q_ASSERT(!This->properties.contains(mo) || This->properties.value(mo) == properties);
+
+ This->properties.insert(mo, properties);
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativeaccessors_p.h b/src/declarative/qml/qdeclarativeaccessors_p.h
new file mode 100644
index 0000000000..bf0b11189a
--- /dev/null
+++ b/src/declarative/qml/qdeclarativeaccessors_p.h
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEACCESSORS_P_H
+#define QDECLARATIVEACCESSORS_P_H
+
+#include <QtCore/qvector.h>
+#include <QtCore/qhash.h>
+#include <QtCore/QReadWriteLock>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QObject;
+class QDeclarativeNotifier;
+
+// QML "accessor properties" allow V4 and V8 to bypass Qt's meta system to read and, more
+// importantly, subscribe to properties directly. Any property that is primarily read
+// from bindings is a candidate for inclusion as an accessor property.
+//
+// To define accessor properties, use the QML_DECLARE_PROPERTIES() and QML_DEFINE_PROPERTIES()
+// macros. The QML_DECLARE_PROPERTIES() macro is used to specify the properties, and the
+// QML_DEFINE_PROPERTIES() macro to register the properties with the
+// QDeclarativeAccessorProperties singleton.
+//
+// A class with accessor properties must also add the Q_CLASSINFO("qt_HasQmlAccessors", "true")
+// tag to its declaration. This is essential for QML to maintain internal consistency,
+// and forgetting to do so will probably cause your application to qFatal() with a
+// helpful reminder of this requirement.
+//
+// It is important that QML_DEFINE_PROPERTIES() has been called before QML ever sees
+// the type with the accessor properties. As QML_DEFINE_PROPERTIES() is idempotent, it is
+// recommended to call it in the type's constructor as well as when the type is registered
+// as a QML element (if it ever is). QML_DEFINE_PROPERTIES() is a very cheap operation
+// if registration has already occurred.
+
+#define QML_DECLARE_PROPERTIES(type) \
+ static volatile bool qdeclarative_accessor_properties_isregistered_ ## type = false; \
+ static QDeclarativeAccessorProperties::Property qdeclarative_accessor_properties_ ## type[] =
+
+#define QML_DEFINE_PROPERTIES(type) \
+ do { \
+ if (!qdeclarative_accessor_properties_isregistered_ ## type) { \
+ int count = sizeof(qdeclarative_accessor_properties_ ## type) / \
+ sizeof(QDeclarativeAccessorProperties::Property); \
+ QDeclarativeAccessorProperties::registerProperties(&type::staticMetaObject, count, \
+ qdeclarative_accessor_properties_ ## type);\
+ qdeclarative_accessor_properties_isregistered_ ## type = true; \
+ } \
+ } while (false);
+
+#define QML_PRIVATE_ACCESSOR(clazz, cpptype, name, variable) \
+ static void clazz ## _ ## name ## Read(QObject *o, intptr_t, void *rv) \
+ { \
+ clazz ## Private *d = clazz ## Private::get(static_cast<clazz *>(o)); \
+ *static_cast<cpptype *>(rv) = d->variable; \
+ }
+
+#define QML_PROPERTY_NAME(name) #name, sizeof #name - 1
+
+struct QDeclarativeAccessors
+{
+ void (*read)(QObject *object, intptr_t property, void *output);
+ void (*notifier)(QObject *object, intptr_t property, QDeclarativeNotifier **notifier);
+};
+
+namespace QDeclarativeAccessorProperties {
+ struct Property {
+ const char *name;
+ unsigned int nameLength;
+ intptr_t data;
+ QDeclarativeAccessors *accessors;
+ };
+
+ struct Properties {
+ inline Properties();
+ Properties(Property *, int);
+
+ bool operator==(const Properties &o) const {
+ return count == o.count && properties == o.properties;
+ }
+
+ inline Property *property(const char *name);
+
+ int count;
+ Property *properties;
+ quint32 nameMask;
+ };
+
+ Properties properties(const QMetaObject *);
+ void Q_DECLARATIVE_EXPORT registerProperties(const QMetaObject *, int, Property *);
+};
+
+QDeclarativeAccessorProperties::Property *
+QDeclarativeAccessorProperties::Properties::property(const char *name)
+{
+ if (count == 0)
+ return 0;
+
+ unsigned int length = strlen(name);
+
+ Q_ASSERT(length);
+
+ if (nameMask & (1 << qMin(31U, length - 1))) {
+
+ for (int ii = 0; ii < count; ++ii) {
+ if (properties[ii].nameLength == length && 0 == qstrcmp(name, properties[ii].name))
+ return &properties[ii];
+ }
+
+ }
+
+ return 0;
+}
+
+QDeclarativeAccessorProperties::Properties::Properties()
+: count(0), properties(0), nameMask(0)
+{
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEACCESSORS_P_H
diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp
index 9a3a7e005c..fbfba6d8d3 100644
--- a/src/declarative/qml/qdeclarativebinding.cpp
+++ b/src/declarative/qml/qdeclarativebinding.cpp
@@ -300,6 +300,16 @@ void QDeclarativeBinding::setTarget(const QDeclarativeProperty &prop)
update();
}
+void QDeclarativeBinding::setTarget(QObject *object,
+ const QDeclarativePropertyData &core,
+ QDeclarativeContextData *ctxt)
+{
+ Q_D(QDeclarativeBinding);
+ d->property = QDeclarativePropertyPrivate::restore(object, core, ctxt);
+
+ update();
+}
+
QDeclarativeProperty QDeclarativeBinding::property() const
{
Q_D(const QDeclarativeBinding);
diff --git a/src/declarative/qml/qdeclarativebinding_p.h b/src/declarative/qml/qdeclarativebinding_p.h
index 6f545fc2c6..8f4c736d6a 100644
--- a/src/declarative/qml/qdeclarativebinding_p.h
+++ b/src/declarative/qml/qdeclarativebinding_p.h
@@ -157,6 +157,7 @@ public:
QDeclarativeBinding(void *, QObject *, QDeclarativeContextData *, QObject *parent=0);
void setTarget(const QDeclarativeProperty &);
+ void setTarget(QObject *, const QDeclarativePropertyData &, QDeclarativeContextData *);
QDeclarativeProperty property() const;
void setEvaluateFlags(EvaluateFlags flags);
diff --git a/src/declarative/qml/qdeclarativefastproperties.cpp b/src/declarative/qml/qdeclarativefastproperties.cpp
deleted file mode 100644
index 5816b3f8cb..0000000000
--- a/src/declarative/qml/qdeclarativefastproperties.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdeclarativefastproperties_p.h"
-
-#include "qdeclarativedata_p.h"
-#include "qdeclarativenotifier_p.h"
-
-QT_BEGIN_NAMESPACE
-
-// Adding entries to the QDeclarativeFastProperties class allows the QML
-// binding optimizer to bypass Qt's meta system and read and, more
-// importantly, subscribe to properties directly. Any property that is
-// primarily read from bindings is a candidate for inclusion as a fast
-// property.
-
-Q_GLOBAL_STATIC(QDeclarativeFastProperties, fastProperties)
-
-QDeclarativeFastProperties *QDeclarativeFastProperties::instance()
-{
- return fastProperties();
-}
-
-static void QObject_objectName(QObject *object, void *output, QDeclarativeNotifierEndpoint *endpoint)
-{
- if (endpoint)
- endpoint->connect(QDeclarativeData::get(object, true)->objectNameNotifier());
- *((QString *)output) = object->objectName();
-}
-
-QDeclarativeFastProperties::QDeclarativeFastProperties()
-{
- add(&QObject::staticMetaObject, QObject::staticMetaObject.indexOfProperty("objectName"),
- QObject_objectName);
-}
-
-int QDeclarativeFastProperties::accessorIndexForProperty(const QMetaObject *metaObject, int propertyIndex)
-{
- Q_ASSERT(metaObject);
- Q_ASSERT(propertyIndex >= 0);
-
- // Find the "real" metaObject
- while (metaObject->propertyOffset() > propertyIndex)
- metaObject = metaObject->superClass();
-
- QReadLocker lock(&m_lock);
- QHash<QPair<const QMetaObject *, int>, int>::Iterator iter =
- m_index.find(qMakePair(metaObject, propertyIndex));
- if (iter != m_index.end())
- return *iter;
- else
- return -1;
-}
-
-void QDeclarativeFastProperties::add(const QMetaObject *metaObject, int propertyIndex, Accessor accessor)
-{
- Q_ASSERT(metaObject);
- Q_ASSERT(propertyIndex >= 0);
-
- // Find the "real" metaObject
- while (metaObject->propertyOffset() > propertyIndex)
- metaObject = metaObject->superClass();
-
- QPair<const QMetaObject *, int> data = qMakePair(metaObject, propertyIndex);
- QWriteLocker lock(&m_lock);
- int accessorIndex = m_accessors.count();
- m_accessors.append(accessor);
- m_index.insert(data, accessorIndex);
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativefastproperties_p.h b/src/declarative/qml/qdeclarativefastproperties_p.h
deleted file mode 100644
index 1e09131222..0000000000
--- a/src/declarative/qml/qdeclarativefastproperties_p.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECLARATIVEFASTPROPERTIES_P_H
-#define QDECLARATIVEFASTPROPERTIES_P_H
-
-#include <QtCore/qvector.h>
-#include <QtCore/qhash.h>
-#include <QtCore/QReadWriteLock>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-class QObject;
-class QDeclarativeNotifierEndpoint;
-class Q_DECLARATIVE_EXPORT QDeclarativeFastProperties
-{
-public:
- typedef void (*Accessor)(QObject *object, void *output, QDeclarativeNotifierEndpoint *endpoint);
- QDeclarativeFastProperties();
-
- Accessor accessor(int index) const { QReadLocker lock(&m_lock); return m_accessors.at(index); }
- int accessorIndexForProperty(const QMetaObject *, int);
-
- void add(const QMetaObject *, int, Accessor);
-
- static QDeclarativeFastProperties *instance();
-
-private:
- QHash<QPair<const QMetaObject *, int>, int> m_index;
- QVector<Accessor> m_accessors;
- mutable QReadWriteLock m_lock;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDECLARATIVEFASTPROPERTIES_P_H
diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp
index 795283c41d..1e0b14ee02 100644
--- a/src/declarative/qml/qdeclarativeproperty.cpp
+++ b/src/declarative/qml/qdeclarativeproperty.cpp
@@ -219,6 +219,11 @@ QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name, QD
Q_GLOBAL_STATIC(QDeclarativeValueTypeFactory, qmlValueTypes);
+QDeclarativePropertyPrivate::QDeclarativePropertyPrivate()
+: context(0), engine(0), object(0), isNameCached(false)
+{
+}
+
QDeclarativeContextData *QDeclarativePropertyPrivate::effectiveContext() const
{
if (context) return context;
@@ -1695,8 +1700,8 @@ QDeclarativePropertyPrivate::saveValueType(const QMetaObject *metaObject, int in
}
QDeclarativeProperty
-QDeclarativePropertyPrivate::restore(const QDeclarativePropertyData &data,
- QObject *object, QDeclarativeContextData *ctxt)
+QDeclarativePropertyPrivate::restore(QObject *object, const QDeclarativePropertyData &data,
+ QDeclarativeContextData *ctxt)
{
QDeclarativeProperty prop;
diff --git a/src/declarative/qml/qdeclarativeproperty_p.h b/src/declarative/qml/qdeclarativeproperty_p.h
index f2e86dda19..ce66ef8c2c 100644
--- a/src/declarative/qml/qdeclarativeproperty_p.h
+++ b/src/declarative/qml/qdeclarativeproperty_p.h
@@ -69,21 +69,26 @@ class QDeclarativeJavaScriptExpression;
class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativePropertyPrivate : public QDeclarativeRefCount
{
public:
- enum WriteFlag { BypassInterceptor = 0x01, DontRemoveBinding = 0x02, RemoveBindingOnAliasWrite = 0x04 };
+ enum WriteFlag {
+ BypassInterceptor = 0x01,
+ DontRemoveBinding = 0x02,
+ RemoveBindingOnAliasWrite = 0x04
+ };
Q_DECLARE_FLAGS(WriteFlags, WriteFlag)
- QDeclarativePropertyPrivate()
- : context(0), engine(0), object(0), isNameCached(false) {}
-
- inline QDeclarativeContextData *effectiveContext() const;
QDeclarativeContextData *context;
QDeclarativeEngine *engine;
QDeclarativeGuard<QObject> object;
- bool isNameCached:1;
QDeclarativePropertyData core;
+
+ bool isNameCached:1;
QString nameCache;
+ QDeclarativePropertyPrivate();
+
+ inline QDeclarativeContextData *effectiveContext() const;
+
void initProperty(QObject *obj, const QString &name);
void initDefault(QObject *obj);
@@ -105,18 +110,21 @@ public:
static bool write(QObject *, const QDeclarativePropertyData &, const QVariant &,
QDeclarativeContextData *, WriteFlags flags = 0);
static void findAliasTarget(QObject *, int, QObject **, int *);
- static QDeclarativeAbstractBinding *setBinding(QObject *, int coreIndex, int valueTypeIndex /* -1 */,
+ static QDeclarativeAbstractBinding *setBinding(QObject *, int coreIndex,
+ int valueTypeIndex /* -1 */,
QDeclarativeAbstractBinding *,
WriteFlags flags = DontRemoveBinding);
- static QDeclarativeAbstractBinding *setBindingNoEnable(QObject *, int coreIndex, int valueTypeIndex /* -1 */,
+ static QDeclarativeAbstractBinding *setBindingNoEnable(QObject *, int coreIndex,
+ int valueTypeIndex /* -1 */,
QDeclarativeAbstractBinding *);
- static QDeclarativeAbstractBinding *binding(QObject *, int coreIndex, int valueTypeIndex /* -1 */);
+ static QDeclarativeAbstractBinding *binding(QObject *, int coreIndex,
+ int valueTypeIndex /* -1 */);
static QDeclarativePropertyData saveValueType(const QMetaObject *, int,
const QMetaObject *, int,
QDeclarativeEngine *);
- static QDeclarativeProperty restore(const QDeclarativePropertyData &,
- QObject *,
+ static QDeclarativeProperty restore(QObject *,
+ const QDeclarativePropertyData &,
QDeclarativeContextData *);
static bool equal(const QMetaObject *, const QMetaObject *);
diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp
index d99731955b..239b7942da 100644
--- a/src/declarative/qml/qdeclarativepropertycache.cpp
+++ b/src/declarative/qml/qdeclarativepropertycache.cpp
@@ -46,6 +46,7 @@
#include <private/qv8engine_p.h>
#include <private/qmetaobject_p.h>
+#include <private/qdeclarativeaccessors_p.h>
#include <QtCore/qdebug.h>
@@ -54,6 +55,8 @@ Q_DECLARE_METATYPE(QDeclarativeV8Handle);
QT_BEGIN_NAMESPACE
+#define Q_INT16_MAX 32767
+
class QDeclarativePropertyCacheMethodArguments
{
public:
@@ -85,9 +88,15 @@ static QDeclarativePropertyData::Flags fastFlagsForProperty(const QMetaProperty
// load
static QDeclarativePropertyData::Flags flagsForPropertyType(int propType, QDeclarativeEngine *engine)
{
+ Q_ASSERT(propType != -1);
+
QDeclarativePropertyData::Flags flags;
- if (propType < QMetaType::User && propType != QMetaType::QObjectStar && propType != QMetaType::QWidgetStar) {
+ if (propType == QMetaType::QObjectStar || propType == QMetaType::QWidgetStar) {
+ flags |= QDeclarativePropertyData::IsQObjectDerived;
+ } else if (propType == QMetaType::QVariant) {
+ flags |= QDeclarativePropertyData::IsQVariant;
+ } else if (propType < (int)QVariant::UserType) {
} else if (propType == qMetaTypeId<QDeclarativeBinding *>()) {
flags |= QDeclarativePropertyData::IsQmlBinding;
} else if (propType == qMetaTypeId<QJSValue>()) {
@@ -120,6 +129,7 @@ void QDeclarativePropertyData::lazyLoad(const QMetaProperty &p, QDeclarativeEngi
coreIndex = p.propertyIndex();
notifyIndex = p.notifySignalIndex();
+ Q_ASSERT(p.revision() <= Q_INT16_MAX);
revision = p.revision();
flags = fastFlagsForProperty(p);
@@ -140,10 +150,11 @@ void QDeclarativePropertyData::load(const QMetaProperty &p, QDeclarativeEngine *
{
propType = p.userType();
if (QVariant::Type(propType) == QVariant::LastType)
- propType = qMetaTypeId<QVariant>();
+ propType = QMetaType::QVariant;
coreIndex = p.propertyIndex();
notifyIndex = p.notifySignalIndex();
flags = fastFlagsForProperty(p) | flagsForPropertyType(propType, engine);
+ Q_ASSERT(p.revision() <= Q_INT16_MAX);
revision = p.revision();
}
@@ -171,6 +182,7 @@ void QDeclarativePropertyData::load(const QMetaMethod &m)
}
}
+ Q_ASSERT(m.revision() <= Q_INT16_MAX);
revision = m.revision();
}
@@ -200,6 +212,7 @@ void QDeclarativePropertyData::lazyLoad(const QMetaMethod &m)
}
}
+ Q_ASSERT(m.revision() <= Q_INT16_MAX);
revision = m.revision();
}
@@ -259,52 +272,6 @@ void QDeclarativePropertyCache::clear()
engine = 0;
}
-QDeclarativePropertyData QDeclarativePropertyCache::create(const QMetaObject *metaObject,
- const QString &property)
-{
- Q_ASSERT(metaObject);
-
- QDeclarativePropertyData rv;
- {
- const QMetaObject *cmo = metaObject;
- const QByteArray propertyName = property.toUtf8();
- while (cmo) {
- int idx = cmo->indexOfProperty(propertyName);
- if (idx != -1) {
- QMetaProperty p = cmo->property(idx);
- if (p.isScriptable()) {
- rv.load(p);
- return rv;
- } else {
- while (cmo && cmo->propertyOffset() >= idx)
- cmo = cmo->superClass();
- }
- } else {
- cmo = 0;
- }
- }
- }
-
- 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());
-
- int parenIdx = methodName.indexOf(QLatin1Char('('));
- Q_ASSERT(parenIdx != -1);
- QStringRef methodNameRef = methodName.leftRef(parenIdx);
-
- if (methodNameRef == property) {
- rv.load(m);
- return rv;
- }
- }
-
- return rv;
-}
-
QDeclarativePropertyCache *QDeclarativePropertyCache::copy(int reserve)
{
QDeclarativePropertyCache *cache = new QDeclarativePropertyCache(engine);
@@ -347,6 +314,40 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb
int methodCount = metaObject->methodCount();
Q_ASSERT(QMetaObjectPrivate::get(metaObject)->revision >= 4);
int signalCount = QMetaObjectPrivate::get(metaObject)->signalCount;
+ int classInfoCount = QMetaObjectPrivate::get(metaObject)->classInfoCount;
+
+ QDeclarativeAccessorProperties::Properties accessorProperties;
+
+ // Special case QObject as we don't want to add a qt_HasQmlAccessors classinfo to it
+ if (metaObject == &QObject::staticMetaObject) {
+ accessorProperties = QDeclarativeAccessorProperties::properties(metaObject);
+ } else if (classInfoCount) {
+ int classInfoOffset = metaObject->classInfoOffset();
+ bool hasFastProperty = false;
+ for (int ii = 0; ii < classInfoCount; ++ii) {
+ int idx = ii + classInfoOffset;
+
+ if (0 == qstrcmp(metaObject->classInfo(idx).name(), "qt_HasQmlAccessors")) {
+ hasFastProperty = true;
+ break;
+ }
+ }
+
+ if (hasFastProperty) {
+ accessorProperties = QDeclarativeAccessorProperties::properties(metaObject);
+ if (accessorProperties.count == 0)
+ qFatal("QDeclarativePropertyCache: %s has FastProperty class info, but has not "
+ "installed property accessors", metaObject->className());
+ } else {
+#ifndef QT_NO_DEBUG
+ accessorProperties = QDeclarativeAccessorProperties::properties(metaObject);
+ if (accessorProperties.count != 0)
+ qFatal("QDeclarativePropertyCache: %s has fast property accessors, but is missing "
+ "FastProperty class info", metaObject->className());
+#endif
+ }
+ }
+
// 3 to block the destroyed signal and the deleteLater() slot
int methodOffset = qMax(3, metaObject->methodOffset());
@@ -381,6 +382,7 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb
if (!dynamicMetaObject)
data->flags |= QDeclarativePropertyData::IsDirect;
+ Q_ASSERT((allowedRevisionCache.count() - 1) < Q_INT16_MAX);
data->metaObjectOffset = allowedRevisionCache.count() - 1;
if (data->isSignal()) {
@@ -459,6 +461,7 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb
if (!dynamicMetaObject)
data->flags |= QDeclarativePropertyData::IsDirect;
+ Q_ASSERT((allowedRevisionCache.count() - 1) < Q_INT16_MAX);
data->metaObjectOffset = allowedRevisionCache.count() - 1;
QDeclarativePropertyData *old = 0;
@@ -475,7 +478,16 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb
stringCache.insert(propName, data);
}
- if (old) {
+ QDeclarativeAccessorProperties::Property *accessorProperty = accessorProperties.property(str);
+
+ // Fast properties may not be overrides
+ Q_ASSERT(accessorProperty == 0 || old == 0);
+
+ if (accessorProperty) {
+ data->flags |= QDeclarativePropertyData::HasAccessors;
+ data->accessors = accessorProperty->accessors;
+ data->accessorData = accessorProperty->data;
+ } else if (old) {
data->overrideIndexIsProperty = !old->isFunction();
data->overrideIndex = old->coreIndex;
}
@@ -488,8 +500,7 @@ void QDeclarativePropertyCache::resolve(QDeclarativePropertyData *data) const
data->propType = QMetaType::type(data->propTypeName);
if (QVariant::Type(data->propType) == QVariant::LastType)
- data->propType = qMetaTypeId<QVariant>();
-
+ data->propType = QMetaType::QVariant;
if (!data->isFunction())
data->flags |= flagsForPropertyType(data->propType, engine);
@@ -699,21 +710,83 @@ int *QDeclarativePropertyCache::methodParameterTypes(QObject *object, int index,
}
}
+QDeclarativePropertyData qDeclarativePropertyCacheCreate(const QMetaObject *metaObject,
+ const QString &property)
+{
+ Q_ASSERT(metaObject);
+
+ QDeclarativePropertyData rv;
+ {
+ const QMetaObject *cmo = metaObject;
+ const QByteArray propertyName = property.toUtf8();
+ while (cmo) {
+ int idx = cmo->indexOfProperty(propertyName);
+ if (idx != -1) {
+ QMetaProperty p = cmo->property(idx);
+ if (p.isScriptable()) {
+ rv.load(p);
+ return rv;
+ } else {
+ while (cmo && cmo->propertyOffset() >= idx)
+ cmo = cmo->superClass();
+ }
+ } else {
+ cmo = 0;
+ }
+ }
+ }
+
+ 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());
+
+ int parenIdx = methodName.indexOf(QLatin1Char('('));
+ Q_ASSERT(parenIdx != -1);
+ QStringRef methodNameRef = methodName.leftRef(parenIdx);
+
+ if (methodNameRef == property) {
+ rv.load(m);
+ return rv;
+ }
+ }
+
+ return rv;
+}
+
+inline const QString &qDeclarativePropertyCacheToString(const QString &string)
+{
+ return string;
+}
+
+inline QString qDeclarativePropertyCacheToString(const QHashedV8String &string)
+{
+ return QV8Engine::toStringStatic(string.string());
+}
+
+template<typename T>
QDeclarativePropertyData *
-QDeclarativePropertyCache::property(QDeclarativeEngine *engine, QObject *obj,
- const QHashedV8String &name, QDeclarativePropertyData &local)
+qDeclarativePropertyCacheProperty(QDeclarativeEngine *engine, QObject *obj,
+ const T &name, QDeclarativePropertyData &local)
{
- // XXX Optimize for worker script case where engine isn't available
QDeclarativePropertyCache *cache = 0;
- if (engine) {
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
+ if (engine) {
QDeclarativeData *ddata = QDeclarativeData::get(obj);
- if (ddata && ddata->propertyCache)
+
+ if (ddata && ddata->propertyCache) {
cache = ddata->propertyCache;
- if (!cache) {
+ } else if (engine) {
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
cache = ep->cache(obj);
- if (cache && ddata && !ddata->propertyCache) { cache->addref(); ddata->propertyCache = cache; }
+ if (cache) {
+ ddata = QDeclarativeData::get(obj, true);
+ cache->addref();
+ ddata->propertyCache = cache;
+ }
}
}
@@ -722,9 +795,8 @@ QDeclarativePropertyCache::property(QDeclarativeEngine *engine, QObject *obj,
if (cache) {
rv = cache->property(name);
} else {
- QString strname = QV8Engine::toStringStatic(name.string());
- // QString strname = ep->v8engine()->toString(name);
- local = QDeclarativePropertyCache::create(obj->metaObject(), strname);
+ local = qDeclarativePropertyCacheCreate(obj->metaObject(),
+ qDeclarativePropertyCacheToString(name));
if (local.isValid())
rv = &local;
}
@@ -734,36 +806,16 @@ QDeclarativePropertyCache::property(QDeclarativeEngine *engine, QObject *obj,
QDeclarativePropertyData *
QDeclarativePropertyCache::property(QDeclarativeEngine *engine, QObject *obj,
- const QString &name, QDeclarativePropertyData &local)
+ const QHashedV8String &name, QDeclarativePropertyData &local)
{
- QDeclarativePropertyData *rv = 0;
-
- if (!engine) {
- local = QDeclarativePropertyCache::create(obj->metaObject(), name);
- if (local.isValid())
- rv = &local;
- } else {
- QDeclarativeEnginePrivate *enginePrivate = QDeclarativeEnginePrivate::get(engine);
-
- QDeclarativePropertyCache *cache = 0;
- QDeclarativeData *ddata = QDeclarativeData::get(obj);
- if (ddata && ddata->propertyCache)
- cache = ddata->propertyCache;
- if (!cache) {
- cache = enginePrivate->cache(obj);
- if (cache && ddata && !ddata->propertyCache) { cache->addref(); ddata->propertyCache = cache; }
- }
-
- if (cache) {
- rv = cache->property(name);
- } else {
- local = QDeclarativePropertyCache::create(obj->metaObject(), name);
- if (local.isValid())
- rv = &local;
- }
- }
+ return qDeclarativePropertyCacheProperty<QHashedV8String>(engine, obj, name, local);
+}
- return rv;
+QDeclarativePropertyData *
+QDeclarativePropertyCache::property(QDeclarativeEngine *engine, QObject *obj,
+ const QString &name, QDeclarativePropertyData &local)
+{
+ return qDeclarativePropertyCacheProperty<QString>(engine, obj, name, local);
}
static inline const QMetaObjectPrivate *priv(const uint* data)
diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h
index fc4a24ca9c..3deafdf9c5 100644
--- a/src/declarative/qml/qdeclarativepropertycache_p.h
+++ b/src/declarative/qml/qdeclarativepropertycache_p.h
@@ -63,14 +63,15 @@
QT_BEGIN_NAMESPACE
-class QDeclarativeEngine;
-class QMetaProperty;
class QV8Engine;
+class QMetaProperty;
class QV8QObjectWrapper;
-class QDeclarativePropertyCacheMethodArguments;
+class QDeclarativeEngine;
class QDeclarativePropertyData;
+class QDeclarativeAccessors;
+class QDeclarativePropertyCacheMethodArguments;
-// We have this somewhat aweful split between RawData and Data so that RawData can be
+// We have this somewhat awful split between RawData and Data so that RawData can be
// used in unions. In normal code, you should always use Data which initializes RawData
// to an invalid state on construction.
class QDeclarativePropertyRawData
@@ -87,29 +88,31 @@ public:
IsAlias = 0x00000008, // Is a QML alias to another property
IsFinal = 0x00000010, // Has FINAL flag
IsDirect = 0x00000020, // Exists on a C++ QMetaObject
+ HasAccessors = 0x00000040, // Has property accessors
// These are mutualy exclusive
- IsFunction = 0x00000040, // Is an invokable
- IsQObjectDerived = 0x00000080, // Property type is a QObject* derived type
- IsEnumType = 0x00000100, // Property type is an enum
- IsQList = 0x00000200, // Property type is a QML list
- IsQmlBinding = 0x00000400, // Property type is a QDeclarativeBinding*
- IsQJSValue = 0x00000800, // Property type is a QScriptValue
- IsV8Handle = 0x00001000, // Property type is a QDeclarativeV8Handle
- IsVMEProperty = 0x00002000, // Property type is a "var" property of VMEMO
- IsValueTypeVirtual = 0x00004000, // Property is a value type "virtual" property
+ IsFunction = 0x00000080, // Is an invokable
+ IsQObjectDerived = 0x00000100, // Property type is a QObject* derived type
+ IsEnumType = 0x00000200, // Property type is an enum
+ IsQList = 0x00000400, // Property type is a QML list
+ IsQmlBinding = 0x00000800, // Property type is a QDeclarativeBinding*
+ IsQJSValue = 0x00001000, // Property type is a QScriptValue
+ IsV8Handle = 0x00002000, // Property type is a QDeclarativeV8Handle
+ IsVMEProperty = 0x00004000, // Property type is a "var" property of VMEMO
+ IsValueTypeVirtual = 0x00008000, // Property is a value type "virtual" property
+ IsQVariant = 0x00010000, // Property is a QVariant
// Apply only to IsFunctions
- IsVMEFunction = 0x00008000, // Function was added by QML
- HasArguments = 0x00010000, // Function takes arguments
- IsSignal = 0x00020000, // Function is a signal
- IsVMESignal = 0x00040000, // Signal was added by QML
- IsV8Function = 0x00080000, // Function takes QDeclarativeV8Function* args
- IsSignalHandler = 0x00100000, // Function is a signal handler
- IsOverload = 0x00200000, // Function is an overload of another function
+ IsVMEFunction = 0x00020000, // Function was added by QML
+ HasArguments = 0x00040000, // Function takes arguments
+ IsSignal = 0x00080000, // Function is a signal
+ IsVMESignal = 0x00100000, // Signal was added by QML
+ IsV8Function = 0x00200000, // Function takes QDeclarativeV8Function* args
+ IsSignalHandler = 0x00400000, // Function is a signal handler
+ IsOverload = 0x00800000, // Function is an overload of another function
// Internal QDeclarativePropertyCache flags
- NotFullyResolved = 0x00400000 // True if the type data is to be lazily resolved
+ NotFullyResolved = 0x01000000 // True if the type data is to be lazily resolved
};
Q_DECLARE_FLAGS(Flags, Flag)
@@ -124,6 +127,7 @@ public:
bool isAlias() const { return flags & IsAlias; }
bool isFinal() const { return flags & IsFinal; }
bool isDirect() const { return flags & IsDirect; }
+ bool hasAccessors() const { return flags & HasAccessors; }
bool isFunction() const { return flags & IsFunction; }
bool isQObject() const { return flags & IsQObjectDerived; }
bool isEnum() const { return flags & IsEnumType; }
@@ -133,6 +137,7 @@ public:
bool isV8Handle() const { return flags & IsV8Handle; }
bool isVMEProperty() const { return flags & IsVMEProperty; }
bool isValueTypeVirtual() const { return flags & IsValueTypeVirtual; }
+ bool isQVariant() const { return flags & IsQVariant; }
bool isVMEFunction() const { return flags & IsVMEFunction; }
bool hasArguments() const { return flags & HasArguments; }
bool isSignal() const { return flags & IsSignal; }
@@ -141,6 +146,11 @@ public:
bool isSignalHandler() const { return flags & IsSignalHandler; }
bool isOverload() const { return flags & IsOverload; }
+ bool hasOverride() const { return !(flags & IsValueTypeVirtual) && overrideIndex >= 0; }
+
+ // Returns -1 if not a value type virtual property
+ inline int getValueTypeCoreIndex() const;
+
union {
int propType; // When !NotFullyResolved
const char *propTypeName; // When NotFullyResolved
@@ -163,8 +173,14 @@ public:
//proxy object
};
};
- int revision;
- int metaObjectOffset;
+
+ qint16 revision;
+ qint16 metaObjectOffset;
+
+ struct { // When HasAccessors
+ QDeclarativeAccessors *accessors;
+ intptr_t accessorData;
+ };
private:
friend class QDeclarativePropertyData;
@@ -187,9 +203,6 @@ public:
QString name(QObject *);
QString name(const QMetaObject *);
- // Returns -1 if not a value type virtual property
- inline int getValueTypeCoreIndex() const;
-
private:
friend class QDeclarativePropertyCache;
void lazyLoad(const QMetaProperty &, QDeclarativeEngine *engine = 0);
@@ -216,8 +229,6 @@ public:
QDeclarativePropertyData::Flag methodFlags = QDeclarativePropertyData::NoFlags,
QDeclarativePropertyData::Flag signalFlags = QDeclarativePropertyData::NoFlags);
- static QDeclarativePropertyData create(const QMetaObject *, const QString &);
-
inline QDeclarativePropertyData *property(const QHashedV8String &) const;
QDeclarativePropertyData *property(const QHashedStringRef &) const;
QDeclarativePropertyData *property(const QHashedCStringRef &) const;
@@ -282,6 +293,8 @@ QDeclarativePropertyData::QDeclarativePropertyData()
overrideIndex = -1;
revision = 0;
metaObjectOffset = -1;
+ accessors = 0;
+ accessorData = 0;
flags = 0;
}
@@ -302,7 +315,7 @@ bool QDeclarativePropertyData::operator==(const QDeclarativePropertyRawData &oth
valueTypePropType == other.valueTypePropType));
}
-int QDeclarativePropertyData::getValueTypeCoreIndex() const
+int QDeclarativePropertyRawData::getValueTypeCoreIndex() const
{
return isValueTypeVirtual()?valueTypeCoreIndex:-1;
}
@@ -310,7 +323,7 @@ int QDeclarativePropertyData::getValueTypeCoreIndex() const
QDeclarativePropertyData *
QDeclarativePropertyCache::overrideData(QDeclarativePropertyData *data) const
{
- if (data->overrideIndex < 0)
+ if (!data->hasOverride())
return 0;
if (data->overrideIndexIsProperty)
diff --git a/src/declarative/qml/qdeclarativevaluetype.cpp b/src/declarative/qml/qdeclarativevaluetype.cpp
index ffd0041f7e..434059ff76 100644
--- a/src/declarative/qml/qdeclarativevaluetype.cpp
+++ b/src/declarative/qml/qdeclarativevaluetype.cpp
@@ -168,44 +168,58 @@ QDeclarativeValueType::QDeclarativeValueType(QObject *parent)
{
}
-QDeclarativePointFValueType::QDeclarativePointFValueType(QObject *parent)
-: QDeclarativeValueType(parent)
-{
-}
-
-void QDeclarativePointFValueType::read(QObject *obj, int idx)
-{
- void *a[] = { &point, 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
-}
-
-void QDeclarativePointFValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags)
-{
- int status = -1;
- void *a[] = { &point, 0, &status, &flags };
- QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
-}
-
-QVariant QDeclarativePointFValueType::value()
-{
- return QVariant(point);
-}
+#define QML_VALUETYPE_READWRITE(name, cpptype, var) \
+ QDeclarative ## name ## ValueType::QDeclarative ## name ## ValueType(QObject *parent) \
+ : QDeclarativeValueType(parent) \
+ { \
+ } \
+ void QDeclarative ## name ## ValueType::read(QObject *obj, int idx) \
+ { \
+ void *a[] = { &var, 0 }; \
+ QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a); \
+ onLoad(); \
+ } \
+ void QDeclarative ## name ## ValueType::write(QObject *obj, int idx, \
+ QDeclarativePropertyPrivate::WriteFlags flags) \
+ { \
+ int status = -1; \
+ void *a[] = { &var, 0, &status, &flags }; \
+ QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a); \
+ } \
+ bool QDeclarative ## name ## ValueType::isEqual(const QVariant &value) const \
+ { \
+ return QVariant(var) == value; \
+ } \
+ QVariant QDeclarative ## name ## ValueType::value() \
+ { \
+ return QVariant(var); \
+ } \
+ void QDeclarative ## name ## ValueType::setValue(const QVariant &value) \
+ { \
+ var = qvariant_cast<cpptype>(value); \
+ onLoad(); \
+ }
-void QDeclarativePointFValueType::setValue(QVariant value)
-{
- point = qvariant_cast<QPointF>(value);
-}
+QML_VALUETYPE_READWRITE(PointF, QPointF, point);
+QML_VALUETYPE_READWRITE(Point, QPoint, point);
+QML_VALUETYPE_READWRITE(SizeF, QSizeF, size);
+QML_VALUETYPE_READWRITE(Size, QSize, size);
+QML_VALUETYPE_READWRITE(RectF, QRectF, rect);
+QML_VALUETYPE_READWRITE(Rect, QRect, rect);
+QML_VALUETYPE_READWRITE(Vector2D, QVector2D, vector);
+QML_VALUETYPE_READWRITE(Vector3D, QVector3D, vector);
+QML_VALUETYPE_READWRITE(Vector4D, QVector4D, vector);
+QML_VALUETYPE_READWRITE(Quaternion, QQuaternion, quaternion);
+QML_VALUETYPE_READWRITE(Matrix4x4, QMatrix4x4, matrix);
+QML_VALUETYPE_READWRITE(Easing, QEasingCurve, easing);
+QML_VALUETYPE_READWRITE(Font, QFont, font);
+QML_VALUETYPE_READWRITE(Color, QColor, color);
QString QDeclarativePointFValueType::toString() const
{
return QString(QLatin1String("QPointF(%1, %2)")).arg(point.x()).arg(point.y());
}
-bool QDeclarativePointFValueType::isEqual(const QVariant &value) const
-{
- return (QVariant(point) == value);
-}
-
qreal QDeclarativePointFValueType::x() const
{
return point.x();
@@ -226,44 +240,11 @@ void QDeclarativePointFValueType::setY(qreal y)
point.setY(y);
}
-QDeclarativePointValueType::QDeclarativePointValueType(QObject *parent)
-: QDeclarativeValueType(parent)
-{
-}
-
-void QDeclarativePointValueType::read(QObject *obj, int idx)
-{
- void *a[] = { &point, 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
-}
-
-void QDeclarativePointValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags)
-{
- int status = -1;
- void *a[] = { &point, 0, &status, &flags };
- QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
-}
-
-QVariant QDeclarativePointValueType::value()
-{
- return QVariant(point);
-}
-
-void QDeclarativePointValueType::setValue(QVariant value)
-{
- point = qvariant_cast<QPoint>(value);
-}
-
QString QDeclarativePointValueType::toString() const
{
return QString(QLatin1String("QPoint(%1, %2)")).arg(point.x()).arg(point.y());
}
-bool QDeclarativePointValueType::isEqual(const QVariant &value) const
-{
- return (QVariant(point) == value);
-}
-
int QDeclarativePointValueType::x() const
{
return point.x();
@@ -284,44 +265,11 @@ void QDeclarativePointValueType::setY(int y)
point.setY(y);
}
-QDeclarativeSizeFValueType::QDeclarativeSizeFValueType(QObject *parent)
-: QDeclarativeValueType(parent)
-{
-}
-
-void QDeclarativeSizeFValueType::read(QObject *obj, int idx)
-{
- void *a[] = { &size, 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
-}
-
-void QDeclarativeSizeFValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags)
-{
- int status = -1;
- void *a[] = { &size, 0, &status, &flags };
- QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
-}
-
-QVariant QDeclarativeSizeFValueType::value()
-{
- return QVariant(size);
-}
-
-void QDeclarativeSizeFValueType::setValue(QVariant value)
-{
- size = qvariant_cast<QSizeF>(value);
-}
-
QString QDeclarativeSizeFValueType::toString() const
{
return QString(QLatin1String("QSizeF(%1, %2)")).arg(size.width()).arg(size.height());
}
-bool QDeclarativeSizeFValueType::isEqual(const QVariant &value) const
-{
- return (QVariant(size) == value);
-}
-
qreal QDeclarativeSizeFValueType::width() const
{
return size.width();
@@ -342,44 +290,11 @@ void QDeclarativeSizeFValueType::setHeight(qreal h)
size.setHeight(h);
}
-QDeclarativeSizeValueType::QDeclarativeSizeValueType(QObject *parent)
-: QDeclarativeValueType(parent)
-{
-}
-
-void QDeclarativeSizeValueType::read(QObject *obj, int idx)
-{
- void *a[] = { &size, 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
-}
-
-void QDeclarativeSizeValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags)
-{
- int status = -1;
- void *a[] = { &size, 0, &status, &flags };
- QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
-}
-
-QVariant QDeclarativeSizeValueType::value()
-{
- return QVariant(size);
-}
-
-void QDeclarativeSizeValueType::setValue(QVariant value)
-{
- size = qvariant_cast<QSize>(value);
-}
-
QString QDeclarativeSizeValueType::toString() const
{
return QString(QLatin1String("QSize(%1, %2)")).arg(size.width()).arg(size.height());
}
-bool QDeclarativeSizeValueType::isEqual(const QVariant &value) const
-{
- return (QVariant(size) == value);
-}
-
int QDeclarativeSizeValueType::width() const
{
return size.width();
@@ -400,44 +315,11 @@ void QDeclarativeSizeValueType::setHeight(int h)
size.setHeight(h);
}
-QDeclarativeRectFValueType::QDeclarativeRectFValueType(QObject *parent)
-: QDeclarativeValueType(parent)
-{
-}
-
-void QDeclarativeRectFValueType::read(QObject *obj, int idx)
-{
- void *a[] = { &rect, 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
-}
-
-void QDeclarativeRectFValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags)
-{
- int status = -1;
- void *a[] = { &rect, 0, &status, &flags };
- QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
-}
-
-QVariant QDeclarativeRectFValueType::value()
-{
- return QVariant(rect);
-}
-
-void QDeclarativeRectFValueType::setValue(QVariant value)
-{
- rect = qvariant_cast<QRectF>(value);
-}
-
QString QDeclarativeRectFValueType::toString() const
{
return QString(QLatin1String("QRectF(%1, %2, %3, %4)")).arg(rect.x()).arg(rect.y()).arg(rect.width()).arg(rect.height());
}
-bool QDeclarativeRectFValueType::isEqual(const QVariant &value) const
-{
- return (QVariant(rect) == value);
-}
-
qreal QDeclarativeRectFValueType::x() const
{
return rect.x();
@@ -478,44 +360,11 @@ void QDeclarativeRectFValueType::setHeight(qreal h)
rect.setHeight(h);
}
-QDeclarativeRectValueType::QDeclarativeRectValueType(QObject *parent)
-: QDeclarativeValueType(parent)
-{
-}
-
-void QDeclarativeRectValueType::read(QObject *obj, int idx)
-{
- void *a[] = { &rect, 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
-}
-
-void QDeclarativeRectValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags)
-{
- int status = -1;
- void *a[] = { &rect, 0, &status, &flags };
- QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
-}
-
-QVariant QDeclarativeRectValueType::value()
-{
- return QVariant(rect);
-}
-
-void QDeclarativeRectValueType::setValue(QVariant value)
-{
- rect = qvariant_cast<QRect>(value);
-}
-
QString QDeclarativeRectValueType::toString() const
{
return QString(QLatin1String("QRect(%1, %2, %3, %4)")).arg(rect.x()).arg(rect.y()).arg(rect.width()).arg(rect.height());
}
-bool QDeclarativeRectValueType::isEqual(const QVariant &value) const
-{
- return (QVariant(rect) == value);
-}
-
int QDeclarativeRectValueType::x() const
{
return rect.x();
@@ -556,44 +405,11 @@ void QDeclarativeRectValueType::setHeight(int h)
rect.setHeight(h);
}
-QDeclarativeVector2DValueType::QDeclarativeVector2DValueType(QObject *parent)
-: QDeclarativeValueType(parent)
-{
-}
-
-void QDeclarativeVector2DValueType::read(QObject *obj, int idx)
-{
- void *a[] = { &vector, 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
-}
-
-void QDeclarativeVector2DValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags)
-{
- int status = -1;
- void *a[] = { &vector, 0, &status, &flags };
- QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
-}
-
-QVariant QDeclarativeVector2DValueType::value()
-{
- return QVariant(vector);
-}
-
-void QDeclarativeVector2DValueType::setValue(QVariant value)
-{
- vector = qvariant_cast<QVector2D>(value);
-}
-
QString QDeclarativeVector2DValueType::toString() const
{
return QString(QLatin1String("QVector2D(%1, %2)")).arg(vector.x()).arg(vector.y());
}
-bool QDeclarativeVector2DValueType::isEqual(const QVariant &value) const
-{
- return (QVariant(vector) == value);
-}
-
qreal QDeclarativeVector2DValueType::x() const
{
return vector.x();
@@ -614,44 +430,11 @@ void QDeclarativeVector2DValueType::setY(qreal y)
vector.setY(y);
}
-QDeclarativeVector3DValueType::QDeclarativeVector3DValueType(QObject *parent)
-: QDeclarativeValueType(parent)
-{
-}
-
-void QDeclarativeVector3DValueType::read(QObject *obj, int idx)
-{
- void *a[] = { &vector, 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
-}
-
-void QDeclarativeVector3DValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags)
-{
- int status = -1;
- void *a[] = { &vector, 0, &status, &flags };
- QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
-}
-
-QVariant QDeclarativeVector3DValueType::value()
-{
- return QVariant(vector);
-}
-
-void QDeclarativeVector3DValueType::setValue(QVariant value)
-{
- vector = qvariant_cast<QVector3D>(value);
-}
-
QString QDeclarativeVector3DValueType::toString() const
{
return QString(QLatin1String("QVector3D(%1, %2, %3)")).arg(vector.x()).arg(vector.y()).arg(vector.z());
}
-bool QDeclarativeVector3DValueType::isEqual(const QVariant &value) const
-{
- return (QVariant(vector) == value);
-}
-
qreal QDeclarativeVector3DValueType::x() const
{
return vector.x();
@@ -682,44 +465,11 @@ void QDeclarativeVector3DValueType::setZ(qreal z)
vector.setZ(z);
}
-QDeclarativeVector4DValueType::QDeclarativeVector4DValueType(QObject *parent)
-: QDeclarativeValueType(parent)
-{
-}
-
-void QDeclarativeVector4DValueType::read(QObject *obj, int idx)
-{
- void *a[] = { &vector, 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
-}
-
-void QDeclarativeVector4DValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags)
-{
- int status = -1;
- void *a[] = { &vector, 0, &status, &flags };
- QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
-}
-
-QVariant QDeclarativeVector4DValueType::value()
-{
- return QVariant(vector);
-}
-
-void QDeclarativeVector4DValueType::setValue(QVariant value)
-{
- vector = qvariant_cast<QVector4D>(value);
-}
-
QString QDeclarativeVector4DValueType::toString() const
{
return QString(QLatin1String("QVector4D(%1, %2, %3, %4)")).arg(vector.x()).arg(vector.y()).arg(vector.z()).arg(vector.w());
}
-bool QDeclarativeVector4DValueType::isEqual(const QVariant &value) const
-{
- return (QVariant(vector) == value);
-}
-
qreal QDeclarativeVector4DValueType::x() const
{
return vector.x();
@@ -760,44 +510,11 @@ void QDeclarativeVector4DValueType::setW(qreal w)
vector.setW(w);
}
-QDeclarativeQuaternionValueType::QDeclarativeQuaternionValueType(QObject *parent)
-: QDeclarativeValueType(parent)
-{
-}
-
-void QDeclarativeQuaternionValueType::read(QObject *obj, int idx)
-{
- void *a[] = { &quaternion, 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
-}
-
-void QDeclarativeQuaternionValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags)
-{
- int status = -1;
- void *a[] = { &quaternion, 0, &status, &flags };
- QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
-}
-
-QVariant QDeclarativeQuaternionValueType::value()
-{
- return QVariant(quaternion);
-}
-
-void QDeclarativeQuaternionValueType::setValue(QVariant value)
-{
- quaternion = qvariant_cast<QQuaternion>(value);
-}
-
QString QDeclarativeQuaternionValueType::toString() const
{
return QString(QLatin1String("QQuaternion(%1, %2, %3, %4)")).arg(quaternion.scalar()).arg(quaternion.x()).arg(quaternion.y()).arg(quaternion.z());
}
-bool QDeclarativeQuaternionValueType::isEqual(const QVariant &value) const
-{
- return (QVariant(quaternion) == value);
-}
-
qreal QDeclarativeQuaternionValueType::scalar() const
{
return quaternion.scalar();
@@ -838,34 +555,6 @@ void QDeclarativeQuaternionValueType::setZ(qreal z)
quaternion.setZ(z);
}
-QDeclarativeMatrix4x4ValueType::QDeclarativeMatrix4x4ValueType(QObject *parent)
-: QDeclarativeValueType(parent)
-{
-}
-
-void QDeclarativeMatrix4x4ValueType::read(QObject *obj, int idx)
-{
- void *a[] = { &matrix, 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
-}
-
-void QDeclarativeMatrix4x4ValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags)
-{
- int status = -1;
- void *a[] = { &matrix, 0, &status, &flags };
- QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
-}
-
-QVariant QDeclarativeMatrix4x4ValueType::value()
-{
- return QVariant(matrix);
-}
-
-void QDeclarativeMatrix4x4ValueType::setValue(QVariant value)
-{
- matrix = qvariant_cast<QMatrix4x4>(value);
-}
-
QString QDeclarativeMatrix4x4ValueType::toString() const
{
return QString(QLatin1String("QMatrix4x4(%1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11, %12, %13, %14, %15, %16)"))
@@ -875,49 +564,11 @@ QString QDeclarativeMatrix4x4ValueType::toString() const
.arg(matrix(3, 0)).arg(matrix(3, 1)).arg(matrix(3, 2)).arg(matrix(3, 3));
}
-bool QDeclarativeMatrix4x4ValueType::isEqual(const QVariant &value) const
-{
- return (QVariant(matrix) == value);
-}
-
-QDeclarativeEasingValueType::QDeclarativeEasingValueType(QObject *parent)
-: QDeclarativeValueType(parent)
-{
-}
-
-void QDeclarativeEasingValueType::read(QObject *obj, int idx)
-{
- void *a[] = { &easing, 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
-}
-
-void QDeclarativeEasingValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags)
-{
- int status = -1;
- void *a[] = { &easing, 0, &status, &flags };
- QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
-}
-
-QVariant QDeclarativeEasingValueType::value()
-{
- return QVariant(easing);
-}
-
-void QDeclarativeEasingValueType::setValue(QVariant value)
-{
- easing = qvariant_cast<QEasingCurve>(value);
-}
-
QString QDeclarativeEasingValueType::toString() const
{
return QString(QLatin1String("QEasingCurve(%1, %2, %3, %4)")).arg(easing.type()).arg(easing.amplitude()).arg(easing.overshoot()).arg(easing.period());
}
-bool QDeclarativeEasingValueType::isEqual(const QVariant &value) const
-{
- return (QVariant(easing) == value);
-}
-
QDeclarativeEasingValueType::Type QDeclarativeEasingValueType::type() const
{
return (QDeclarativeEasingValueType::Type)easing.type();
@@ -1004,47 +655,17 @@ QVariantList QDeclarativeEasingValueType::bezierCurve() const
return rv;
}
-QDeclarativeFontValueType::QDeclarativeFontValueType(QObject *parent)
-: QDeclarativeValueType(parent), pixelSizeSet(false), pointSizeSet(false)
-{
-}
-
-void QDeclarativeFontValueType::read(QObject *obj, int idx)
+void QDeclarativeFontValueType::onLoad()
{
- void *a[] = { &font, 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
pixelSizeSet = false;
pointSizeSet = false;
}
-void QDeclarativeFontValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags)
-{
- int status = -1;
- void *a[] = { &font, 0, &status, &flags };
- QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
-}
-
-QVariant QDeclarativeFontValueType::value()
-{
- return QVariant(font);
-}
-
-void QDeclarativeFontValueType::setValue(QVariant value)
-{
- font = qvariant_cast<QFont>(value);
-}
-
QString QDeclarativeFontValueType::toString() const
{
return QString(QLatin1String("QFont(%1)")).arg(font.toString());
}
-bool QDeclarativeFontValueType::isEqual(const QVariant &value) const
-{
- return (QVariant(font) == value);
-}
-
-
QString QDeclarativeFontValueType::family() const
{
return font.family();
@@ -1192,45 +813,12 @@ void QDeclarativeFontValueType::setWordSpacing(qreal size)
font.setWordSpacing(size);
}
-QDeclarativeColorValueType::QDeclarativeColorValueType(QObject *parent)
-: QDeclarativeValueType(parent)
-{
-}
-
-void QDeclarativeColorValueType::read(QObject *obj, int idx)
-{
- void *a[] = { &color, 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
-}
-
-void QDeclarativeColorValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags)
-{
- int status = -1;
- void *a[] = { &color, 0, &status, &flags };
- QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
-}
-
-QVariant QDeclarativeColorValueType::value()
-{
- return QVariant(color);
-}
-
-void QDeclarativeColorValueType::setValue(QVariant value)
-{
- color = qvariant_cast<QColor>(value);
-}
-
QString QDeclarativeColorValueType::toString() const
{
// special case - to maintain behaviour with QtQuick 1.0, we just output normal toString() value.
return QVariant(color).toString();
}
-bool QDeclarativeColorValueType::isEqual(const QVariant &value) const
-{
- return (QVariant(color) == value);
-}
-
qreal QDeclarativeColorValueType::r() const
{
return color.redF();
diff --git a/src/declarative/qml/qdeclarativevaluetype_p.h b/src/declarative/qml/qdeclarativevaluetype_p.h
index 9f00d97800..b4c8d7f0a5 100644
--- a/src/declarative/qml/qdeclarativevaluetype_p.h
+++ b/src/declarative/qml/qdeclarativevaluetype_p.h
@@ -79,10 +79,12 @@ public:
virtual void read(QObject *, int) = 0;
virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags flags) = 0;
virtual QVariant value() = 0;
- virtual void setValue(QVariant) = 0;
+ virtual void setValue(const QVariant &) = 0;
virtual QString toString() const = 0;
virtual bool isEqual(const QVariant &value) const = 0;
+
+ inline void onLoad();
};
class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeValueTypeFactory
@@ -117,7 +119,7 @@ public:
virtual void read(QObject *, int);
virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags);
virtual QVariant value();
- virtual void setValue(QVariant value);
+ virtual void setValue(const QVariant &value);
virtual QString toString() const;
virtual bool isEqual(const QVariant &value) const;
@@ -142,7 +144,7 @@ public:
virtual void read(QObject *, int);
virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags);
virtual QVariant value();
- virtual void setValue(QVariant value);
+ virtual void setValue(const QVariant &value);
virtual QString toString() const;
virtual bool isEqual(const QVariant &value) const;
@@ -167,7 +169,7 @@ public:
virtual void read(QObject *, int);
virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags);
virtual QVariant value();
- virtual void setValue(QVariant value);
+ virtual void setValue(const QVariant &value);
virtual QString toString() const;
virtual bool isEqual(const QVariant &value) const;
@@ -192,7 +194,7 @@ public:
virtual void read(QObject *, int);
virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags);
virtual QVariant value();
- virtual void setValue(QVariant value);
+ virtual void setValue(const QVariant &value);
virtual QString toString() const;
virtual bool isEqual(const QVariant &value) const;
@@ -219,7 +221,7 @@ public:
virtual void read(QObject *, int);
virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags);
virtual QVariant value();
- virtual void setValue(QVariant value);
+ virtual void setValue(const QVariant &value);
virtual QString toString() const;
virtual bool isEqual(const QVariant &value) const;
@@ -251,7 +253,7 @@ public:
virtual void read(QObject *, int);
virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags);
virtual QVariant value();
- virtual void setValue(QVariant value);
+ virtual void setValue(const QVariant &value);
virtual QString toString() const;
virtual bool isEqual(const QVariant &value) const;
@@ -280,7 +282,7 @@ public:
virtual void read(QObject *, int);
virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags);
virtual QVariant value();
- virtual void setValue(QVariant value);
+ virtual void setValue(const QVariant &value);
virtual QString toString() const;
virtual bool isEqual(const QVariant &value) const;
@@ -305,7 +307,7 @@ public:
virtual void read(QObject *, int);
virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags);
virtual QVariant value();
- virtual void setValue(QVariant value);
+ virtual void setValue(const QVariant &value);
virtual QString toString() const;
virtual bool isEqual(const QVariant &value) const;
@@ -333,7 +335,7 @@ public:
virtual void read(QObject *, int);
virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags);
virtual QVariant value();
- virtual void setValue(QVariant value);
+ virtual void setValue(const QVariant &value);
virtual QString toString() const;
virtual bool isEqual(const QVariant &value) const;
@@ -363,7 +365,7 @@ public:
virtual void read(QObject *, int);
virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags);
virtual QVariant value();
- virtual void setValue(QVariant value);
+ virtual void setValue(const QVariant &value);
virtual QString toString() const;
virtual bool isEqual(const QVariant &value) const;
@@ -405,7 +407,7 @@ public:
virtual void read(QObject *, int);
virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags);
virtual QVariant value();
- virtual void setValue(QVariant value);
+ virtual void setValue(const QVariant &value);
virtual QString toString() const;
virtual bool isEqual(const QVariant &value) const;
@@ -490,7 +492,7 @@ public:
virtual void read(QObject *, int);
virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags);
virtual QVariant value();
- virtual void setValue(QVariant value);
+ virtual void setValue(const QVariant &value);
virtual QString toString() const;
virtual bool isEqual(const QVariant &value) const;
@@ -546,7 +548,7 @@ public:
virtual void read(QObject *, int);
virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags);
virtual QVariant value();
- virtual void setValue(QVariant value);
+ virtual void setValue(const QVariant &value);
virtual QString toString() const;
virtual bool isEqual(const QVariant &value) const;
@@ -586,6 +588,7 @@ public:
qreal wordSpacing() const;
void setWordSpacing(qreal spacing);
+ void onLoad();
private:
QFont font;
bool pixelSizeSet;
@@ -606,7 +609,7 @@ public:
virtual void read(QObject *, int);
virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags);
virtual QVariant value();
- virtual void setValue(QVariant value);
+ virtual void setValue(const QVariant &value);
virtual QString toString() const;
virtual bool isEqual(const QVariant &value) const;
@@ -623,6 +626,10 @@ private:
QColor color;
};
+void QDeclarativeValueType::onLoad()
+{
+}
+
QT_END_NAMESPACE
#endif // QDECLARATIVEVALUETYPE_P_H
diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp
index 327a0ae6c0..556e2a2b69 100644
--- a/src/declarative/qml/qdeclarativevme.cpp
+++ b/src/declarative/qml/qdeclarativevme.cpp
@@ -199,6 +199,11 @@ static void removeBindingOnProperty(QObject *o, int index)
if (binding) binding->destroy();
}
+static QVariant variantFromString(const QString &string)
+{
+ return QDeclarativeStringConverters::variantFromString(string);
+}
+
// XXX we probably need some form of "work count" here to prevent us checking this
// for every instruction.
#define QML_BEGIN_INSTR_COMMON(I) { \
@@ -237,7 +242,46 @@ static void removeBindingOnProperty(QObject *o, int index)
} break;
#endif
-#define CLEAN_PROPERTY(o, index) if (fastHasBinding(o, index)) removeBindingOnProperty(o, index)
+#define QML_STORE_VALUE(name, cpptype, value) \
+ QML_BEGIN_INSTR(name) \
+ cpptype v = value; \
+ void *a[] = { (void *)&v, 0, &status, &flags }; \
+ QObject *target = objects.top(); \
+ CLEAN_PROPERTY(target, instr.propertyIndex); \
+ QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.propertyIndex, a); \
+ QML_END_INSTR(name)
+
+#define QML_STORE_LIST(name, cpptype, value) \
+ QML_BEGIN_INSTR(name) \
+ cpptype v; \
+ v.append(value); \
+ void *a[] = { (void *)&v, 0, &status, &flags }; \
+ QObject *target = objects.top(); \
+ CLEAN_PROPERTY(target, instr.propertyIndex); \
+ QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.propertyIndex, a); \
+ QML_END_INSTR(name)
+
+#define QML_STORE_VAR(name, value) \
+ QML_BEGIN_INSTR(name) \
+ v8::Handle<v8::Value> v8value = value; \
+ QObject *target = objects.top(); \
+ CLEAN_PROPERTY(target, instr.propertyIndex); \
+ QMetaObject *mo = const_cast<QMetaObject *>(target->metaObject()); \
+ QDeclarativeVMEMetaObject *vmemo = static_cast<QDeclarativeVMEMetaObject *>(mo); \
+ vmemo->setVMEProperty(instr.propertyIndex, v8value); \
+ QML_END_INSTR(name)
+
+#define QML_STORE_POINTER(name, value) \
+ QML_BEGIN_INSTR(name) \
+ void *a[] = { (void *)value, 0, &status, &flags }; \
+ QObject *target = objects.top(); \
+ CLEAN_PROPERTY(target, instr.propertyIndex); \
+ QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.propertyIndex, a); \
+ QML_END_INSTR(name)
+
+#define CLEAN_PROPERTY(o, index) \
+ if (fastHasBinding(o, index)) \
+ removeBindingOnProperty(o, index)
QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors,
const Interrupt &interrupt
@@ -294,6 +338,55 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors,
switch (genericInstr->common.instructionType) {
#endif
+
+ // Store a created object in a property. These all pop from the objects stack.
+ QML_STORE_VALUE(StoreObject, QObject *, objects.pop());
+ QML_STORE_VALUE(StoreVariantObject, QVariant, QVariant::fromValue(objects.pop()));
+ QML_STORE_VAR(StoreVarObject, ep->v8engine()->newQObject(objects.pop()));
+
+ // Store a literal value in a corresponding property
+ QML_STORE_VALUE(StoreFloat, float, instr.value);
+ QML_STORE_VALUE(StoreDouble, double, instr.value);
+ QML_STORE_VALUE(StoreBool, bool, instr.value);
+ QML_STORE_VALUE(StoreInteger, int, instr.value);
+ QML_STORE_VALUE(StoreColor, QColor, QColor::fromRgba(instr.value));
+ QML_STORE_VALUE(StoreDate, QDate, QDate::fromJulianDay(instr.value));
+ QML_STORE_VALUE(StoreDateTime, QDateTime,
+ QDateTime(QDate::fromJulianDay(instr.date), *(QTime *)&instr.time));
+ QML_STORE_POINTER(StoreTime, (QTime *)&instr.time);
+ QML_STORE_POINTER(StorePoint, (QPoint *)&instr.point);
+ QML_STORE_POINTER(StorePointF, (QPointF *)&instr.point);
+ QML_STORE_POINTER(StoreSize, (QSize *)&instr.size);
+ QML_STORE_POINTER(StoreSizeF, (QSizeF *)&instr.size);
+ QML_STORE_POINTER(StoreRect, (QRect *)&instr.rect);
+ QML_STORE_POINTER(StoreRectF, (QRectF *)&instr.rect);
+ QML_STORE_POINTER(StoreVector3D, (QVector3D *)&instr.vector);
+ QML_STORE_POINTER(StoreVector4D, (QVector4D *)&instr.vector);
+ QML_STORE_POINTER(StoreString, &PRIMITIVES.at(instr.value));
+ QML_STORE_POINTER(StoreByteArray, &DATAS.at(instr.value));
+ QML_STORE_POINTER(StoreUrl, &URLS.at(instr.value));
+
+ // Store a literal value in a QList
+ QML_STORE_LIST(StoreStringList, QStringList, PRIMITIVES.at(instr.value));
+ QML_STORE_LIST(StoreStringQList, QList<QString>, PRIMITIVES.at(instr.value));
+ QML_STORE_LIST(StoreUrlQList, QList<QUrl>, URLS.at(instr.value));
+ QML_STORE_LIST(StoreDoubleQList, QList<double>, instr.value);
+ QML_STORE_LIST(StoreBoolQList, QList<bool>, instr.value);
+ QML_STORE_LIST(StoreIntegerQList, QList<int>, instr.value);
+
+ // Store a literal value in a QVariant property
+ QML_STORE_VALUE(StoreVariant, QVariant, variantFromString(PRIMITIVES.at(instr.value)));
+ QML_STORE_VALUE(StoreVariantInteger, QVariant, QVariant(instr.value));
+ QML_STORE_VALUE(StoreVariantDouble, QVariant, QVariant(instr.value));
+ QML_STORE_VALUE(StoreVariantBool, QVariant, QVariant(instr.value));
+
+ // Store a literal value in a var property.
+ // We deliberately do not use string converters here
+ QML_STORE_VAR(StoreVar, ep->v8engine()->fromVariant(PRIMITIVES.at(instr.value)));
+ QML_STORE_VAR(StoreVarInteger, v8::Integer::New(instr.value));
+ QML_STORE_VAR(StoreVarDouble, v8::Number::New(instr.value));
+ QML_STORE_VAR(StoreVarBool, v8::Boolean::New(instr.value));
+
QML_BEGIN_INSTR(Init)
// Ensure that the compiled data has been initialized
if (!COMP->isInitialized()) COMP->initialize(engine);
@@ -540,341 +633,6 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors,
}
QML_END_INSTR(StoreMetaObject)
- QML_BEGIN_INSTR(StoreVariant)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- // XXX - can be more efficient
- QVariant v = QDeclarativeStringConverters::variantFromString(PRIMITIVES.at(instr.value));
- void *a[] = { &v, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreVariant)
-
- QML_BEGIN_INSTR(StoreVariantInteger)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QVariant v(instr.value);
- void *a[] = { &v, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreVariantInteger)
-
- QML_BEGIN_INSTR(StoreVariantDouble)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QVariant v(instr.value);
- void *a[] = { &v, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreVariantDouble)
-
- QML_BEGIN_INSTR(StoreVariantBool)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QVariant v(instr.value);
- void *a[] = { &v, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreVariantBool)
-
- QML_BEGIN_INSTR(StoreVar)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- // Note that we don't use QDeclarativeStringConverters::variantFromString() here, which
- // means that automatic generation of value types from strings doesn't occur.
- // This is a deliberate behaviour difference to variant properties.
- v8::Handle<v8::Value> v8Value = ep->v8engine()->fromVariant(PRIMITIVES.at(instr.value));
- static_cast<QDeclarativeVMEMetaObject *>(const_cast<QMetaObject *>(target->metaObject()))->setVMEProperty(instr.propertyIndex, v8Value);
- QML_END_INSTR(StoreVar)
-
- QML_BEGIN_INSTR(StoreVarInteger)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- v8::Handle<v8::Value> v8Value = v8::Integer::New(instr.value);
- static_cast<QDeclarativeVMEMetaObject *>(const_cast<QMetaObject *>(target->metaObject()))->setVMEProperty(instr.propertyIndex, v8Value);
- QML_END_INSTR(StoreVarInteger)
-
- QML_BEGIN_INSTR(StoreVarDouble)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- v8::Handle<v8::Value> v8Value = v8::Number::New(instr.value);
- static_cast<QDeclarativeVMEMetaObject *>(const_cast<QMetaObject *>(target->metaObject()))->setVMEProperty(instr.propertyIndex, v8Value);
- QML_END_INSTR(StoreVarDouble)
-
- QML_BEGIN_INSTR(StoreVarBool)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- v8::Handle<v8::Value> v8Value = v8::Boolean::New(instr.value);
- static_cast<QDeclarativeVMEMetaObject *>(const_cast<QMetaObject *>(target->metaObject()))->setVMEProperty(instr.propertyIndex, v8Value);
- QML_END_INSTR(StoreVarBool)
-
- QML_BEGIN_INSTR(StoreString)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- void *a[] = { (void *)&PRIMITIVES.at(instr.value), 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreString)
-
- QML_BEGIN_INSTR(StoreStringList)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QStringList stringlist(PRIMITIVES.at(instr.value));
- void *a[] = { (void *)&stringlist, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreStringList)
-
- QML_BEGIN_INSTR(StoreStringQList)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QList<QString> stringqlist;
- stringqlist.append(PRIMITIVES.at(instr.value));
- void *a[] = { (void *)&stringqlist, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreStringQList)
-
- QML_BEGIN_INSTR(StoreByteArray)
- QObject *target = objects.top();
- void *a[] = { (void *)&DATAS.at(instr.value), 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreByteArray)
-
- QML_BEGIN_INSTR(StoreUrl)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- void *a[] = { (void *)&URLS.at(instr.value), 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreUrl)
-
- QML_BEGIN_INSTR(StoreUrlQList)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QList<QUrl> urlqlist;
- urlqlist.append(URLS.at(instr.value));
- void *a[] = { (void *)&urlqlist, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreUrlQList)
-
- QML_BEGIN_INSTR(StoreFloat)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- float f = instr.value;
- void *a[] = { &f, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreFloat)
-
- QML_BEGIN_INSTR(StoreDouble)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- double d = instr.value;
- void *a[] = { &d, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreDouble)
-
- QML_BEGIN_INSTR(StoreDoubleQList)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QList<double> doubleqlist;
- doubleqlist.append(instr.value);
- void *a[] = { (void *)&doubleqlist, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreDoubleQList)
-
- QML_BEGIN_INSTR(StoreBool)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- void *a[] = { (void *)&instr.value, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreBool)
-
- QML_BEGIN_INSTR(StoreBoolQList)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QList<bool> boolqlist;
- boolqlist.append(instr.value);
- void *a[] = { (void *)&boolqlist, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreBoolQList)
-
- QML_BEGIN_INSTR(StoreInteger)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- void *a[] = { (void *)&instr.value, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreInteger)
-
- QML_BEGIN_INSTR(StoreIntegerQList)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QList<int> intqlist;
- intqlist.append(instr.value);
- void *a[] = { (void *)&intqlist, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreIntegerQList)
-
- QML_BEGIN_INSTR(StoreColor)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QColor c = QColor::fromRgba(instr.value);
- void *a[] = { &c, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreColor)
-
- QML_BEGIN_INSTR(StoreDate)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QDate d = QDate::fromJulianDay(instr.value);
- void *a[] = { &d, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreDate)
-
- QML_BEGIN_INSTR(StoreTime)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QTime *t = (QTime *)&instr.time;
- void *a[] = { t, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreTime)
-
- QML_BEGIN_INSTR(StoreDateTime)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QTime *t = (QTime *)&instr.time;
- QDateTime dt(QDate::fromJulianDay(instr.date), *t);
- void *a[] = { &dt, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreDateTime)
-
- QML_BEGIN_INSTR(StorePoint)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QPoint *p = (QPoint *)&instr.point;
- void *a[] = { p, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StorePoint)
-
- QML_BEGIN_INSTR(StorePointF)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QPointF *p = (QPointF *)&instr.point;
- void *a[] = { p, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StorePointF)
-
- QML_BEGIN_INSTR(StoreSize)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QSize *s = (QSize *)&instr.size;
- void *a[] = { s, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreSize)
-
- QML_BEGIN_INSTR(StoreSizeF)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QSizeF *s = (QSizeF *)&instr.size;
- void *a[] = { s, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreSizeF)
-
- QML_BEGIN_INSTR(StoreRect)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QRect *r = (QRect *)&instr.rect;
- void *a[] = { r, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreRect)
-
- QML_BEGIN_INSTR(StoreRectF)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QRectF *r = (QRectF *)&instr.rect;
- void *a[] = { r, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreRectF)
-
- QML_BEGIN_INSTR(StoreVector3D)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QVector3D *v = (QVector3D *)&instr.vector;
- void *a[] = { v, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreVector3D)
-
- QML_BEGIN_INSTR(StoreVector4D)
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QVector4D *v = (QVector4D *)&instr.vector;
- void *a[] = { v, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreVector4D)
-
- QML_BEGIN_INSTR(StoreObject)
- QObject *assignObj = objects.pop();
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- void *a[] = { (void *)&assignObj, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreObject)
-
QML_BEGIN_INSTR(AssignCustomType)
QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
@@ -972,21 +730,16 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors,
QObject *context =
objects.at(objects.count() - 1 - instr.context);
- QDeclarativeProperty mp =
- QDeclarativePropertyPrivate::restore(instr.property, target, CTXT);
-
- int coreIndex = mp.index();
-
- if (instr.isRoot && BINDINGSKIPLIST.testBit(coreIndex))
+ if (instr.isRoot && BINDINGSKIPLIST.testBit(instr.property.coreIndex))
QML_NEXT_INSTR(StoreBinding);
QDeclarativeBinding *bind = new QDeclarativeBinding(PRIMITIVES.at(instr.value), true,
context, CTXT, COMP->name, instr.line);
bindValues.push(bind);
bind->m_mePtr = &bindValues.top();
- bind->setTarget(mp);
+ bind->setTarget(target, instr.property, CTXT);
- bind->addToObject(target, QDeclarativePropertyPrivate::bindingIndex(mp));
+ bind->addToObject(target, QDeclarativePropertyPrivate::bindingIndex(instr.property));
QML_END_INSTR(StoreBinding)
QML_BEGIN_INSTR(StoreBindingOnAlias)
@@ -995,21 +748,19 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors,
QObject *context =
objects.at(objects.count() - 1 - instr.context);
- QDeclarativeProperty mp =
- QDeclarativePropertyPrivate::restore(instr.property, target, CTXT);
-
- int coreIndex = mp.index();
-
- if (instr.isRoot && BINDINGSKIPLIST.testBit(coreIndex))
+ if (instr.isRoot && BINDINGSKIPLIST.testBit(instr.property.coreIndex))
QML_NEXT_INSTR(StoreBindingOnAlias);
QDeclarativeBinding *bind = new QDeclarativeBinding(PRIMITIVES.at(instr.value), true,
context, CTXT, COMP->name, instr.line);
bindValues.push(bind);
bind->m_mePtr = &bindValues.top();
- bind->setTarget(mp);
+ bind->setTarget(target, instr.property, CTXT);
- QDeclarativeAbstractBinding *old = QDeclarativePropertyPrivate::setBindingNoEnable(target, coreIndex, QDeclarativePropertyPrivate::valueTypeCoreIndex(mp), bind);
+ QDeclarativeAbstractBinding *old =
+ QDeclarativePropertyPrivate::setBindingNoEnable(target, instr.property.coreIndex,
+ instr.property.getValueTypeCoreIndex(),
+ bind);
if (old) { old->destroy(); }
QML_END_INSTR(StoreBindingOnAlias)
@@ -1052,10 +803,8 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors,
QDeclarativePropertyValueSource *vs = reinterpret_cast<QDeclarativePropertyValueSource *>(reinterpret_cast<char *>(obj) + instr.castValue);
QObject *target = objects.at(objects.count() - 1 - instr.owner);
- QDeclarativeProperty prop =
- QDeclarativePropertyPrivate::restore(instr.property, target, CTXT);
obj->setParent(target);
- vs->setTarget(prop);
+ vs->setTarget(QDeclarativePropertyPrivate::restore(target, instr.property, CTXT));
QML_END_INSTR(StoreValueSource)
QML_BEGIN_INSTR(StoreValueInterceptor)
@@ -1063,7 +812,7 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors,
QDeclarativePropertyValueInterceptor *vi = reinterpret_cast<QDeclarativePropertyValueInterceptor *>(reinterpret_cast<char *>(obj) + instr.castValue);
QObject *target = objects.at(objects.count() - 1 - instr.owner);
QDeclarativeProperty prop =
- QDeclarativePropertyPrivate::restore(instr.property, target, CTXT);
+ QDeclarativePropertyPrivate::restore(target, instr.property, CTXT);
obj->setParent(target);
vi->setTarget(prop);
QDeclarativeVMEMetaObject *mo = static_cast<QDeclarativeVMEMetaObject *>((QMetaObject*)target->metaObject());
@@ -1096,26 +845,6 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors,
list.qListProperty.append((QDeclarativeListProperty<void>*)&list.qListProperty, ptr);
QML_END_INSTR(AssignObjectList)
- QML_BEGIN_INSTR(StoreVariantObject)
- QObject *assign = objects.pop();
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- QVariant v = QVariant::fromValue(assign);
- void *a[] = { &v, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.propertyIndex, a);
- QML_END_INSTR(StoreVariantObject)
-
- QML_BEGIN_INSTR(StoreVarObject)
- QObject *assign = objects.pop();
- QObject *target = objects.top();
- CLEAN_PROPERTY(target, instr.propertyIndex);
-
- v8::Handle<v8::Value> v8Value = ep->v8engine()->newQObject(assign);
- static_cast<QDeclarativeVMEMetaObject *>(const_cast<QMetaObject *>(target->metaObject()))->setVMEProperty(instr.propertyIndex, v8Value);
- QML_END_INSTR(StoreVarObject)
-
QML_BEGIN_INSTR(StoreInterface)
QObject *assign = objects.pop();
QObject *target = objects.top();
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 8508e24e10..890eadf2e1 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -29,7 +29,7 @@ SOURCES += \
$$PWD/qdeclarativescript.cpp \
$$PWD/qdeclarativerewrite.cpp \
$$PWD/qdeclarativevaluetype.cpp \
- $$PWD/qdeclarativefastproperties.cpp \
+ $$PWD/qdeclarativeaccessors.cpp \
$$PWD/qdeclarativexmlhttprequest.cpp \
$$PWD/qdeclarativesqldatabase.cpp \
$$PWD/qdeclarativewatcher.cpp \
@@ -95,7 +95,7 @@ HEADERS += \
$$PWD/qdeclarativescript_p.h \
$$PWD/qdeclarativerewrite_p.h \
$$PWD/qdeclarativevaluetype_p.h \
- $$PWD/qdeclarativefastproperties_p.h \
+ $$PWD/qdeclarativeaccessors_p.h \
$$PWD/qdeclarativexmlhttprequest_p.h \
$$PWD/qdeclarativesqldatabase_p.h \
$$PWD/qdeclarativewatcher_p.h \
diff --git a/src/declarative/qml/v4/qv4bindings.cpp b/src/declarative/qml/v4/qv4bindings.cpp
index 835b7e7752..2dc812f47b 100644
--- a/src/declarative/qml/v4/qv4bindings.cpp
+++ b/src/declarative/qml/v4/qv4bindings.cpp
@@ -46,7 +46,7 @@
#include "qv4compiler_p.h"
#include "qv4compiler_p_p.h"
-#include <private/qdeclarativefastproperties_p.h>
+#include <private/qdeclarativeaccessors_p.h>
#include <private/qdeclarativedebugtrace_p.h>
#include <private/qdeclarativemetatype_p.h>
@@ -760,7 +760,17 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
reg.init((Register::Type)instr->fetchAndSubscribe.valueType);
if (instr->fetchAndSubscribe.valueType >= FirstCleanupType)
MARK_REGISTER(instr->fetchAndSubscribe.reg);
- QDeclarativeFastProperties::instance()->accessor(instr->fetchAndSubscribe.function)(object, reg.typeDataPtr(), sub);
+ QDeclarativeAccessors *accessors = instr->fetchAndSubscribe.property.accessors;
+ accessors->read(object, instr->fetchAndSubscribe.property.accessorData,
+ reg.typeDataPtr());
+
+ if (accessors->notifier) {
+ QDeclarativeNotifier *notifier = 0;
+ accessors->notifier(object, instr->fetchAndSubscribe.property.accessorData, &notifier);
+ if (notifier) sub->connect(notifier);
+ } else if (instr->fetchAndSubscribe.property.notifyIndex != -1) {
+ sub->connect(object, instr->fetchAndSubscribe.property.notifyIndex);
+ }
}
}
QML_V4_END_INSTR(FetchAndSubscribe, fetchAndSubscribe)
diff --git a/src/declarative/qml/v4/qv4compiler.cpp b/src/declarative/qml/v4/qv4compiler.cpp
index 1d6cd30a99..e091ce2731 100644
--- a/src/declarative/qml/v4/qv4compiler.cpp
+++ b/src/declarative/qml/v4/qv4compiler.cpp
@@ -46,7 +46,7 @@
#include "qv4irbuilder_p.h"
#include <private/qdeclarativejsast_p.h>
-#include <private/qdeclarativefastproperties_p.h>
+#include <private/qdeclarativeaccessors_p.h>
#include <private/qdeclarativejsengine_p.h>
QT_BEGIN_NAMESPACE
@@ -323,7 +323,6 @@ void QV4CompilerPrivate::visitName(IR::Name *e)
QMetaProperty prop;
e->property->load(prop, QDeclarativeEnginePrivate::get(engine));
}
- int fastFetchIndex = QDeclarativeFastProperties::instance()->accessorIndexForProperty(e->meta, e->property->coreIndex);
const int propTy = e->property->propType;
QDeclarativeRegisterType regType;
@@ -359,13 +358,13 @@ void QV4CompilerPrivate::visitName(IR::Name *e)
break;
} // switch
- if (fastFetchIndex != -1) {
+ if (e->property->hasAccessors()) {
Instr::FetchAndSubscribe fetch;
fetch.reg = currentReg;
- fetch.function = fastFetchIndex;
fetch.subscription = subscriptionIndex(_subscribeName);
fetch.exceptionId = exceptionId(e->line, e->column);
fetch.valueType = regType;
+ fetch.property = *e->property;
gen(fetch);
} else {
if (blockNeedsSubscription(_subscribeName) && e->property->notifyIndex != -1) {
diff --git a/src/declarative/qml/v4/qv4instruction.cpp b/src/declarative/qml/v4/qv4instruction.cpp
index 411e96b137..ccf91d567b 100644
--- a/src/declarative/qml/v4/qv4instruction.cpp
+++ b/src/declarative/qml/v4/qv4instruction.cpp
@@ -103,7 +103,7 @@ void Bytecode::dump(const V4Instr *i, int address) const
INSTR_DUMP << "\t" << "SubscribeId" << "\t\t" << "Id_Offset(" << i->subscribeop.index << ") -> Subscribe_Slot(" << i->subscribeop.offset << ")";
break;
case V4Instr::FetchAndSubscribe:
- INSTR_DUMP << "\t" << "FetchAndSubscribe" << "\t" << "Object_Reg(" << i->fetchAndSubscribe.reg << ") Fast_Accessor(" << i->fetchAndSubscribe.function << ") -> Output_Reg(" << i->fetchAndSubscribe.reg << ") Subscription_Slot(" << i->fetchAndSubscribe.subscription << ")";
+ INSTR_DUMP << "\t" << "FetchAndSubscribe" << "\t" << "Object_Reg(" << i->fetchAndSubscribe.reg << ") Fast_Accessor(" << i->fetchAndSubscribe.property.accessors << ") -> Output_Reg(" << i->fetchAndSubscribe.reg << ") Subscription_Slot(" << i->fetchAndSubscribe.subscription << ")";
break;
case V4Instr::LoadId:
INSTR_DUMP << "\t" << "LoadId" << "\t\t\t" << "Id_Offset(" << i->load.index << ") -> Output_Reg(" << i->load.reg << ")";
diff --git a/src/declarative/qml/v4/qv4instruction_p.h b/src/declarative/qml/v4/qv4instruction_p.h
index 343df809b4..6f90117c7c 100644
--- a/src/declarative/qml/v4/qv4instruction_p.h
+++ b/src/declarative/qml/v4/qv4instruction_p.h
@@ -58,6 +58,8 @@
#include <QtCore/qvector.h>
#include <QtCore/qvarlengtharray.h>
+#include <private/qdeclarativepropertycache_p.h>
+
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
@@ -166,6 +168,9 @@ QT_BEGIN_NAMESPACE
# define QML_V4_INSTR_HEADER quint8 type;
#endif
+class QObject;
+class QDeclarativeNotifier;
+
namespace QDeclarativeJS {
union V4Instr {
@@ -232,7 +237,7 @@ union V4Instr {
quint8 exceptionId;
quint8 valueType;
quint16 subscription;
- quint16 function;
+ QDeclarativePropertyRawData property;
};
struct instr_fetch{
diff --git a/src/declarative/qml/v8/qv8bindings.cpp b/src/declarative/qml/v8/qv8bindings.cpp
index 271267d851..3386c5ddc8 100644
--- a/src/declarative/qml/v8/qv8bindings.cpp
+++ b/src/declarative/qml/v8/qv8bindings.cpp
@@ -122,7 +122,7 @@ void QV8Bindings::Binding::update(QDeclarativePropertyPrivate::WriteFlags flags)
ep->dereferenceScarceResources();
} else {
- QDeclarativeProperty p = QDeclarativePropertyPrivate::restore(property, object, context);
+ QDeclarativeProperty p = QDeclarativePropertyPrivate::restore(object, property, context);
QDeclarativeBindingPrivate::printBindingLoopError(p);
}
}
diff --git a/src/declarative/qml/v8/qv8qobjectwrapper.cpp b/src/declarative/qml/v8/qv8qobjectwrapper.cpp
index 6a9f583b0f..40ad93a544 100644
--- a/src/declarative/qml/v8/qv8qobjectwrapper.cpp
+++ b/src/declarative/qml/v8/qv8qobjectwrapper.cpp
@@ -50,6 +50,7 @@
#include <private/qdeclarativebinding_p.h>
#include <private/qjsvalue_p.h>
#include <private/qscript_impl_p.h>
+#include <private/qdeclarativeaccessors_p.h>
#include <QtDeclarative/qjsvalue.h>
#include <QtCore/qvarlengtharray.h>
@@ -131,9 +132,9 @@ public:
static const size_t Size = SMax<A, SMax<B, SMax<C, SMax<D, E> > > >::Size;
};
-struct MetaCallArgument {
- inline MetaCallArgument();
- inline ~MetaCallArgument();
+struct CallArgument {
+ inline CallArgument();
+ inline ~CallArgument();
inline void *dataPtr();
inline void initAsType(int type);
@@ -141,7 +142,7 @@ struct MetaCallArgument {
inline v8::Handle<v8::Value> toValue(QV8Engine *);
private:
- MetaCallArgument(const MetaCallArgument &);
+ CallArgument(const CallArgument &);
inline void cleanup();
@@ -213,65 +214,90 @@ void QV8QObjectWrapper::destroy()
qPersistentDispose(m_constructor);
}
-#define FAST_VALUE_GETTER(name, cpptype, defaultvalue, constructor) \
-static v8::Handle<v8::Value> name ## ValueGetter(v8::Local<v8::String>, const v8::AccessorInfo &info) \
-{ \
- v8::Handle<v8::Object> This = info.This(); \
- QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(This); \
- \
- if (resource->object.isNull()) return v8::Undefined(); \
- \
- QObject *object = resource->object; \
- \
- uint32_t data = info.Data()->Uint32Value(); \
- int index = data & 0x7FFF; \
- int notify = (data & 0x0FFF0000) >> 16; \
- if (notify == 0x0FFF) notify = -1; \
- \
- QDeclarativeEnginePrivate *ep = resource->engine->engine()?QDeclarativeEnginePrivate::get(resource->engine->engine()):0; \
- if (ep && notify /* 0 means constant */ ) \
- ep->captureProperty(object, index, notify); \
- \
- cpptype value = defaultvalue; \
- void *args[] = { &value, 0 }; \
- QMetaObject::metacall(object, QMetaObject::ReadProperty, index, args); \
- \
- return constructor(value); \
-} \
-static v8::Handle<v8::Value> name ## ValueGetterDirect(v8::Local<v8::String>, const v8::AccessorInfo &info) \
-{ \
- v8::Handle<v8::Object> This = info.This(); \
- QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(This); \
- \
- if (resource->object.isNull()) return v8::Undefined(); \
- \
- QObject *object = resource->object; \
- \
- uint32_t data = info.Data()->Uint32Value(); \
- int index = data & 0x7FFF; \
- int notify = (data & 0x0FFF0000) >> 16; \
- if (notify == 0x0FFF) notify = -1; \
- \
- QDeclarativeEnginePrivate *ep = resource->engine->engine()?QDeclarativeEnginePrivate::get(resource->engine->engine()):0; \
- if (ep && notify /* 0 means constant */ ) \
- ep->captureProperty(object, index, notify); \
- \
- cpptype value = defaultvalue; \
- void *args[] = { &value, 0 }; \
- object->qt_metacall(QMetaObject::ReadProperty, index, args); \
- \
- return constructor(value); \
-}
-
-#define CREATE_FUNCTION \
- "(function(method) { "\
- "return (function(object, data, qmlglobal) { "\
- "return (function() { "\
- "return method(object, data, qmlglobal, arguments.length, arguments); "\
- "});"\
- "});"\
- "})"
+struct ReadAccessor {
+ static inline void Indirect(QObject *object, const QDeclarativePropertyData &property,
+ void *output, QDeclarativeNotifier **n)
+ {
+ Q_ASSERT(n == 0);
+ Q_UNUSED(n);
+
+ void *args[] = { output, 0 };
+ QMetaObject::metacall(object, QMetaObject::ReadProperty, property.coreIndex, args);
+ }
+ static inline void Direct(QObject *object, const QDeclarativePropertyData &property,
+ void *output, QDeclarativeNotifier **n)
+ {
+ Q_ASSERT(n == 0);
+ Q_UNUSED(n);
+
+ void *args[] = { output, 0 };
+ object->qt_metacall(QMetaObject::ReadProperty, property.coreIndex, args);
+ }
+
+ static inline void Accessor(QObject *object, const QDeclarativePropertyData &property,
+ void *output, QDeclarativeNotifier **n)
+ {
+ Q_ASSERT(property.accessors);
+
+ property.accessors->read(object, property.accessorData, output);
+ if (n) property.accessors->notifier(object, property.accessorData, n);
+ }
+};
+
+static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *, int v)
+{ return v8::Integer::New(v); }
+static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *, uint v)
+{ return v8::Integer::NewFromUnsigned(v); }
+static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *, bool v)
+{ return v8::Boolean::New(v); }
+static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *e, const QString &v)
+{ return e->toString(v); }
+static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *, float v)
+{ return v8::Number::New(v); }
+static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *, double v)
+{ return v8::Number::New(v); }
+static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *e, QObject *v)
+{ return e->newQObject(v); }
+
+template<typename T, void (*ReadFunction)(QObject *, const QDeclarativePropertyData &,
+ void *, QDeclarativeNotifier **)>
+static v8::Handle<v8::Value> GenericValueGetter(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ v8::Handle<v8::Object> This = info.This();
+ QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(This);
+
+ QObject *object = resource->object;
+ if (!object) return v8::Undefined();
+
+ QDeclarativePropertyData *property =
+ (QDeclarativePropertyData *)v8::External::Unwrap(info.Data());
+
+ QDeclarativeEngine *engine = resource->engine->engine();
+ QDeclarativeEnginePrivate *ep = engine?QDeclarativeEnginePrivate::get(engine):0;
+
+ T value = T();
+
+ if (ep && ep->propertyCapture) {
+ if (ReadFunction == ReadAccessor::Accessor && property->accessors->notifier) {
+ QDeclarativeNotifier *notifier = 0;
+ ReadFunction(object, *property, &value, &notifier);
+ if (notifier) ep->captureProperty(notifier);
+ } else if (!property->isConstant()) {
+ ep->captureProperty(object, property->coreIndex, property->notifyIndex);
+ ReadFunction(object, *property, &value, 0);
+ } else {
+ ReadFunction(object, *property, &value, 0);
+ }
+ } else {
+ ReadFunction(object, *property, &value, 0);
+ }
+
+ return valueToHandle(resource->engine, value);
+}
+
+#define FAST_GETTER_FUNCTION(property, cpptype) \
+ (property->hasAccessors()?((v8::AccessorGetter)GenericValueGetter<cpptype, &ReadAccessor::Accessor>):(property->isDirect()?((v8::AccessorGetter)GenericValueGetter<cpptype, &ReadAccessor::Direct>):((v8::AccessorGetter)GenericValueGetter<cpptype, &ReadAccessor::Indirect>)))
static quint32 toStringHash = -1;
static quint32 destroyHash = -1;
@@ -298,8 +324,17 @@ void QV8QObjectWrapper::init(QV8Engine *engine)
}
{
v8::ScriptOrigin origin(m_hiddenObject); // Hack to allow us to identify these functions
- v8::Local<v8::Script> script = v8::Script::New(v8::String::New(CREATE_FUNCTION), &origin, 0,
+#define CREATE_FUNCTION_SOURCE \
+ "(function(method) { "\
+ "return (function(object, data, qmlglobal) { "\
+ "return (function() { "\
+ "return method(object, data, qmlglobal, arguments.length, arguments); "\
+ "});"\
+ "});"\
+ "})"
+ v8::Local<v8::Script> script = v8::Script::New(v8::String::New(CREATE_FUNCTION_SOURCE), &origin, 0,
v8::Handle<v8::String>(), v8::Script::NativeMode);
+#undef CREATE_FUNCTION_SOURCE
v8::Local<v8::Function> fn = v8::Local<v8::Function>::Cast(script->Run());
v8::Handle<v8::Value> invokeFn = v8::FunctionTemplate::New(Invoke)->GetFunction();
v8::Handle<v8::Value> args[] = { invokeFn };
@@ -344,107 +379,85 @@ QObject *QV8QObjectWrapper::toQObject(QV8ObjectResource *r)
}
// Load value properties
-static v8::Handle<v8::Value> LoadProperty(QV8Engine *engine, QObject *object,
- const QDeclarativePropertyData &property)
+template<void (*ReadFunction)(QObject *, const QDeclarativePropertyData &,
+ void *, QDeclarativeNotifier **)>
+static v8::Handle<v8::Value> LoadProperty(QV8Engine *engine, QObject *object,
+ const QDeclarativePropertyData &property,
+ QDeclarativeNotifier **notifier)
{
Q_ASSERT(!property.isFunction());
-#define PROPERTY_LOAD(metatype, cpptype, constructor) \
- if (property.propType == QMetaType:: metatype) { \
- cpptype type = cpptype(); \
- void *args[] = { &type, 0 }; \
- QMetaObject::metacall(object, QMetaObject::ReadProperty, property.coreIndex, args); \
- return constructor(type); \
- }
-
if (property.isQObject()) {
QObject *rv = 0;
- void *args[] = { &rv, 0 };
- QMetaObject::metacall(object, QMetaObject::ReadProperty, property.coreIndex, args);
+ ReadFunction(object, property, &rv, notifier);
return engine->newQObject(rv);
} else if (property.isQList()) {
return engine->listWrapper()->newList(object, property.coreIndex, property.propType);
- } else PROPERTY_LOAD(QReal, qreal, v8::Number::New)
- else PROPERTY_LOAD(Int || property.isEnum(), int, v8::Integer::New)
- else PROPERTY_LOAD(Bool, bool, v8::Boolean::New)
- else PROPERTY_LOAD(QString, QString, engine->toString)
- else PROPERTY_LOAD(UInt, uint, v8::Integer::NewFromUnsigned)
- else PROPERTY_LOAD(Float, float, v8::Number::New)
- else PROPERTY_LOAD(Double, double, v8::Number::New)
- else if(property.isV8Handle()) {
+ } else if (property.propType == QMetaType::QReal) {
+ qreal v = 0;
+ ReadFunction(object, property, &v, notifier);
+ return valueToHandle(engine, v);
+ } else if (property.propType == QMetaType::Int || property.isEnum()) {
+ int v = 0;
+ ReadFunction(object, property, &v, notifier);
+ return valueToHandle(engine, v);
+ } else if (property.propType == QMetaType::Bool) {
+ bool v = false;
+ ReadFunction(object, property, &v, notifier);
+ return valueToHandle(engine, v);
+ } else if (property.propType == QMetaType::QString) {
+ QString v;
+ ReadFunction(object, property, &v, notifier);
+ return valueToHandle(engine, v);
+ } else if (property.propType == QMetaType::UInt) {
+ uint v = 0;
+ ReadFunction(object, property, &v, notifier);
+ return valueToHandle(engine, v);
+ } else if (property.propType == QMetaType::Float) {
+ float v = 0;
+ ReadFunction(object, property, &v, notifier);
+ return valueToHandle(engine, v);
+ } else if (property.propType == QMetaType::Double) {
+ double v = 0;
+ ReadFunction(object, property, &v, notifier);
+ return valueToHandle(engine, v);
+ } else if (property.isV8Handle()) {
QDeclarativeV8Handle handle;
- void *args[] = { &handle, 0 };
- QMetaObject::metacall(object, QMetaObject::ReadProperty, property.coreIndex, args);
+ ReadFunction(object, property, &handle, notifier);
return handle.toHandle();
+ } else if (property.isQVariant()) {
+ QVariant v;
+ ReadFunction(object, property, &v, notifier);
+ return engine->fromVariant(v);
} else if (QDeclarativeValueTypeFactory::isValueType((uint)property.propType)
&& engine->engine()) {
+ Q_ASSERT(notifier == 0);
+
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine->engine());
QDeclarativeValueType *valueType = ep->valueTypes[property.propType];
if (valueType)
return engine->newValueType(object, property.coreIndex, valueType);
} else {
+ Q_ASSERT(notifier == 0);
+
// see if it's a sequence type
bool succeeded = false;
- v8::Handle<v8::Value> retn = engine->newSequence(property.propType, object, property.coreIndex, &succeeded);
+ v8::Handle<v8::Value> retn = engine->newSequence(property.propType, object, property.coreIndex,
+ &succeeded);
if (succeeded)
return retn;
}
- QVariant var = object->metaObject()->property(property.coreIndex).read(object);
- return engine->fromVariant(var);
-
-#undef PROPERTY_LOAD
-}
-
-static v8::Handle<v8::Value> LoadPropertyDirect(QV8Engine *engine, QObject *object,
- const QDeclarativePropertyData &property)
-{
- Q_ASSERT(!property.isFunction());
-
-#define PROPERTY_LOAD(metatype, cpptype, constructor) \
- if (property.propType == QMetaType:: metatype) { \
- cpptype type = cpptype(); \
- void *args[] = { &type, 0 }; \
- object->qt_metacall(QMetaObject::ReadProperty, property.coreIndex, args); \
- return constructor(type); \
- }
-
- if (property.isQObject()) {
- QObject *rv = 0;
- void *args[] = { &rv, 0 };
- QMetaObject::metacall(object, QMetaObject::ReadProperty, property.coreIndex, args);
- return engine->newQObject(rv);
- } else if (property.isQList()) {
- return engine->listWrapper()->newList(object, property.coreIndex, property.propType);
- } else PROPERTY_LOAD(QReal, qreal, v8::Number::New)
- else PROPERTY_LOAD(Int || property.isEnum(), int, v8::Integer::New)
- else PROPERTY_LOAD(Bool, bool, v8::Boolean::New)
- else PROPERTY_LOAD(QString, QString, engine->toString)
- else PROPERTY_LOAD(UInt, uint, v8::Integer::NewFromUnsigned)
- else PROPERTY_LOAD(Float, float, v8::Number::New)
- else PROPERTY_LOAD(Double, double, v8::Number::New)
- else if(property.isV8Handle()) {
- QDeclarativeV8Handle handle;
- void *args[] = { &handle, 0 };
- object->qt_metacall(QMetaObject::ReadProperty, property.coreIndex, args);
- return handle.toHandle();
- } else if (engine->engine() && QDeclarativeValueTypeFactory::isValueType((uint)property.propType)) {
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine->engine());
- QDeclarativeValueType *valueType = ep->valueTypes[property.propType];
- if (valueType)
- return engine->newValueType(object, property.coreIndex, valueType);
+ if (property.propType == QVariant::Invalid) {
+ QMetaProperty p = object->metaObject()->property(property.coreIndex);
+ qWarning("QMetaProperty::read: Unable to handle unregistered datatype '%s' for property "
+ "'%s::%s'", p.typeName(), object->metaObject()->className(), p.name());
+ return v8::Undefined();
} else {
- // see if it's a sequence type
- bool success = false;
- v8::Handle<v8::Value> retn = engine->newSequence(property.propType, object, property.coreIndex, &success);
- if (success)
- return retn;
+ QVariant v(property.propType, (void *)0);
+ ReadFunction(object, property, v.data(), notifier);
+ return engine->fromVariant(v);
}
-
- QVariant var = object->metaObject()->property(property.coreIndex).read(object);
- return engine->fromVariant(var);
-
-#undef PROPERTY_LOAD
}
v8::Handle<v8::Value> QV8QObjectWrapper::GetProperty(QV8Engine *engine, QObject *object,
@@ -520,21 +533,43 @@ v8::Handle<v8::Value> QV8QObjectWrapper::GetProperty(QV8Engine *engine, QObject
}
}
- QDeclarativeEnginePrivate *ep = engine->engine()?QDeclarativeEnginePrivate::get(engine->engine()):0;
+ QDeclarativeEnginePrivate *ep =
+ engine->engine()?QDeclarativeEnginePrivate::get(engine->engine()):0;
+
+ if (result->hasAccessors()) {
+ QDeclarativeNotifier *n = 0;
+ QDeclarativeNotifier **nptr = 0;
+
+ if (ep && ep->propertyCapture && result->accessors->notifier)
+ nptr = &n;
+
+ v8::Handle<v8::Value> rv = LoadProperty<ReadAccessor::Accessor>(engine, object, *result, nptr);
+
+ if (result->accessors->notifier) {
+ if (n) ep->captureProperty(n);
+ } else {
+ ep->captureProperty(object, result->coreIndex, result->notifyIndex);
+ }
+
+ return rv;
+ }
+
if (ep && !result->isConstant()) {
+
if (result->coreIndex == 0)
ep->captureProperty(QDeclarativeData::get(object, true)->objectNameNotifier());
else
ep->captureProperty(object, result->coreIndex, result->notifyIndex);
}
- if (result->isVMEProperty())
- return static_cast<QDeclarativeVMEMetaObject *>(const_cast<QMetaObject*>(object->metaObject()))->vmeProperty(result->coreIndex);
-
- if (result->isDirect()) {
- return LoadPropertyDirect(engine, object, *result);
+ if (result->isVMEProperty()) {
+ typedef QDeclarativeVMEMetaObject VMEMO;
+ VMEMO *vmemo = const_cast<VMEMO *>(static_cast<const VMEMO *>(object->metaObject()));
+ return vmemo->vmeProperty(result->coreIndex);
+ } else if (result->isDirect()) {
+ return LoadProperty<ReadAccessor::Direct>(engine, object, *result, 0);
} else {
- return LoadProperty(engine, object, *result);
+ return LoadProperty<ReadAccessor::Indirect>(engine, object, *result, 0);
}
}
@@ -557,8 +592,9 @@ static inline void StoreProperty(QV8Engine *engine, QObject *object, QDeclarativ
newBinding = new QDeclarativeBinding(&function, object, context);
newBinding->setSourceLocation(url, lineNumber);
- newBinding->setTarget(QDeclarativePropertyPrivate::restore(*property, object, context));
- newBinding->setEvaluateFlags(newBinding->evaluateFlags() | QDeclarativeBinding::RequiresThisObject);
+ newBinding->setTarget(object, *property, context);
+ newBinding->setEvaluateFlags(newBinding->evaluateFlags() |
+ QDeclarativeBinding::RequiresThisObject);
}
QDeclarativeAbstractBinding *oldBinding =
@@ -791,14 +827,6 @@ v8::Handle<v8::Array> QV8QObjectWrapper::Enumerator(const v8::AccessorInfo &info
return rv;
}
-FAST_VALUE_GETTER(QObject, QObject*, 0, resource->engine->newQObject);
-FAST_VALUE_GETTER(Int, int, 0, v8::Integer::New);
-FAST_VALUE_GETTER(Bool, bool, false, v8::Boolean::New);
-FAST_VALUE_GETTER(QString, QString, QString(), resource->engine->toString);
-FAST_VALUE_GETTER(UInt, uint, 0, v8::Integer::NewFromUnsigned);
-FAST_VALUE_GETTER(Float, float, 0, v8::Number::New);
-FAST_VALUE_GETTER(Double, double, 0, v8::Number::New);
-
static void FastValueSetter(v8::Local<v8::String>, v8::Local<v8::Value> value,
const v8::AccessorInfo& info)
{
@@ -809,8 +837,10 @@ static void FastValueSetter(v8::Local<v8::String>, v8::Local<v8::Value> value,
QObject *object = resource->object;
- uint32_t data = info.Data()->Uint32Value();
- int index = data & 0x7FFF; // So that we can use the same data for Setter and Getter
+ QDeclarativePropertyData *property =
+ (QDeclarativePropertyData *)v8::External::Unwrap(info.Data());
+
+ int index = property->coreIndex;
QDeclarativeData *ddata = QDeclarativeData::get(object, false);
Q_ASSERT(ddata);
@@ -887,9 +917,9 @@ v8::Local<v8::Object> QDeclarativePropertyCache::newQObject(QObject *object, QV8
// its not guarenteed that this is a win overall. We need to try and measure the cost.
for (StringCache::ConstIterator iter = stringCache.begin(); iter != stringCache.end(); ++iter) {
QDeclarativePropertyData *property = *iter;
- if (property->isFunction() ||
- property->coreIndex >= 0x7FFF || property->notifyIndex >= 0x0FFF ||
- property->coreIndex == 0)
+ if (property->notFullyResolved()) resolve(property);
+
+ if (property->isFunction())
continue;
v8::AccessorGetter fastgetter = 0;
@@ -898,26 +928,21 @@ v8::Local<v8::Object> QDeclarativePropertyCache::newQObject(QObject *object, QV8
fastsetter = FastValueSetterReadOnly;
if (property->isQObject())
- fastgetter = property->isDirect()?QObjectValueGetterDirect:QObjectValueGetter;
+ fastgetter = FAST_GETTER_FUNCTION(property, QObject*);
else if (property->propType == QMetaType::Int || property->isEnum())
- fastgetter = property->isDirect()?IntValueGetterDirect:IntValueGetter;
+ fastgetter = FAST_GETTER_FUNCTION(property, int);
else if (property->propType == QMetaType::Bool)
- fastgetter = property->isDirect()?BoolValueGetterDirect:BoolValueGetter;
+ fastgetter = FAST_GETTER_FUNCTION(property, bool);
else if (property->propType == QMetaType::QString)
- fastgetter = property->isDirect()?QStringValueGetterDirect:QStringValueGetter;
+ fastgetter = FAST_GETTER_FUNCTION(property, QString);
else if (property->propType == QMetaType::UInt)
- fastgetter = property->isDirect()?UIntValueGetterDirect:UIntValueGetter;
+ fastgetter = FAST_GETTER_FUNCTION(property, uint);
else if (property->propType == QMetaType::Float)
- fastgetter = property->isDirect()?FloatValueGetterDirect:FloatValueGetter;
+ fastgetter = FAST_GETTER_FUNCTION(property, float);
else if (property->propType == QMetaType::Double)
- fastgetter = property->isDirect()?DoubleValueGetterDirect:DoubleValueGetter;
+ fastgetter = FAST_GETTER_FUNCTION(property, double);
if (fastgetter) {
- int notifyIndex = property->notifyIndex;
- if (property->isConstant()) notifyIndex = 0;
- else if (notifyIndex == -1) notifyIndex = 0x0FFF;
- uint32_t data = (notifyIndex & 0x0FFF) << 16 | property->coreIndex;
-
QString name = iter.key();
if (name == toString || name == destroy)
continue;
@@ -932,8 +957,12 @@ v8::Local<v8::Object> QDeclarativePropertyCache::newQObject(QObject *object, QV8
ft->InstanceTemplate()->SetHasExternalResource(true);
}
+ // We wrap the raw QDeclarativePropertyData pointer here. This is safe as the
+ // pointer will remain valid at least as long as the lifetime of any QObject's of
+ // this type and the property accessor checks if the object is 0 (deleted) before
+ // dereferencing the pointer.
ft->InstanceTemplate()->SetAccessor(engine->toString(name), fastgetter, fastsetter,
- v8::Integer::NewFromUnsigned(data));
+ v8::External::Wrap(property));
}
}
@@ -1422,7 +1451,7 @@ static v8::Handle<v8::Value> CallMethod(QObject *object, int index, int returnTy
{
if (argCount > 0) {
- QVarLengthArray<MetaCallArgument, 9> args(argCount + 1);
+ QVarLengthArray<CallArgument, 9> args(argCount + 1);
args[0].initAsType(returnType);
for (int ii = 0; ii < argCount; ++ii)
@@ -1438,7 +1467,7 @@ static v8::Handle<v8::Value> CallMethod(QObject *object, int index, int returnTy
} else if (returnType != 0) {
- MetaCallArgument arg;
+ CallArgument arg;
arg.initAsType(returnType);
void *args[] = { arg.dataPtr() };
@@ -1871,17 +1900,17 @@ v8::Handle<v8::Value> QV8QObjectWrapper::Invoke(const v8::Arguments &args)
}
}
-MetaCallArgument::MetaCallArgument()
+CallArgument::CallArgument()
: type(QVariant::Invalid)
{
}
-MetaCallArgument::~MetaCallArgument()
+CallArgument::~CallArgument()
{
cleanup();
}
-void MetaCallArgument::cleanup()
+void CallArgument::cleanup()
{
if (type == QMetaType::QString) {
qstringPtr->~QString();
@@ -1894,7 +1923,7 @@ void MetaCallArgument::cleanup()
}
}
-void *MetaCallArgument::dataPtr()
+void *CallArgument::dataPtr()
{
if (type == -1)
return qvariantPtr->data();
@@ -1902,7 +1931,7 @@ void *MetaCallArgument::dataPtr()
return (void *)&allocData;
}
-void MetaCallArgument::initAsType(int callType)
+void CallArgument::initAsType(int callType)
{
if (type != 0) { cleanup(); type = 0; }
if (callType == 0) return;
@@ -1937,7 +1966,7 @@ void MetaCallArgument::initAsType(int callType)
}
}
-void MetaCallArgument::fromValue(int callType, QV8Engine *engine, v8::Handle<v8::Value> value)
+void CallArgument::fromValue(int callType, QV8Engine *engine, v8::Handle<v8::Value> value)
{
if (type != 0) { cleanup(); type = 0; }
@@ -2013,7 +2042,7 @@ void MetaCallArgument::fromValue(int callType, QV8Engine *engine, v8::Handle<v8:
}
}
-v8::Handle<v8::Value> MetaCallArgument::toValue(QV8Engine *engine)
+v8::Handle<v8::Value> CallArgument::toValue(QV8Engine *engine)
{
if (type == qMetaTypeId<QJSValue>()) {
return QJSValuePrivate::get(*qjsValuePtr)->asV8Value(engine);
diff --git a/src/declarative/qml/v8/qv8sequencewrapper_p_p.h b/src/declarative/qml/v8/qv8sequencewrapper_p_p.h
index a947d52013..1861ea69e6 100644
--- a/src/declarative/qml/v8/qv8sequencewrapper_p_p.h
+++ b/src/declarative/qml/v8/qv8sequencewrapper_p_p.h
@@ -254,8 +254,7 @@ static QString convertUrlToString(QV8Engine *, const QUrl &v)
if (objectType == QV8SequenceResource::Reference) { \
if (!object) \
return QVariant(); \
- void *a[] = { &c, 0 }; \
- QMetaObject::metacall(object, QMetaObject::ReadProperty, propertyIndex, a); \
+ loadReference(); \
} \
return QVariant::fromValue<SequenceType>(c); \
} \
@@ -283,8 +282,7 @@ static QString convertUrlToString(QV8Engine *, const QUrl &v)
if (objectType == QV8SequenceResource::Reference) { \
if (!object) \
return 0; \
- void *a[] = { &c, 0 }; \
- QMetaObject::metacall(object, QMetaObject::ReadProperty, propertyIndex, a); \
+ loadReference(); \
} \
return c.count(); \
} \
@@ -335,8 +333,7 @@ static QString convertUrlToString(QV8Engine *, const QUrl &v)
if (objectType == QV8SequenceResource::Reference) { \
if (!object) \
return v8::Undefined(); \
- void *a[] = { &c, 0 }; \
- QMetaObject::metacall(object, QMetaObject::ReadProperty, propertyIndex, a); \
+ loadReference(); \
} \
/* modify the sequence */ \
SequenceElementType elementValue = ConversionFromV8fn(engine, value); \
@@ -353,13 +350,9 @@ static QString convertUrlToString(QV8Engine *, const QUrl &v)
} \
c.append(elementValue); \
} \
- if (objectType == QV8SequenceResource::Reference) { \
- /* write back. already checked that object is non-null, so skip that check here. */ \
- int status = -1; \
- QDeclarativePropertyPrivate::WriteFlags flags = QDeclarativePropertyPrivate::DontRemoveBinding; \
- void *a[] = { &c, 0, &status, &flags }; \
- QMetaObject::metacall(object, QMetaObject::WriteProperty, propertyIndex, a); \
- } \
+ /* write back. already checked that object is non-null, so skip that check here. */ \
+ if (objectType == QV8SequenceResource::Reference) \
+ storeReference(); \
return value; \
} \
v8::Handle<v8::Value> indexedGetter(quint32 index) \
@@ -367,8 +360,7 @@ static QString convertUrlToString(QV8Engine *, const QUrl &v)
if (objectType == QV8SequenceResource::Reference) { \
if (!object) \
return v8::Undefined(); \
- void *a[] = { &c, 0 }; \
- QMetaObject::metacall(object, QMetaObject::ReadProperty, propertyIndex, a); \
+ loadReference(); \
} \
quint32 count = c.count(); \
if (index < count) \
@@ -403,8 +395,7 @@ static QString convertUrlToString(QV8Engine *, const QUrl &v)
if (objectType == QV8SequenceResource::Reference) { \
if (!object) \
return v8::Handle<v8::Array>(); \
- void *a[] = { &c, 0 }; \
- QMetaObject::metacall(object, QMetaObject::ReadProperty, propertyIndex, a); \
+ loadReference(); \
} \
quint32 count = c.count(); \
v8::Local<v8::Array> retn = v8::Array::New(count); \
@@ -418,8 +409,7 @@ static QString convertUrlToString(QV8Engine *, const QUrl &v)
if (objectType == QV8SequenceResource::Reference) { \
if (!object) \
return v8::Undefined(); \
- void *a[] = { &c, 0 }; \
- QMetaObject::metacall(object, QMetaObject::ReadProperty, propertyIndex, a); \
+ loadReference(); \
} \
QString str; \
quint32 count = c.count(); \
@@ -429,6 +419,23 @@ static QString convertUrlToString(QV8Engine *, const QUrl &v)
str.chop(1); \
return engine->toString(str); \
} \
+ void loadReference() \
+ { \
+ Q_ASSERT(object); \
+ Q_ASSERT(objectType == QV8SequenceResource::Reference); \
+ void *a[] = { &c, 0 }; \
+ QMetaObject::metacall(object, QMetaObject::ReadProperty, propertyIndex, a); \
+ } \
+ void storeReference() \
+ { \
+ Q_ASSERT(object); \
+ Q_ASSERT(objectType == QV8SequenceResource::Reference); \
+ int status = -1; \
+ QDeclarativePropertyPrivate::WriteFlags flags = \
+ QDeclarativePropertyPrivate::DontRemoveBinding; \
+ void *a[] = { &c, 0, &status, &flags }; \
+ QMetaObject::metacall(object, QMetaObject::WriteProperty, propertyIndex, a); \
+ } \
private: \
QDeclarativeGuard<QObject> object; \
int propertyIndex; \
diff --git a/src/declarative/qml/v8/qv8valuetypewrapper.cpp b/src/declarative/qml/v8/qv8valuetypewrapper.cpp
index aca0c85ace..53d500c454 100644
--- a/src/declarative/qml/v8/qv8valuetypewrapper.cpp
+++ b/src/declarative/qml/v8/qv8valuetypewrapper.cpp
@@ -346,9 +346,9 @@ v8::Handle<v8::Value> QV8ValueTypeWrapper::Setter(v8::Local<v8::String> property
newBinding = new QDeclarativeBinding(&function, reference->object, context);
newBinding->setSourceLocation(url, lineNumber);
- newBinding->setTarget(QDeclarativePropertyPrivate::restore(cacheData, reference->object,
- context));
- newBinding->setEvaluateFlags(newBinding->evaluateFlags() | QDeclarativeBinding::RequiresThisObject);
+ newBinding->setTarget(reference->object, cacheData, context);
+ newBinding->setEvaluateFlags(newBinding->evaluateFlags() |
+ QDeclarativeBinding::RequiresThisObject);
}
QDeclarativeAbstractBinding *oldBinding =
diff --git a/src/qtquick1/graphicsitems/qdeclarativeitem.cpp b/src/qtquick1/graphicsitems/qdeclarativeitem.cpp
index bd795cb4b5..1f57d53b7e 100644
--- a/src/qtquick1/graphicsitems/qdeclarativeitem.cpp
+++ b/src/qtquick1/graphicsitems/qdeclarativeitem.cpp
@@ -1986,14 +1986,6 @@ void QDeclarativeItemPrivate::transform_clear(QDeclarativeListProperty<QGraphics
}
}
-void QDeclarativeItemPrivate::parentProperty(QObject *o, void *rv, QDeclarativeNotifierEndpoint *e)
-{
- QDeclarativeItem *item = static_cast<QDeclarativeItem*>(o);
- if (e)
- e->connect(&item->d_func()->parentNotifier);
- *((QDeclarativeItem **)rv) = item->parentItem();
-}
-
/*!
\qmlproperty list<Object> QtQuick1::Item::data
\default
@@ -3101,7 +3093,6 @@ QVariant QDeclarativeItem::itemChange(GraphicsItemChange change,
case ItemParentHasChanged:
d->resolveLayoutMirror();
emit parentChanged(parentItem());
- d->parentNotifier.notify();
break;
case ItemVisibleHasChanged: {
for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
diff --git a/src/qtquick1/graphicsitems/qdeclarativeitem_p.h b/src/qtquick1/graphicsitems/qdeclarativeitem_p.h
index 8dccd1ac37..1dcafe55f4 100644
--- a/src/qtquick1/graphicsitems/qdeclarativeitem_p.h
+++ b/src/qtquick1/graphicsitems/qdeclarativeitem_p.h
@@ -216,10 +216,6 @@ public:
return item->d_func();
}
- // Accelerated property accessors
- QDeclarativeNotifier parentNotifier;
- static void parentProperty(QObject *o, void *rv, QDeclarativeNotifierEndpoint *e);
-
QDeclarative1Anchors *anchors() {
if (!_anchors) {
Q_Q(QDeclarativeItem);
diff --git a/src/qtquick1/qtquick1.cpp b/src/qtquick1/qtquick1.cpp
index b8c0e109ba..bb6c536413 100644
--- a/src/qtquick1/qtquick1.cpp
+++ b/src/qtquick1/qtquick1.cpp
@@ -40,7 +40,6 @@
****************************************************************************/
#include <QtDeclarative/qdeclarative.h>
-#include <QtDeclarative/private/qdeclarativefastproperties_p.h>
#include <QtQuick1/qdeclarativeitem.h>
#include <QtQuick1/private/qdeclarativeitem_p.h>
#include <QtQuick1/private/qdeclarativeutilmodule_p.h>
@@ -51,9 +50,6 @@ QT_BEGIN_NAMESPACE
void QDeclarativeQtQuick1Module::defineModule(QDeclarativeQtQuick1Module::Module module)
{
- QDeclarativeFastProperties::instance()->add(&QDeclarativeItem::staticMetaObject,
- QDeclarativeItem::staticMetaObject.indexOfProperty("parent"),
- QDeclarativeItemPrivate::parentProperty);
if (module == QtQuick1)
qmlRegisterBaseTypes("QtQuick", 1, 0);
else if (module == Qt47)
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index a9409ecdf4..5ec0787d9e 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -64,14 +64,45 @@
#include <QtQuick/private/qdeclarativestate_p.h>
#include <private/qlistmodelinterface_p.h>
#include <private/qquickitem_p.h>
+#include <private/qdeclarativeaccessors_p.h>
#include <float.h>
-// XXX todo Readd parentNotifier for faster parent bindings
// XXX todo Check that elements that create items handle memory correctly after visual ownership change
QT_BEGIN_NAMESPACE
+static void QQuickItem_parentNotifier(QObject *o, intptr_t, QDeclarativeNotifier **n)
+{
+ QQuickItemPrivate *d = QQuickItemPrivate::get(static_cast<QQuickItem *>(o));
+ *n = &d->parentNotifier;
+}
+
+QML_PRIVATE_ACCESSOR(QQuickItem, QQuickItem *, parent, parentItem)
+QML_PRIVATE_ACCESSOR(QQuickItem, qreal, x, x)
+QML_PRIVATE_ACCESSOR(QQuickItem, qreal, y, y)
+QML_PRIVATE_ACCESSOR(QQuickItem, qreal, width, width)
+QML_PRIVATE_ACCESSOR(QQuickItem, qreal, height, height)
+
+static QDeclarativeAccessors QQuickItem_parent = { QQuickItem_parentRead, QQuickItem_parentNotifier };
+static QDeclarativeAccessors QQuickItem_x = { QQuickItem_xRead, 0 };
+static QDeclarativeAccessors QQuickItem_y = { QQuickItem_yRead, 0 };
+static QDeclarativeAccessors QQuickItem_width = { QQuickItem_widthRead, 0 };
+static QDeclarativeAccessors QQuickItem_height = { QQuickItem_heightRead, 0 };
+
+QML_DECLARE_PROPERTIES(QQuickItem) {
+ { QML_PROPERTY_NAME(parent), 0, &QQuickItem_parent },
+ { QML_PROPERTY_NAME(x), 0, &QQuickItem_x },
+ { QML_PROPERTY_NAME(y), 0, &QQuickItem_y },
+ { QML_PROPERTY_NAME(width), 0, &QQuickItem_width },
+ { QML_PROPERTY_NAME(height), 0, &QQuickItem_height }
+};
+
+void QQuickItemPrivate::registerAccessorProperties()
+{
+ QML_DEFINE_PROPERTIES(QQuickItem);
+}
+
/*!
\qmlclass Transform QQuickTransform
\inqmlmodule QtQuick 2
@@ -1880,6 +1911,7 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
d->itemChange(ItemParentHasChanged, d->parentItem);
+ d->parentNotifier.notify();
emit parentChanged(d->parentItem);
}
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index 6e7a909696..ffc1017105 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -146,6 +146,7 @@ class Q_QUICK_EXPORT QQuickItem : public QObject, public QDeclarativeParserStatu
Q_ENUMS(TransformOrigin)
Q_CLASSINFO("DefaultProperty", "data")
+ Q_CLASSINFO("qt_HasQmlAccessors", "true")
public:
enum Flag {
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index a522a19a70..79d98d7fe4 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -141,6 +141,8 @@ public:
static QQuickItemPrivate* get(QQuickItem *item) { return item->d_func(); }
static const QQuickItemPrivate* get(const QQuickItem *item) { return item->d_func(); }
+ static void registerAccessorProperties();
+
QQuickItemPrivate();
~QQuickItemPrivate();
void init(QQuickItem *parent);
@@ -281,6 +283,8 @@ public:
QSGContext *sceneGraphContext() const { Q_ASSERT(canvas); return static_cast<QQuickCanvasPrivate *>(QObjectPrivate::get(canvas))->context; }
QQuickItem *parentItem;
+ QDeclarativeNotifier parentNotifier;
+
QList<QQuickItem *> childItems;
mutable QList<QQuickItem *> *sortedChildItems;
QList<QQuickItem *> paintOrderChildItems() const;
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index a9d8a193f0..69b9caf940 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -108,6 +108,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
{
QDeclarativePrivate::RegisterAutoParent autoparent = { 0, &qquickitem_autoParent };
QDeclarativePrivate::qmlregister(QDeclarativePrivate::AutoParentRegistration, &autoparent);
+ QQuickItemPrivate::registerAccessorProperties();
#ifdef QT_NO_MOVIE
qmlRegisterTypeNotAvailable(uri,major,minor,"AnimatedImage", qApp->translate("QQuickAnimatedImage","Qt was built without support for QMovie"));