diff options
author | Aurélien Brooke <aurelien@bahiasoft.fr> | 2024-01-15 15:02:01 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2024-01-16 01:59:41 +0000 |
commit | 6907e014f23fabdf8cf1637f6cc200adb84dd285 (patch) | |
tree | 9cac13b42fbc772321388c739aa6f87205141517 | |
parent | 183eac3d34ee6688dbe9dc3e18622020d798eb4e (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.cpp | 5 |
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); |