diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2016-04-10 13:29:35 +0100 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2016-04-12 12:46:37 +0000 |
commit | 7985b42031e56795527fbf187deb9edd4639223b (patch) | |
tree | b883e035eba20316bbf5a91cd4c3ce4d5d68e701 /src | |
parent | 1226b25ff68d3e8516207a02816daa2ce7155098 (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.cpp | 72 |
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) |