diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2015-02-15 19:47:25 +0000 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2015-02-28 16:28:39 +0000 |
commit | 7ccaf0f9a917f49e1cde551c2a4f4dcff575406c (patch) | |
tree | 3dd47490fce2cf99f783b0bad608cf97d84fd6ab /tests/auto/quick3d | |
parent | 66b26f86856ff57713ffab35fb689d087aa91ecc (diff) |
Added NodeInstantiator
Hopefully in the long term we can make the renderer smart enough
that it can automatically use instancing to render such things.
Change-Id: I9f5cfabeea11f5e6b925d5ad2466afa8e601e6f8
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'tests/auto/quick3d')
10 files changed, 437 insertions, 0 deletions
diff --git a/tests/auto/quick3d/quick3d.pro b/tests/auto/quick3d/quick3d.pro new file mode 100644 index 000000000..898265ab6 --- /dev/null +++ b/tests/auto/quick3d/quick3d.pro @@ -0,0 +1,6 @@ +TEMPLATE = subdirs + +contains(QT_CONFIG, private_tests) { + SUBDIRS += \ + quick3dnodeinstantiator +} diff --git a/tests/auto/quick3d/quick3dnodeinstantiator/data/createAndRemove.qml b/tests/auto/quick3d/quick3dnodeinstantiator/data/createAndRemove.qml new file mode 100644 index 000000000..23084bfb0 --- /dev/null +++ b/tests/auto/quick3d/quick3dnodeinstantiator/data/createAndRemove.qml @@ -0,0 +1,20 @@ +import QtQml 2.1 +// To avoid clash with Component.onCompleted +// TODO: Export Qt3D::QComponent with a different name +import Qt3D 2.0 as Qt3D + +Qt3D.Entity { + Qt3D.NodeInstantiator { + objectName: "instantiator1" + model: model1 + delegate: Qt3D.Entity { + property string datum: model.text + } + } + Component.onCompleted: { + model1.add("Delta"); + model1.add("Gamma"); + model1.add("Beta"); + model1.add("Alpha"); + } +} diff --git a/tests/auto/quick3d/quick3dnodeinstantiator/data/createMultiple.qml b/tests/auto/quick3d/quick3dnodeinstantiator/data/createMultiple.qml new file mode 100644 index 000000000..ad4879c7a --- /dev/null +++ b/tests/auto/quick3d/quick3dnodeinstantiator/data/createMultiple.qml @@ -0,0 +1,10 @@ +import QtQml 2.1 +import Qt3D 2.0 + +NodeInstantiator { + model: 10 + delegate: Entity { + property bool success: true + property int idx: index + } +} diff --git a/tests/auto/quick3d/quick3dnodeinstantiator/data/createNone.qml b/tests/auto/quick3d/quick3dnodeinstantiator/data/createNone.qml new file mode 100644 index 000000000..c2ea5b650 --- /dev/null +++ b/tests/auto/quick3d/quick3dnodeinstantiator/data/createNone.qml @@ -0,0 +1,13 @@ +import QtQml 2.1 +import Qt3D 2.0 + +NodeInstantiator { + model: 0 + property bool success: true + Entity { + property bool success: true + property int idx: index + } + onObjectChanged: success = false;//Don't create intermediate objects + onCountChanged: success = false;//Don't create intermediate objects +} diff --git a/tests/auto/quick3d/quick3dnodeinstantiator/data/createSingle.qml b/tests/auto/quick3d/quick3dnodeinstantiator/data/createSingle.qml new file mode 100644 index 000000000..2816310ec --- /dev/null +++ b/tests/auto/quick3d/quick3dnodeinstantiator/data/createSingle.qml @@ -0,0 +1,9 @@ +import QtQml 2.1 +import Qt3D 2.0 + +NodeInstantiator { + Entity { + property bool success: true + property int idx: index + } +} diff --git a/tests/auto/quick3d/quick3dnodeinstantiator/data/inactive.qml b/tests/auto/quick3d/quick3dnodeinstantiator/data/inactive.qml new file mode 100644 index 000000000..1edef1e0c --- /dev/null +++ b/tests/auto/quick3d/quick3dnodeinstantiator/data/inactive.qml @@ -0,0 +1,10 @@ +import QtQml 2.1 +import Qt3D 2.0 + +NodeInstantiator { + active: false + Entity { + property bool success: true + property int idx: index + } +} diff --git a/tests/auto/quick3d/quick3dnodeinstantiator/data/stringModel.qml b/tests/auto/quick3d/quick3dnodeinstantiator/data/stringModel.qml new file mode 100644 index 000000000..55f536b1f --- /dev/null +++ b/tests/auto/quick3d/quick3dnodeinstantiator/data/stringModel.qml @@ -0,0 +1,10 @@ +import QtQml 2.1 +import Qt3D 2.0 + +NodeInstantiator { + model: ["alpha", "beta", "gamma", "delta"] + delegate: Entity { + property bool success: index == 1 ? datum.length == 4 : datum.length == 5 + property string datum: modelData + } +} diff --git a/tests/auto/quick3d/quick3dnodeinstantiator/quick3dnodeinstantiator.pro b/tests/auto/quick3d/quick3dnodeinstantiator/quick3dnodeinstantiator.pro new file mode 100644 index 000000000..f690d2c3b --- /dev/null +++ b/tests/auto/quick3d/quick3dnodeinstantiator/quick3dnodeinstantiator.pro @@ -0,0 +1,14 @@ +CONFIG += testcase +TARGET = tst_qnodeinstantiator +osx:CONFIG -= app_bundle + +INCLUDEPATH += ../../shared/ +SOURCES += \ + tst_quick3dnodeinstantiator.cpp +HEADERS += stringmodel.h + +include (../../shared/util.pri) + +TESTDATA = data/* + +QT += core-private gui-private 3dcore 3dquick 3dquick-private testlib diff --git a/tests/auto/quick3d/quick3dnodeinstantiator/stringmodel.h b/tests/auto/quick3d/quick3dnodeinstantiator/stringmodel.h new file mode 100644 index 000000000..b429866ff --- /dev/null +++ b/tests/auto/quick3d/quick3dnodeinstantiator/stringmodel.h @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Dmitrii Kosarev aka Kakadu <kakadu.hafanana@gmail.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef STRINGMODEL_H +#define STRINGMODEL_H + +#include <QtCore/QObject> +#include <QtCore/QAbstractItemModel> +#include <QtCore/QDebug> + +class StringModel : public QAbstractItemModel +{ + Q_OBJECT + QVector<QString> items; + QHash<int, QByteArray> roles; + QString name; + +public: + explicit StringModel(const QString& name) : QAbstractItemModel(), name(name) + { + roles.insert(555, "text"); + } + + void drop(int count) + { + beginRemoveRows(QModelIndex(), 0, count-1); + for (int i=0; i<count; i++) + items.pop_front(); + endRemoveRows(); + } + + Q_INVOKABLE void add(QString s) + { + beginInsertRows(QModelIndex(), 0, 0); + items.push_front(s); + endInsertRows(); + } + + int rowCount(const QModelIndex &) const + { + return items.count(); + } + + virtual QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE + { + return roles; + } + + virtual int columnCount(const QModelIndex &) const + { + return 1; + } + + virtual bool hasChildren(const QModelIndex &) const Q_DECL_OVERRIDE + { + return rowCount(QModelIndex()) > 0; + } + + virtual QModelIndex index(int row, int column, const QModelIndex &parent) const + { + Q_UNUSED(column); + if (row>=0 && row<rowCount(parent)) + return createIndex(row,0); + else + return QModelIndex(); + } + + virtual QModelIndex parent(const QModelIndex &) const + { + return QModelIndex(); + } + + QVariant data (const QModelIndex & index, int role) const + { + int row = index.row(); + if ((row<0) || (row>=items.count())) + return QVariant::Invalid; + + switch (role) { + case Qt::DisplayRole: + case 555: + return QVariant::fromValue(items.at(row)); + default: + return QVariant(); + } + } +}; + +#endif // STRINGMODEL_H diff --git a/tests/auto/quick3d/quick3dnodeinstantiator/tst_quick3dnodeinstantiator.cpp b/tests/auto/quick3d/quick3dnodeinstantiator/tst_quick3dnodeinstantiator.cpp new file mode 100644 index 000000000..37d8ff566 --- /dev/null +++ b/tests/auto/quick3d/quick3dnodeinstantiator/tst_quick3dnodeinstantiator.cpp @@ -0,0 +1,223 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Research In Motion. +** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../../shared/util.h" +#include "stringmodel.h" + +#include <qtest.h> +#include <QSignalSpy> +#include <QDebug> + +#include <Qt3DQuick/private/quick3dnodeinstantiator_p.h> + +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQml/qqmlcontext.h> + +using namespace Qt3D::Quick; + +class tst_quick3dnodeinstantiator: public QQmlDataTest +{ + Q_OBJECT + +private slots: + void createNone(); + void createSingle(); + void createMultiple(); + void stringModel(); + void activeProperty(); + void intModelChange(); + void createAndRemove(); +}; + +void tst_quick3dnodeinstantiator::createNone() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("createNone.qml")); + Quick3DNodeInstantiator *instantiator = qobject_cast<Quick3DNodeInstantiator*>(component.create()); + QVERIFY(instantiator != 0); + QCOMPARE(instantiator->isActive(), true); + QCOMPARE(instantiator->count(), 0); + QCOMPARE(instantiator->property("success").toBool(), true); + QVERIFY(instantiator->delegate()->isReady()); +} + +void tst_quick3dnodeinstantiator::createSingle() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("createSingle.qml")); + Quick3DNodeInstantiator *instantiator = qobject_cast<Quick3DNodeInstantiator*>(component.create()); + QVERIFY(instantiator != 0); + QCOMPARE(instantiator->isActive(), true); + QCOMPARE(instantiator->count(), 1); + QVERIFY(instantiator->delegate()->isReady()); + + QObject *object = instantiator->object(); + QVERIFY(object); + QCOMPARE(object->parent(), instantiator); + QCOMPARE(object->property("success").toBool(), true); + QCOMPARE(object->property("idx").toInt(), 0); +} + +void tst_quick3dnodeinstantiator::createMultiple() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("createMultiple.qml")); + Quick3DNodeInstantiator *instantiator = qobject_cast<Quick3DNodeInstantiator*>(component.create()); + QVERIFY(instantiator != 0); + QCOMPARE(instantiator->isActive(), true); + QCOMPARE(instantiator->count(), 10); + + for (int i = 0; i < 10; i++) { + QObject *object = instantiator->objectAt(i); + QVERIFY(object); + QCOMPARE(object->parent(), instantiator); + QCOMPARE(object->property("success").toBool(), true); + QCOMPARE(object->property("idx").toInt(), i); + } +} + +void tst_quick3dnodeinstantiator::stringModel() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("stringModel.qml")); + Quick3DNodeInstantiator *instantiator = qobject_cast<Quick3DNodeInstantiator*>(component.create()); + QVERIFY(instantiator != 0); + QCOMPARE(instantiator->isActive(), true); + QCOMPARE(instantiator->count(), 4); + + for (int i = 0; i < 4; i++) { + QObject *object = instantiator->objectAt(i); + QVERIFY(object); + QCOMPARE(object->parent(), instantiator); + QCOMPARE(object->property("success").toBool(), true); + } +} + +void tst_quick3dnodeinstantiator::activeProperty() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("inactive.qml")); + Quick3DNodeInstantiator *instantiator = qobject_cast<Quick3DNodeInstantiator*>(component.create()); + QVERIFY(instantiator != 0); + QSignalSpy activeSpy(instantiator, SIGNAL(activeChanged())); + QSignalSpy countSpy(instantiator, SIGNAL(countChanged())); + QSignalSpy objectSpy(instantiator, SIGNAL(objectChanged())); + QSignalSpy modelSpy(instantiator, SIGNAL(modelChanged())); + QCOMPARE(instantiator->isActive(), false); + QCOMPARE(instantiator->count(), 0); + QVERIFY(instantiator->delegate()->isReady()); + + QCOMPARE(activeSpy.count(), 0); + QCOMPARE(countSpy.count(), 0); + QCOMPARE(objectSpy.count(), 0); + QCOMPARE(modelSpy.count(), 0); + + instantiator->setActive(true); + QCOMPARE(instantiator->isActive(), true); + QCOMPARE(instantiator->count(), 1); + + QCOMPARE(activeSpy.count(), 1); + QCOMPARE(countSpy.count(), 1); + QCOMPARE(objectSpy.count(), 1); + QCOMPARE(modelSpy.count(), 0); + + QObject *object = instantiator->object(); + QVERIFY(object); + QCOMPARE(object->parent(), instantiator); + QCOMPARE(object->property("success").toBool(), true); + QCOMPARE(object->property("idx").toInt(), 0); +} + +void tst_quick3dnodeinstantiator::intModelChange() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("createMultiple.qml")); + Quick3DNodeInstantiator *instantiator = qobject_cast<Quick3DNodeInstantiator*>(component.create()); + QVERIFY(instantiator != 0); + QSignalSpy activeSpy(instantiator, SIGNAL(activeChanged())); + QSignalSpy countSpy(instantiator, SIGNAL(countChanged())); + QSignalSpy objectSpy(instantiator, SIGNAL(objectChanged())); + QSignalSpy modelSpy(instantiator, SIGNAL(modelChanged())); + QCOMPARE(instantiator->count(), 10); + + QCOMPARE(activeSpy.count(), 0); + QCOMPARE(countSpy.count(), 0); + QCOMPARE(objectSpy.count(), 0); + QCOMPARE(modelSpy.count(), 0); + + instantiator->setModel(QVariant(2)); + QCOMPARE(instantiator->count(), 2); + + QCOMPARE(activeSpy.count(), 0); + QCOMPARE(countSpy.count(), 1); + QCOMPARE(objectSpy.count(), 2); + QCOMPARE(modelSpy.count(), 1); + + for (int i = 0; i < 2; i++) { + QObject *object = instantiator->objectAt(i); + QVERIFY(object); + QCOMPARE(object->parent(), instantiator); + QCOMPARE(object->property("success").toBool(), true); + QCOMPARE(object->property("idx").toInt(), i); + } +} + +void tst_quick3dnodeinstantiator::createAndRemove() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("createAndRemove.qml")); + StringModel *model = new StringModel("model1"); + engine.rootContext()->setContextProperty("model1", model); + QObject *rootObject = component.create(); + QVERIFY(rootObject != 0); + + Quick3DNodeInstantiator *instantiator = + qobject_cast<Quick3DNodeInstantiator*>(rootObject->findChild<QObject*>("instantiator1")); + QVERIFY(instantiator != 0); + model->drop(1); + QVector<QString> names; + names << "Beta" << "Gamma" << "Delta"; + for (int i = 0; i < 3; i++) { + QObject *object = instantiator->objectAt(i); + QVERIFY(object); + QCOMPARE(object->property("datum").toString(), names[i]); + } +} +QTEST_MAIN(tst_quick3dnodeinstantiator) + +#include "tst_quick3dnodeinstantiator.moc" |