summaryrefslogtreecommitdiffstats
path: root/src/core/nodes
diff options
context:
space:
mode:
authorKevin Ottens <kevin.ottens.ecortex@kdab.com>2014-11-21 08:38:50 +0100
committerSean Harmer <sean.harmer@kdab.com>2014-11-27 15:03:46 +0100
commit01039e45417733e2d93f859f694eaba5ba7e4701 (patch)
treebd9099f57f9074b8bd73c3bcbcf934cd13bee3f8 /src/core/nodes
parenta0b300075f43432d3cbece6b2d25efa246923ba0 (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.cpp6
-rw-r--r--src/core/nodes/qnode.cpp69
-rw-r--r--src/core/nodes/qnode.h3
-rw-r--r--src/core/nodes/qnode_p.h3
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;