summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2016-04-10 13:29:35 +0100
committerPaul Lemire <paul.lemire@kdab.com>2016-04-12 12:46:37 +0000
commit7985b42031e56795527fbf187deb9edd4639223b (patch)
treeb883e035eba20316bbf5a91cd4c3ce4d5d68e701 /src
parent1226b25ff68d3e8516207a02816daa2ce7155098 (diff)
Add codepath for dynamic object creation that avoids cloning
Need to do similar for destruction. Scope to optimize delivery of creation events noted in a TODO. Change-Id: I1076824f7e8a6048cdf3060d6a9df5f06361b8ef Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src')
-rw-r--r--src/core/nodes/qnode.cpp72
1 files changed, 42 insertions, 30 deletions
diff --git a/src/core/nodes/qnode.cpp b/src/core/nodes/qnode.cpp
index 71b88a2ee..fbbeef87e 100644
--- a/src/core/nodes/qnode.cpp
+++ b/src/core/nodes/qnode.cpp
@@ -53,6 +53,7 @@
#include <QMetaProperty>
#include <Qt3DCore/QComponent>
#include <Qt3DCore/private/corelogging_p.h>
+#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
#include <Qt3DCore/private/qnodevisitor_p.h>
QT_BEGIN_NAMESPACE
@@ -80,40 +81,51 @@ QNodePrivate::QNodePrivate()
void QNodePrivate::_q_addChild(QNode *childNode)
{
Q_ASSERT(childNode);
- if (childNode == q_func())
- return ;
-
- // If the scene is null it means that the current node is part of a subtree
- // that has been pre-prepared. Therefore the node shouldn't be added by
- // itself but only when the root of the said subtree is inserted into an
- // existing node whose m_scene member is valid
- if (m_scene == Q_NULLPTR)
- return;
-
- QNodeVisitor visitor;
- // Recursively set scene and change arbiter for the node subtree
- visitor.traverse(childNode, this, &QNodePrivate::setSceneHelper);
- // We notify only if we have a QChangeArbiter
- if (m_changeArbiter != Q_NULLPTR) {
- QScenePropertyChangePtr e(new QScenePropertyChange(NodeCreated, QSceneChange::Node, m_id));
- e->setPropertyName("node");
- // We need to clone the parent of the childNode we send
- QNode *parentClone = QNode::clone(q_func());
- QNode *childClone = Q_NULLPTR;
- for (QObject *c : parentClone->children()) {
- QNode *clone = qobject_cast<QNode *>(c);
- if (clone != Q_NULLPTR && clone->id() == childNode->id()) {
- childClone = clone;
- break;
+ if (ms_useCloning) {
+ if (childNode == q_func())
+ return;
+
+ // If the scene is null it means that the current node is part of a subtree
+ // that has been pre-prepared. Therefore the node shouldn't be added by
+ // itself but only when the root of the said subtree is inserted into an
+ // existing node whose m_scene member is valid
+ if (m_scene == Q_NULLPTR)
+ return;
+
+ QNodeVisitor visitor;
+ // Recursively set scene and change arbiter for the node subtree
+ visitor.traverse(childNode, this, &QNodePrivate::setSceneHelper);
+
+ // We notify only if we have a QChangeArbiter
+ if (m_changeArbiter != Q_NULLPTR) {
+ QScenePropertyChangePtr e(new QScenePropertyChange(NodeCreated, QSceneChange::Node, m_id));
+ e->setPropertyName("node");
+ // We need to clone the parent of the childNode we send
+ QNode *parentClone = QNode::clone(q_func());
+ QNode *childClone = Q_NULLPTR;
+ for (QObject *c : parentClone->children()) {
+ QNode *clone = qobject_cast<QNode *>(c);
+ if (clone != Q_NULLPTR && clone->id() == childNode->id()) {
+ childClone = clone;
+ break;
+ }
}
+ e->setValue(QVariant::fromValue(QNodePtr(childClone, &QNodePrivate::nodePtrDeleter)));
+ notifyObservers(e);
}
- e->setValue(QVariant::fromValue(QNodePtr(childClone, &QNodePrivate::nodePtrDeleter)));
- notifyObservers(e);
- }
- // Handle Entity - Components
- visitor.traverse(childNode, this, &QNodePrivate::addEntityComponentToScene);
+ // Handle Entity - Components
+ visitor.traverse(childNode, this, &QNodePrivate::addEntityComponentToScene);
+ } else {
+ QNodeCreatedChangeGenerator generator(childNode);
+ const auto creationChanges = generator.creationChanges();
+ // TODO: Wrap all creation changes into a single aggregate change to avoid
+ // hamemring the change arbiter when all of these need to be delivered to
+ // all of the aspects.
+ for (const auto &change : creationChanges)
+ notifyObservers(change);
+ }
}
// Called by setParent or cleanup (main thread) (could be other thread if created on the backend in a job)