summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAurélien Brooke <aurelien@bahiasoft.fr>2024-01-15 15:02:01 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2024-01-16 01:59:41 +0000
commit6907e014f23fabdf8cf1637f6cc200adb84dd285 (patch)
tree9cac13b42fbc772321388c739aa6f87205141517
parent183eac3d34ee6688dbe9dc3e18622020d798eb4e (diff)
Fix the creation of backend nodes if using the parent entity constructor
On an already running simulation, when adding entities with the constructor taking a parent node, no backend node was created if a component was previously added to the tree with QEntity::addComponent(). In QEntity::addComponent(), we call _q_ensureBackendNodeCreated() on the component, creating the backend nodes of the whole tree, which marks them with m_hasBackendNode = true. Then, when we try to create a new entity by using the constructor which takes a parent entity (e.g. `auto positions = new QAttribute(entity);`), we effectively call NodePostConstructorInit::addNode(). But since the parent node is still in the m_nodesToConstruct queue (we didn't return to the event loop yet), the function did not queue the new entity for backend node creation. To fix this, allow the new entity to be added in the creation queue, even if the parent in the queue has already been created itself (m_hasBackendNode == true). * The bug does not happen when creating the whole tree in advance and then calling setRootEntity(). * It also does not happen if not calling QEntity::addComponent(), because then the parent backend node is not created, so it will create its child one automatically once itself is created. * Finally, not giving a parent node and explicitly calling setParent() later was also working. QTBUG-120964 contains an example materializing the crash, caused by the missing Attribute backend node. Fixes: QTBUG-77139 Fixes: QTBUG-100387 Fixes: QTBUG-120964 Change-Id: I908f1b5ecc2a845564d38bc634a2c645ad1a8074 Reviewed-by: Mike Krus <mike.krus@kdab.com> (cherry picked from commit 0d4a4a9eff4fad9e81e5ca5fee441ce3bd367835) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> (cherry picked from commit 14264f82e3da395bcd9ff3d51fb6c491114c92c7)
-rw-r--r--src/core/nodes/qnode.cpp5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/core/nodes/qnode.cpp b/src/core/nodes/qnode.cpp
index 7858a1c54..3c2bf3259 100644
--- a/src/core/nodes/qnode.cpp
+++ b/src/core/nodes/qnode.cpp
@@ -849,7 +849,10 @@ void NodePostConstructorInit::addNode(QNode *node)
while (nextNode != nullptr && !m_nodesToConstruct.contains(QNodePrivate::get(nextNode)))
nextNode = nextNode->parentNode();
- if (!nextNode) {
+ // An ancestor in the m_nodesToConstruct may already have been created (m_hasBackendNode)
+ // at this point (e.g. when a QComponent calls _q_ensureBackendNodeCreated()),
+ // that's why we also queue a creation request in this case.
+ if (!nextNode || QNodePrivate::get(nextNode)->m_hasBackendNode) {
m_nodesToConstruct.append(QNodePrivate::get(node));
if (!m_requestedProcessing){
QMetaObject::invokeMethod(this, "processNodes", Qt::QueuedConnection);