aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/types/qqmllistmodel_p_p.h
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@theqtcompany.com>2015-08-15 01:31:13 +0200
committerSimon Hausmann <simon.hausmann@theqtcompany.com>2015-08-19 05:03:50 +0000
commit4876ea6a18ccdfd72014582aa5d50ab9f6b6ec9e (patch)
tree73e9a9ce3ed28b817c77d3d48475c76a7d54c9cf /src/qml/types/qqmllistmodel_p_p.h
parent7fccfc4663c362d717383493732849237562f0c7 (diff)
Fix performance of ListModel::get()
When called, the function would return a full-fledged QObject that maps the list element addressed. It would contain a _copy_ of all values in the list item and it would create a new meta-object for each list element. This function exists for the JavaScript API, and therefore we now return a much more lightweight object. For compatbility reasons it still has to be a QObject, but the meta-object of it is created on-demand, i.e. only when accessing properties from the C++ side or when connecting to the changed signal of a property. Otherwise the JavaScript wrapper will return the live values from the model without copying them. Change-Id: Iabf3ca22192d2aee06ae9d4b4cfb2fcde2a021b1 Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com> Reviewed-by: Michael Brasser <michael.brasser@live.com> Reviewed-by: Spencer Schumann <spencer.schumann@echostar.com>
Diffstat (limited to 'src/qml/types/qqmllistmodel_p_p.h')
-rw-r--r--src/qml/types/qqmllistmodel_p_p.h77
1 files changed, 50 insertions, 27 deletions
diff --git a/src/qml/types/qqmllistmodel_p_p.h b/src/qml/types/qqmllistmodel_p_p.h
index 4e3132b860..bd0f028e7a 100644
--- a/src/qml/types/qqmllistmodel_p_p.h
+++ b/src/qml/types/qqmllistmodel_p_p.h
@@ -111,56 +111,72 @@ private:
friend class DynamicRoleModelNodeMetaObject;
};
-class ModelObject;
-
class ModelNodeMetaObject : public QQmlOpenMetaObject
{
public:
- ModelNodeMetaObject(ModelObject *object);
+ ModelNodeMetaObject(QObject *object, QQmlListModel *model, int elementIndex);
~ModelNodeMetaObject();
+ virtual QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *object);
+
+ static ModelNodeMetaObject *get(QObject *obj);
+
bool m_enabled;
+ QQmlListModel *m_model;
+ int m_elementIndex;
+
+ void updateValues();
+ void updateValues(const QVector<int> &roles);
+
+ bool initialized() const { return m_initialized; }
protected:
void propertyWritten(int index);
private:
-
- ModelObject *m_obj;
-};
-
-class ModelObject : public QObject
-{
- Q_OBJECT
-public:
- ModelObject(QQmlListModel *model, int elementIndex);
-
+ using QQmlOpenMetaObject::setValue;
void setValue(const QByteArray &name, const QVariant &val, bool force)
{
if (force) {
- QVariant existingValue = m_meta->value(name);
+ QVariant existingValue = value(name);
if (existingValue.isValid()) {
- (*m_meta)[name] = QVariant();
+ (*this)[name] = QVariant();
}
}
- m_meta->setValue(name, val);
+ setValue(name, val);
}
- void setNodeUpdatesEnabled(bool enable)
- {
- m_meta->m_enabled = enable;
- }
+ void initialize();
+ bool m_initialized;
+};
- void updateValues();
- void updateValues(const QVector<int> &roles);
+namespace QV4 {
+
+namespace Heap {
+struct ModelObject : public QObjectWrapper {
+ ModelObject(QV4::ExecutionEngine *engine, QObject *object, QQmlListModel *model, int elementIndex)
+ : QObjectWrapper(engine, object)
+ , m_model(model)
+ , m_elementIndex(elementIndex)
+ {}
QQmlListModel *m_model;
int m_elementIndex;
+};
-private:
- ModelNodeMetaObject *m_meta;
+}
+
+struct ModelObject : public QObjectWrapper
+{
+ static void put(Managed *m, String *name, const Value& value);
+ static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
+ static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
+
+ V4_OBJECT2(ModelObject, QObjectWrapper)
};
+} // namespace QV4
+
class ListLayout
{
public:
@@ -236,7 +252,7 @@ public:
enum
{
- BLOCK_SIZE = 64 - sizeof(int) - sizeof(ListElement *) - sizeof(ModelObject *)
+ BLOCK_SIZE = 64 - sizeof(int) - sizeof(ListElement *) - sizeof(ModelNodeMetaObject *)
};
private:
@@ -278,11 +294,13 @@ private:
int getUid() const { return uid; }
+ ModelNodeMetaObject *objectCache();
+
char data[BLOCK_SIZE];
ListElement *next;
int uid;
- ModelObject *m_objectCache;
+ QObject *m_objectCache;
friend class ListModel;
};
@@ -315,6 +333,11 @@ public:
return m_layout->getExistingRole(index);
}
+ const ListLayout::Role *getExistingRole(QV4::String *key)
+ {
+ return m_layout->getExistingRole(key);
+ }
+
const ListLayout::Role &getOrCreateListRole(const QString &name)
{
return m_layout->getRoleOrCreate(name, ListLayout::Role::List);
@@ -343,7 +366,7 @@ public:
static void sync(ListModel *src, ListModel *target, QHash<int, ListModel *> *srcModelHash);
- ModelObject *getOrCreateModelObject(QQmlListModel *model, int elementIndex);
+ QObject *getOrCreateModelObject(QQmlListModel *model, int elementIndex);
private:
QPODVector<ListElement *, 4> elements;