summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSvenn-Arne Dragly <svenn-arne.dragly@qt.io>2018-07-05 13:06:24 +0200
committerSvenn-Arne Dragly <svenn-arne.dragly@qt.io>2018-09-03 14:31:52 +0000
commit4a38107bc12f8c3d9d290d4649c8606ea8b1376d (patch)
tree2ca2e0530cca74456b36a105c68d88fe17543a3e
parent7f3d98c5326de1a6800f5d91b9f53874b4a71fa7 (diff)
Add private API to access child nodes of QEntity and QFrameGraphNode
This opens up for reduced bookeeping on the backend, and is used by the experimental Dragon render aspect, which is currently being implemented in qt3d-runtime. Change-Id: I4cc2e98e4e0e7e8d456ed11c4fbc48db5c93f2a2 Reviewed-by: Paul Lemire <paul.lemire@kdab.com> (cherry picked from commit 77e418fde850c86e39d9dd8528876599fbe9dc34) Reviewed-by: Mike Krus <mike.krus@kdab.com> Reviewed-by: Christian Stromme <christian.stromme@qt.io>
-rw-r--r--src/core/nodes/qentity.cpp16
-rw-r--r--src/core/nodes/qentity_p.h1
-rw-r--r--src/render/framegraph/qframegraphnode.cpp36
-rw-r--r--src/render/framegraph/qframegraphnode_p.h5
-rw-r--r--src/render/framegraph/qframegraphnodecreatedchange.cpp3
-rw-r--r--src/render/framegraph/qframegraphnodecreatedchange_p.h11
-rw-r--r--tests/auto/core/qentity/tst_qentity.cpp46
-rw-r--r--tests/auto/render/qframegraphnode/tst_qframegraphnode.cpp47
8 files changed, 147 insertions, 18 deletions
diff --git a/src/core/nodes/qentity.cpp b/src/core/nodes/qentity.cpp
index d0ed58efd..64ea65087 100644
--- a/src/core/nodes/qentity.cpp
+++ b/src/core/nodes/qentity.cpp
@@ -52,6 +52,8 @@
#include <Qt3DCore/private/qcomponent_p.h>
#include <Qt3DCore/private/qscene_p.h>
+#include <QQueue>
+
QT_BEGIN_NAMESPACE
namespace Qt3DCore {
@@ -233,6 +235,20 @@ QNodeCreatedChangeBasePtr QEntity::createNodeCreationChange() const
Q_D(const QEntity);
data.parentEntityId = parentEntity() ? parentEntity()->id() : Qt3DCore::QNodeId();
+
+ // Find all child entities
+ QQueue<QNode *> queue;
+ queue.append(childNodes().toList());
+ data.childEntityIds.reserve(queue.size());
+ while (!queue.isEmpty()) {
+ auto *child = queue.dequeue();
+ auto *childEntity = qobject_cast<QEntity *>(child);
+ if (childEntity != nullptr)
+ data.childEntityIds.push_back(childEntity->id());
+ else
+ queue.append(child->childNodes().toList());
+ }
+
data.componentIdsAndTypes.reserve(d->m_components.size());
const QComponentVector &components = d->m_components;
for (QComponent *c : components) {
diff --git a/src/core/nodes/qentity_p.h b/src/core/nodes/qentity_p.h
index ef35d83a1..8fe03cd6b 100644
--- a/src/core/nodes/qentity_p.h
+++ b/src/core/nodes/qentity_p.h
@@ -91,6 +91,7 @@ struct QEntityData
{
Qt3DCore::QNodeId parentEntityId;
QVector<QNodeIdTypePair> componentIdsAndTypes;
+ Qt3DCore::QNodeIdVector childEntityIds;
};
}
diff --git a/src/render/framegraph/qframegraphnode.cpp b/src/render/framegraph/qframegraphnode.cpp
index 0a60edef7..3cf19d0d8 100644
--- a/src/render/framegraph/qframegraphnode.cpp
+++ b/src/render/framegraph/qframegraphnode.cpp
@@ -41,6 +41,12 @@
#include "qframegraphnode_p.h"
#include <Qt3DRender/qframegraphnodecreatedchange.h>
+#include <Qt3DCore/QNode>
+
+#include <QQueue>
+
+using namespace Qt3DCore;
+
QT_BEGIN_NAMESPACE
namespace Qt3DRender {
@@ -190,7 +196,10 @@ QFrameGraphNode::~QFrameGraphNode()
}
/*!
- Returns a pointer to the parent.
+ Returns a pointer to the parent frame graph node.
+
+ If the parent of this node is not a frame graph node,
+ this method will recursively look for a parent node that is a frame graph node.
*/
QFrameGraphNode *QFrameGraphNode::parentFrameGraphNode() const
{
@@ -205,6 +214,31 @@ QFrameGraphNode *QFrameGraphNode::parentFrameGraphNode() const
return parentFGNode;
}
+/*!
+ * Returns a list of the children that are frame graph nodes.
+ * If this function encounters a child node that is not a frame graph node,
+ * it will go through the children of the child node and look for frame graph nodes.
+ * If any of these are not frame graph nodes, they will be further searched as
+ * if they were direct children of this node.
+ */
+QVector<QFrameGraphNode *> QFrameGraphNodePrivate::childFrameGraphNodes() const
+{
+ Q_Q(const QFrameGraphNode);
+ QVector<QFrameGraphNode *> result;
+ QQueue<QNode *> queue;
+ queue.append(q->childNodes().toList());
+ result.reserve(queue.size());
+ while (!queue.isEmpty()) {
+ auto *child = queue.dequeue();
+ auto *childFGNode = qobject_cast<QFrameGraphNode *>(child);
+ if (childFGNode != nullptr)
+ result.push_back(childFGNode);
+ else
+ queue.append(child->childNodes().toList());
+ }
+ return result;
+}
+
/*! \internal */
QFrameGraphNode::QFrameGraphNode(QFrameGraphNodePrivate &dd, QNode *parent)
: QNode(dd, parent)
diff --git a/src/render/framegraph/qframegraphnode_p.h b/src/render/framegraph/qframegraphnode_p.h
index 00cc53626..c03017638 100644
--- a/src/render/framegraph/qframegraphnode_p.h
+++ b/src/render/framegraph/qframegraphnode_p.h
@@ -65,9 +65,12 @@ class QFrameGraphNodePrivate : public Qt3DCore::QNodePrivate
{
public:
QFrameGraphNodePrivate();
+ QVector<QFrameGraphNode *> childFrameGraphNodes() const;
+
+ static QFrameGraphNodePrivate *get(QFrameGraphNode *node) { return node->d_func(); }
+ static const QFrameGraphNodePrivate *get(const QFrameGraphNode *node) { return node->d_func(); }
Q_DECLARE_PUBLIC(QFrameGraphNode)
- QList<QFrameGraphNode *> m_fgChildren;
};
} // namespace Qt3DRender
diff --git a/src/render/framegraph/qframegraphnodecreatedchange.cpp b/src/render/framegraph/qframegraphnodecreatedchange.cpp
index ef51d5228..464c98bc3 100644
--- a/src/render/framegraph/qframegraphnodecreatedchange.cpp
+++ b/src/render/framegraph/qframegraphnodecreatedchange.cpp
@@ -36,7 +36,9 @@
#include "qframegraphnodecreatedchange.h"
#include "qframegraphnodecreatedchange_p.h"
+
#include <Qt3DRender/qframegraphnode.h>
+#include <Qt3DRender/private/qframegraphnode_p.h>
QT_BEGIN_NAMESPACE
@@ -45,6 +47,7 @@ namespace Qt3DRender {
QFrameGraphNodeCreatedChangeBasePrivate::QFrameGraphNodeCreatedChangeBasePrivate(const QFrameGraphNode *node)
: Qt3DCore::QNodeCreatedChangeBasePrivate(node)
, m_parentFrameGraphNodeId(Qt3DCore::qIdForNode(node->parentFrameGraphNode()))
+ , m_childFrameGraphNodeIds(Qt3DCore::qIdsForNodes(QFrameGraphNodePrivate::get(node)->childFrameGraphNodes()))
{
}
diff --git a/src/render/framegraph/qframegraphnodecreatedchange_p.h b/src/render/framegraph/qframegraphnodecreatedchange_p.h
index 9aa396b8f..c0437afc5 100644
--- a/src/render/framegraph/qframegraphnodecreatedchange_p.h
+++ b/src/render/framegraph/qframegraphnodecreatedchange_p.h
@@ -49,6 +49,7 @@
//
#include <Qt3DCore/private/qnodecreatedchange_p.h>
+#include <Qt3DRender/qframegraphnodecreatedchange.h>
QT_BEGIN_NAMESPACE
@@ -62,6 +63,16 @@ public:
QFrameGraphNodeCreatedChangeBasePrivate(const QFrameGraphNode *node);
Qt3DCore::QNodeId m_parentFrameGraphNodeId;
+ Qt3DCore::QNodeIdVector m_childFrameGraphNodeIds;
+
+ static QFrameGraphNodeCreatedChangeBasePrivate *get(QFrameGraphNodeCreatedChangeBase *change)
+ {
+ return change->d_func();
+ }
+ static const QFrameGraphNodeCreatedChangeBasePrivate *get(const QFrameGraphNodeCreatedChangeBase *change)
+ {
+ return change->d_func();
+ }
};
} // Qt3DRender
diff --git a/tests/auto/core/qentity/tst_qentity.cpp b/tests/auto/core/qentity/tst_qentity.cpp
index efebb26ef..e27cd1fc9 100644
--- a/tests/auto/core/qentity/tst_qentity.cpp
+++ b/tests/auto/core/qentity/tst_qentity.cpp
@@ -556,30 +556,55 @@ void tst_Entity::removeSeveralTimesSameComponent()
void tst_Entity::checkCloning_data()
{
QTest::addColumn<Qt3DCore::QEntity *>("entity");
+ QTest::addColumn<QVector<QNodeId>>("childEntityIds");
+ QTest::addColumn<int>("creationChangeCount");
- QTest::newRow("defaultConstructed") << new MyEntity();
+ {
+ QTest::newRow("defaultConstructed") << new MyEntity() << QVector<QNodeId>() << 1;
+ }
+
+ {
+ Qt3DCore::QEntity *entityWithComponents = new MyEntity();
+ Qt3DCore::QComponent *component1 = new MyQComponent();
+ Qt3DCore::QComponent *component2 = new MyQComponent();
+ Qt3DCore::QComponent *component3 = new MyQComponent();
+ entityWithComponents->addComponent(component1);
+ entityWithComponents->addComponent(component2);
+ entityWithComponents->addComponent(component3);
+ QTest::newRow("entityWithComponents") << entityWithComponents << QVector<QNodeId>() << 4;
+ }
- Qt3DCore::QEntity *entityWithComponents = new MyEntity();
- Qt3DCore::QComponent *component1 = new MyQComponent();
- Qt3DCore::QComponent *component2 = new MyQComponent();
- Qt3DCore::QComponent *component3 = new MyQComponent();
- entityWithComponents->addComponent(component1);
- entityWithComponents->addComponent(component2);
- entityWithComponents->addComponent(component3);
- QTest::newRow("entityWithComponents") << entityWithComponents;
+ {
+ Qt3DCore::QEntity *entityWithChildren = new MyEntity();
+ Qt3DCore::QEntity *child1 = new MyEntity(entityWithChildren);
+ Qt3DCore::QEntity *child2 = new MyEntity(entityWithChildren);
+ QVector<QNodeId> childIds = {child1->id(), child2->id()};
+ QTest::newRow("entityWithChildren") << entityWithChildren << childIds << 3;
+ }
+
+ {
+ Qt3DCore::QEntity *entityWithNestedChildren = new MyEntity();
+ Qt3DCore::QEntity *child = new MyEntity(entityWithNestedChildren);
+ Qt3DCore::QNode *dummy = new Qt3DCore::QNode(entityWithNestedChildren);
+ Qt3DCore::QEntity *grandChild = new MyEntity(entityWithNestedChildren);
+ QVector<QNodeId> childIds = {child->id(), grandChild->id()};
+ QTest::newRow("entityWithNestedChildren") << entityWithNestedChildren << childIds << 4;
+ }
}
void tst_Entity::checkCloning()
{
// GIVEN
QFETCH(Qt3DCore::QEntity *, entity);
+ QFETCH(QVector<QNodeId>, childEntityIds);
+ QFETCH(int, creationChangeCount);
// WHEN
Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(entity);
QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges = creationChangeGenerator.creationChanges();
// THEN
- QCOMPARE(creationChanges.size(), 1 + entity->components().size());
+ QCOMPARE(creationChanges.size(), creationChangeCount);
const Qt3DCore::QNodeCreatedChangePtr<Qt3DCore::QEntityData> creationChangeData =
qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DCore::QEntityData>>(creationChanges.first());
@@ -591,6 +616,7 @@ void tst_Entity::checkCloning()
QCOMPARE(creationChangeData->metaObject(), entity->metaObject());
QCOMPARE(creationChangeData->parentId(), entity->parentNode() ? entity->parentNode()->id() : Qt3DCore::QNodeId());
QCOMPARE(cloneData.parentEntityId, entity->parentEntity() ? entity->parentEntity()->id() : Qt3DCore::QNodeId());
+ QCOMPARE(cloneData.childEntityIds, childEntityIds);
QCOMPARE(cloneData.componentIdsAndTypes.size(), entity->components().size());
const QVector<Qt3DCore::QComponent *> &components = entity->components();
diff --git a/tests/auto/render/qframegraphnode/tst_qframegraphnode.cpp b/tests/auto/render/qframegraphnode/tst_qframegraphnode.cpp
index b06da033c..1e19d8609 100644
--- a/tests/auto/render/qframegraphnode/tst_qframegraphnode.cpp
+++ b/tests/auto/render/qframegraphnode/tst_qframegraphnode.cpp
@@ -35,6 +35,8 @@
#include <Qt3DRender/qframegraphnode.h>
#include <Qt3DRender/private/qframegraphnode_p.h>
#include <Qt3DRender/qframegraphnodecreatedchange.h>
+#include <Qt3DRender/private/qframegraphnodecreatedchange_p.h>
+
#include "testpostmanarbiter.h"
class MyFrameGraphNode : public Qt3DRender::QFrameGraphNode
@@ -64,21 +66,48 @@ private Q_SLOTS:
void checkCloning_data()
{
QTest::addColumn<Qt3DRender::QFrameGraphNode *>("frameGraphNode");
+ QTest::addColumn<QVector<Qt3DCore::QNodeId>>("childFrameGraphNodeIds");
QTest::addColumn<bool>("enabled");
+ QTest::addColumn<int>("creationChangeCount");
+
+ QVector<Qt3DCore::QNodeId> noChildIds;
+
+ {
+ Qt3DRender::QFrameGraphNode *defaultConstructed = new MyFrameGraphNode();
+ QTest::newRow("defaultConstructed") << defaultConstructed << noChildIds << true << 1;
+ }
+
+ {
+ Qt3DRender::QFrameGraphNode *disabledFrameGraphNode = new MyFrameGraphNode();
+ disabledFrameGraphNode->setEnabled(false);
+ QTest::newRow("allBuffers") << disabledFrameGraphNode << noChildIds << false << 1;
+ }
- Qt3DRender::QFrameGraphNode *defaultConstructed = new MyFrameGraphNode();
- QTest::newRow("defaultConstructed") << defaultConstructed << true;
+ {
+ Qt3DRender::QFrameGraphNode *nodeWithChildren = new MyFrameGraphNode();
+ Qt3DRender::QFrameGraphNode *child1 = new MyFrameGraphNode(nodeWithChildren);
+ Qt3DRender::QFrameGraphNode *child2 = new MyFrameGraphNode(nodeWithChildren);
+ QVector<Qt3DCore::QNodeId> childIds = {child1->id(), child2->id()};
+ QTest::newRow("nodeWithChildren") << nodeWithChildren << childIds << true << 3;
+ }
- Qt3DRender::QFrameGraphNode *disabledFrameGraphNode = new MyFrameGraphNode();
- disabledFrameGraphNode->setEnabled(false);
- QTest::newRow("allBuffers") << disabledFrameGraphNode << false;
+ {
+ Qt3DRender::QFrameGraphNode *nodeWithNestedChildren = new MyFrameGraphNode();
+ Qt3DRender::QFrameGraphNode *child = new MyFrameGraphNode(nodeWithNestedChildren);
+ Qt3DCore::QNode *dummy = new Qt3DCore::QNode(nodeWithNestedChildren);
+ Qt3DRender::QFrameGraphNode *grandChild = new MyFrameGraphNode(nodeWithNestedChildren);
+ QVector<Qt3DCore::QNodeId> childIds = {child->id(), grandChild->id()};
+ QTest::newRow("nodeWithNestedChildren") << nodeWithNestedChildren << childIds << true << 4;
+ }
}
void checkCloning()
{
// GIVEN
QFETCH(Qt3DRender::QFrameGraphNode *, frameGraphNode);
+ QFETCH(QVector<Qt3DCore::QNodeId>, childFrameGraphNodeIds);
QFETCH(bool, enabled);
+ QFETCH(int, creationChangeCount);
// THEN
QCOMPARE(frameGraphNode->isEnabled(), enabled);
@@ -88,7 +117,7 @@ private Q_SLOTS:
QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges = creationChangeGenerator.creationChanges();
// THEN
- QCOMPARE(creationChanges.size(), 1);
+ QCOMPARE(creationChanges.size(), creationChangeCount);
const Qt3DCore::QNodeCreatedChangeBasePtr creationChangeData = creationChanges.first();
// THEN
@@ -96,6 +125,12 @@ private Q_SLOTS:
QCOMPARE(frameGraphNode->isEnabled(), creationChangeData->isNodeEnabled());
QCOMPARE(frameGraphNode->metaObject(), creationChangeData->metaObject());
+ // THEN
+ Qt3DRender::QFrameGraphNodeCreatedChangeBasePtr frameGraphNodeCreatedChange = qSharedPointerCast<Qt3DRender::QFrameGraphNodeCreatedChangeBase>(creationChangeData);
+ Qt3DRender::QFrameGraphNodeCreatedChangeBasePrivate *creationChangeDataPrivate = Qt3DRender::QFrameGraphNodeCreatedChangeBasePrivate::get(frameGraphNodeCreatedChange.get());
+ QCOMPARE(creationChangeDataPrivate->m_parentFrameGraphNodeId, frameGraphNode->parentNode() ? frameGraphNode->parentNode()->id() : Qt3DCore::QNodeId());
+ QCOMPARE(creationChangeDataPrivate->m_childFrameGraphNodeIds, childFrameGraphNodeIds);
+
delete frameGraphNode;
}