diff options
author | Kevin Ottens <kevin.ottens.ecortex@kdab.com> | 2014-11-21 08:38:50 +0100 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2014-11-27 15:03:46 +0100 |
commit | 01039e45417733e2d93f859f694eaba5ba7e4701 (patch) | |
tree | bd9099f57f9074b8bd73c3bcbcf934cd13bee3f8 /src/core/nodes | |
parent | a0b300075f43432d3cbece6b2d25efa246923ba0 (diff) |
Make cloning available to third party QNodes
Third party QNode subclasses won't have access to QNodePrivate, so move
the clone() operation as a protected static method on QNode itself. This
way third party nodes can implement deep copy in their copy()
implementation as expected.
Change-Id: I59d0414f4ea9c679f2b7e197ea90e36bd8a915a4
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/core/nodes')
-rw-r--r-- | src/core/nodes/qentity.cpp | 6 | ||||
-rw-r--r-- | src/core/nodes/qnode.cpp | 69 | ||||
-rw-r--r-- | src/core/nodes/qnode.h | 3 | ||||
-rw-r--r-- | src/core/nodes/qnode_p.h | 3 |
4 files changed, 38 insertions, 43 deletions
diff --git a/src/core/nodes/qentity.cpp b/src/core/nodes/qentity.cpp index 69abb83bd..a65a1d704 100644 --- a/src/core/nodes/qentity.cpp +++ b/src/core/nodes/qentity.cpp @@ -86,7 +86,7 @@ void QEntity::copy(const QNode *ref) d_func()->m_visible = entity->d_func()->m_visible; Q_FOREACH (QComponent *c, entity->d_func()->m_components) { - QNode *ccclone = QNodePrivate::get(c)->clone(); + QNode *ccclone = QNode::clone(c); addComponent(qobject_cast<QComponent *>(ccclone)); } } @@ -115,7 +115,7 @@ void QEntity::addComponent(QComponent *comp) if (d->m_changeArbiter != Q_NULLPTR) { QScenePropertyChangePtr propertyChange(new QScenePropertyChange(ComponentAdded, this)); propertyChange->setPropertyName(QByteArrayLiteral("component")); - propertyChange->setValue(QVariant::fromValue(QNodePtr(QNodePrivate::get(comp)->clone(), &QNodePrivate::nodePtrDeleter))); + propertyChange->setValue(QVariant::fromValue(QNodePtr(QNode::clone(comp), &QNodePrivate::nodePtrDeleter))); d->notifyObservers(propertyChange); } static_cast<QComponentPrivate *>(QComponentPrivate::get(comp))->addEntity(this); @@ -131,7 +131,7 @@ void QEntity::removeComponent(QComponent *comp) if (d->m_changeArbiter != Q_NULLPTR) { QScenePropertyChangePtr propertyChange(new QScenePropertyChange(ComponentRemoved, this)); - propertyChange->setValue(QVariant::fromValue(QNodePtr(QNodePrivate::get(comp)->clone(), &QNodePrivate::nodePtrDeleter))); + propertyChange->setValue(QVariant::fromValue(QNodePtr(QNode::clone(comp), &QNodePrivate::nodePtrDeleter))); propertyChange->setPropertyName(QByteArrayLiteral("component")); d->notifyObservers(propertyChange); } diff --git a/src/core/nodes/qnode.cpp b/src/core/nodes/qnode.cpp index 959cf3ab6..6df130dcb 100644 --- a/src/core/nodes/qnode.cpp +++ b/src/core/nodes/qnode.cpp @@ -92,7 +92,7 @@ void QNodePrivate::addChild(QNode *childNode) QScenePropertyChangePtr e(new QScenePropertyChange(NodeCreated, q)); e->setPropertyName(QByteArrayLiteral("node")); // We need to clone the parent of the childNode we send - QNode *parentClone = clone(); + QNode *parentClone = QNode::clone(q_func()); QNode *childClone = Q_NULLPTR; Q_FOREACH (QObject *c, parentClone->children()) { QNode *clone = qobject_cast<QNode *>(c); @@ -119,7 +119,7 @@ void QNodePrivate::removeChild(QNode *childNode) QScenePropertyChangePtr e(new QScenePropertyChange(NodeAboutToBeDeleted, q)); e->setPropertyName(QByteArrayLiteral("node")); // We need to clone the parent of the childNode we send - QNode *parentClone = clone(); + QNode *parentClone = QNode::clone(q_func()); QNode *childClone = Q_NULLPTR; Q_FOREACH (QObject *c, parentClone->children()) { QNode *clone = qobject_cast<QNode *>(c); @@ -137,41 +137,6 @@ void QNodePrivate::removeChild(QNode *childNode) childNode->d_func()->setScene(Q_NULLPTR); } -// In most cases isClone is true so that the clone isn't handled like -// a real node. If there is a need for a real clone, set isClone to false -// eg When a subtree built in the backend needs to be cloned -// in the main thread to be added to the scene graph -QNode *QNodePrivate::clone() -{ - static int clearLock = 0; - clearLock++; - - // We keep a reference of clones for the current subtree - // In order to preserve relationships when multiple entities - // reference the same component - QNode *clonedNode = QNodePrivate::m_clonesLookupTable.value(m_uuid); - if (clonedNode == Q_NULLPTR) { - Q_Q(QNode); - clonedNode = q->doClone(); - // doClone, returns new instance with content copied - // and relationships added - QNodePrivate::m_clonesLookupTable.insert(clonedNode->uuid(), clonedNode); - } - Q_FOREACH (QObject *c, q_ptr->children()) { - QNode *childNode = qobject_cast<QNode *>(c); - if (childNode != Q_NULLPTR) { - QNode *cclone = childNode->d_func()->clone(); - if (cclone != Q_NULLPTR) - cclone->setParent(clonedNode); - } - } - - if (--clearLock == 0) - QNodePrivate::m_clonesLookupTable.clear(); - - return clonedNode; -} - void QNodePrivate::removeAllChildren() { Q_FOREACH (QObject *child, q_ptr->children()) { @@ -386,6 +351,36 @@ bool QNode::blockNotifications(bool block) return previous; } +QNode *QNode::clone(QNode *node) +{ + static int clearLock = 0; + clearLock++; + + // We keep a reference of clones for the current subtree + // In order to preserve relationships when multiple entities + // reference the same component + QNode *clonedNode = QNodePrivate::m_clonesLookupTable.value(node->uuid()); + if (clonedNode == Q_NULLPTR) { + clonedNode = node->doClone(); + // doClone, returns new instance with content copied + // and relationships added + QNodePrivate::m_clonesLookupTable.insert(clonedNode->uuid(), clonedNode); + } + Q_FOREACH (QObject *c, node->children()) { + QNode *childNode = qobject_cast<QNode *>(c); + if (childNode != Q_NULLPTR) { + QNode *cclone = QNode::clone(childNode); + if (cclone != Q_NULLPTR) + cclone->setParent(clonedNode); + } + } + + if (--clearLock == 0) + QNodePrivate::m_clonesLookupTable.clear(); + + return clonedNode; +} + bool QNode::event(QEvent *e) { Q_D(QNode); diff --git a/src/core/nodes/qnode.h b/src/core/nodes/qnode.h index 01da4d961..3235d0a7e 100644 --- a/src/core/nodes/qnode.h +++ b/src/core/nodes/qnode.h @@ -81,6 +81,9 @@ public: bool blockNotifications(bool block); protected: + // Clone should only be made in the main thread + static QNode *clone(QNode *node); + QNode(QNodePrivate &dd, QNode *parent = 0); virtual void copy(const QNode *ref); virtual void sceneChangeEvent(const QSceneChangePtr &change); diff --git a/src/core/nodes/qnode_p.h b/src/core/nodes/qnode_p.h index 4271f7d13..fc238024d 100644 --- a/src/core/nodes/qnode_p.h +++ b/src/core/nodes/qnode_p.h @@ -61,9 +61,6 @@ class QT3DCORESHARED_EXPORT QNodePrivate : public QObjectPrivate, public QObserv public: QNodePrivate(QNode *qq); - // Clone should only be made in the main thread - QNode *clone(); - void setScene(QSceneInterface *scene); QSceneInterface *scene() const; |