diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2019-04-02 15:08:50 +0200 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2019-04-02 15:25:12 +0200 |
commit | f3259300bde381b10cb737735fe19b039c969782 (patch) | |
tree | 43c70cfe34cbf08947752653e98ccb777c1c9521 /src/core/nodes | |
parent | 6f7ac29268df048b5f23ad26c47efcbfdfdb3585 (diff) | |
parent | 59d26d3e9411150c7ed0fb0cf68d48988c8dbf59 (diff) |
Merge branch '5.12' into 5.13
Change-Id: If17511da64dd666a536408aa3cb3178ef6db0403
Diffstat (limited to 'src/core/nodes')
-rw-r--r-- | src/core/nodes/qentity.cpp | 2 | ||||
-rw-r--r-- | src/core/nodes/qnode.cpp | 35 | ||||
-rw-r--r-- | src/core/nodes/qnode_p.h | 1 |
3 files changed, 32 insertions, 6 deletions
diff --git a/src/core/nodes/qentity.cpp b/src/core/nodes/qentity.cpp index 3c8805a67..69d774dd1 100644 --- a/src/core/nodes/qentity.cpp +++ b/src/core/nodes/qentity.cpp @@ -159,6 +159,8 @@ void QEntity::addComponent(QComponent *comp) if (!comp->parent()) comp->setParent(this); + QNodePrivate::get(comp)->_q_ensureBackendNodeCreated(); + d->m_components.append(comp); // Ensures proper bookkeeping diff --git a/src/core/nodes/qnode.cpp b/src/core/nodes/qnode.cpp index 83ac49471..c2373b805 100644 --- a/src/core/nodes/qnode.cpp +++ b/src/core/nodes/qnode.cpp @@ -394,15 +394,15 @@ void QNodePrivate::propertyChanged(int propertyIndex) if (data.canConvert<QNode*>()) { QNode *node = data.value<QNode*>(); - // Ensure the node has issued a node creation change. We can end - // up here if a newly created node with a parent is immediately set + // Ensure the node and all ancestors have issued their node creation changes. + // We can end up here if a newly created node with a parent is immediately set // as a property on another node. In this case the deferred call to // _q_postConstructorInit() will not have happened yet as the event - // loop will still be blocked. So force it here and we catch this - // eventuality in the _q_postConstructorInit() function so that we - // do not repeat the creation and new child scene change events. + // loop will still be blocked. We need to do this for all ancestors, + // since the subtree of this node otherwise can end up on the backend + // with a reference to a non-existent parent. if (node) - QNodePrivate::get(node)->_q_postConstructorInit(); + QNodePrivate::get(node)->_q_ensureBackendNodeCreated(); const QNodeId id = node ? node->id() : QNodeId(); return QVariant::fromValue(id); @@ -506,6 +506,29 @@ void QNodePrivate::setArbiter(QLockableObserverInterface *arbiter) } /*! + * \internal + * Makes sure this node has a backend by traversing the tree up to the most distant ancestor + * without a backend node and initializing that node. This is done to make sure the parent nodes + * are always created before the child nodes, since child nodes reference parent nodes at creation + * time. + */ +void QNodePrivate::_q_ensureBackendNodeCreated() +{ + if (m_hasBackendNode) + return; + + Q_Q(QNode); + + QNode *nextNode = q; + QNode *topNodeWithoutBackend = nullptr; + while (nextNode != nullptr && !QNodePrivate::get(nextNode)->m_hasBackendNode) { + topNodeWithoutBackend = nextNode; + nextNode = nextNode->parentNode(); + } + QNodePrivate::get(topNodeWithoutBackend)->_q_postConstructorInit(); +} + +/*! \class Qt3DCore::QNode \inherits QObject diff --git a/src/core/nodes/qnode_p.h b/src/core/nodes/qnode_p.h index 73893cc1e..6ffb19ce8 100644 --- a/src/core/nodes/qnode_p.h +++ b/src/core/nodes/qnode_p.h @@ -152,6 +152,7 @@ public: static const QMetaObject *findStaticMetaObject(const QMetaObject *metaObject); void _q_postConstructorInit(); + void _q_ensureBackendNodeCreated(); private: void notifyCreationChange(); |