Also reduce the number of direct calls to qt_metacall().
Change-Id: I04cd6e516a3e61058548309a19fe0b830f15c93f
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
--- /dev/null
+/****************************************************************************
+**
+** 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
--- /dev/null
+/****************************************************************************
+**
+** 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
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);
QDeclarativeBinding(void *, QObject *, QDeclarativeContextData *, QObject *parent=0);
void setTarget(const QDeclarativeProperty &);
+ void setTarget(QObject *, const QDeclarativePropertyData &, QDeclarativeContextData *);
QDeclarativeProperty property() const;
void setEvaluateFlags(EvaluateFlags flags);
+++ /dev/null
-/****************************************************************************
-**
-** 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
+++ /dev/null
-/****************************************************************************
-**
-** 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
Q_GLOBAL_STATIC(QDeclarativeValueTypeFactory, qmlValueTypes);
+QDeclarativePropertyPrivate::QDeclarativePropertyPrivate()
+: context(0), engine(0), object(0), isNameCached(false)
+{
+}
+
QDeclarativeContextData *QDeclarativePropertyPrivate::effectiveContext() const
{
if (context) return context;
}
QDeclarativeProperty
-QDeclarativePropertyPrivate::restore(const QDeclarativePropertyData &data,
- QObject *object, QDeclarativeContextData *ctxt)
+QDeclarativePropertyPrivate::restore(QObject *object, const QDeclarativePropertyData &data,
+ QDeclarativeContextData *ctxt)
{
QDeclarativeProperty prop;
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);
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 *);
#include <private/qv8engine_p.h>
#include <private/qmetaobject_p.h>
+#include <private/qdeclarativeaccessors_p.h>
#include <QtCore/qdebug.h>
QT_BEGIN_NAMESPACE
+#define Q_INT16_MAX 32767
+
class QDeclarativePropertyCacheMethodArguments
{
public:
// 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>()) {
coreIndex = p.propertyIndex();
notifyIndex = p.notifySignalIndex();
+ Q_ASSERT(p.revision() <= Q_INT16_MAX);
revision = p.revision();
flags = fastFlagsForProperty(p);
{
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();
}
}
}
+ Q_ASSERT(m.revision() <= Q_INT16_MAX);
revision = m.revision();
}
}
}
+ Q_ASSERT(m.revision() <= Q_INT16_MAX);
revision = m.revision();
}
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);
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());
if (!dynamicMetaObject)
data->flags |= QDeclarativePropertyData::IsDirect;
+ Q_ASSERT((allowedRevisionCache.count() - 1) < Q_INT16_MAX);
data->metaObjectOffset = allowedRevisionCache.count() - 1;
if (data->isSignal()) {
if (!dynamicMetaObject)
data->flags |= QDeclarativePropertyData::IsDirect;
+ Q_ASSERT((allowedRevisionCache.count() - 1) < Q_INT16_MAX);
data->metaObjectOffset = allowedRevisionCache.count() - 1;
QDeclarativePropertyData *old = 0;
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;
}
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);
}
}
+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;
+ }
}
}
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;
}
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)
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
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)
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; }
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; }
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
//proxy object
};
};
- int revision;
- int metaObjectOffset;
+
+ qint16 revision;
+ qint16 metaObjectOffset;
+
+ struct { // When HasAccessors
+ QDeclarativeAccessors *accessors;
+ intptr_t accessorData;
+ };
private:
friend class QDeclarativePropertyData;
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);
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;
overrideIndex = -1;
revision = 0;
metaObjectOffset = -1;
+ accessors = 0;
+ accessorData = 0;
flags = 0;
}
valueTypePropType == other.valueTypePropType));
}
-int QDeclarativePropertyData::getValueTypeCoreIndex() const
+int QDeclarativePropertyRawData::getValueTypeCoreIndex() const
{
return isValueTypeVirtual()?valueTypeCoreIndex:-1;
}
QDeclarativePropertyData *
QDeclarativePropertyCache::overrideData(QDeclarativePropertyData *data) const
{
- if (data->overrideIndex < 0)
+ if (!data->hasOverride())
return 0;
if (data->overrideIndexIsProperty)
{
}
-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();
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();
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();
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();
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();
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();
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();
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();
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();
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();
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)"))
.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();
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();
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();
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
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
qreal wordSpacing() const;
void setWordSpacing(qreal spacing);
+ void onLoad();
private:
QFont font;
bool pixelSizeSet;
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;
QColor color;
};
+void QDeclarativeValueType::onLoad()
+{
+}
+
QT_END_NAMESPACE
#endif // QDECLARATIVEVALUETYPE_P_H
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) { \
} 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
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);
}
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);
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)
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)
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)
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());
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();
$$PWD/qdeclarativescript.cpp \
$$PWD/qdeclarativerewrite.cpp \
$$PWD/qdeclarativevaluetype.cpp \
- $$PWD/qdeclarativefastproperties.cpp \
+ $$PWD/qdeclarativeaccessors.cpp \
$$PWD/qdeclarativexmlhttprequest.cpp \
$$PWD/qdeclarativesqldatabase.cpp \
$$PWD/qdeclarativewatcher.cpp \
$$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 \
#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>
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, ¬ifier);
+ 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)
#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
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;
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) {
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 << ")";
#include <QtCore/qvector.h>
#include <QtCore/qvarlengtharray.h>
+#include <private/qdeclarativepropertycache_p.h>
+
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
# define QML_V4_INSTR_HEADER quint8 type;
#endif
+class QObject;
+class QDeclarativeNotifier;
+
namespace QDeclarativeJS {
union V4Instr {
quint8 exceptionId;
quint8 valueType;
quint16 subscription;
- quint16 function;
+ QDeclarativePropertyRawData property;
};
struct instr_fetch{
ep->dereferenceScarceResources();
} else {
- QDeclarativeProperty p = QDeclarativePropertyPrivate::restore(property, object, context);
+ QDeclarativeProperty p = QDeclarativePropertyPrivate::restore(object, property, context);
QDeclarativeBindingPrivate::printBindingLoopError(p);
}
}
#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>
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);
inline v8::Handle<v8::Value> toValue(QV8Engine *);
private:
- MetaCallArgument(const MetaCallArgument &);
+ CallArgument(const CallArgument &);
inline void cleanup();
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, ¬ifier);
+ 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;
}
{
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 };
}
// 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,
}
}
- 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);
}
}
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 =
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)
{
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);
// 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;
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;
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));
}
}
{
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)
} else if (returnType != 0) {
- MetaCallArgument arg;
+ CallArgument arg;
arg.initAsType(returnType);
void *args[] = { arg.dataPtr() };
}
}
-MetaCallArgument::MetaCallArgument()
+CallArgument::CallArgument()
: type(QVariant::Invalid)
{
}
-MetaCallArgument::~MetaCallArgument()
+CallArgument::~CallArgument()
{
cleanup();
}
-void MetaCallArgument::cleanup()
+void CallArgument::cleanup()
{
if (type == QMetaType::QString) {
qstringPtr->~QString();
}
}
-void *MetaCallArgument::dataPtr()
+void *CallArgument::dataPtr()
{
if (type == -1)
return qvariantPtr->data();
return (void *)&allocData;
}
-void MetaCallArgument::initAsType(int callType)
+void CallArgument::initAsType(int callType)
{
if (type != 0) { cleanup(); type = 0; }
if (callType == 0) return;
}
}
-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; }
}
}
-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);
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); \
} \
if (objectType == QV8SequenceResource::Reference) { \
if (!object) \
return 0; \
- void *a[] = { &c, 0 }; \
- QMetaObject::metacall(object, QMetaObject::ReadProperty, propertyIndex, a); \
+ loadReference(); \
} \
return c.count(); \
} \
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); \
} \
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) \
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) \
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); \
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(); \
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; \
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 =
}
}
-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
case ItemParentHasChanged:
d->resolveLayoutMirror();
emit parentChanged(parentItem());
- d->parentNotifier.notify();
break;
case ItemVisibleHasChanged: {
for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
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);
****************************************************************************/
#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>
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)
#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
d->itemChange(ItemParentHasChanged, d->parentItem);
+ d->parentNotifier.notify();
emit parentChanged(d->parentItem);
}
Q_ENUMS(TransformOrigin)
Q_CLASSINFO("DefaultProperty", "data")
+ Q_CLASSINFO("qt_HasQmlAccessors", "true")
public:
enum Flag {
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);
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;
{
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"));