diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2018-02-05 13:01:09 +0000 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2018-02-05 15:42:29 +0000 |
commit | 0403ee45736241aa621eb3d38880a4fff571fd96 (patch) | |
tree | 94650145a3b7e2517dfcf29d33f97859933b518d /src/core/nodes | |
parent | 04afcf1cb9e79697360baa01a97a26815237eba1 (diff) | |
parent | ceae743678d41a58154612781e896c04c87a8c4f (diff) |
Merge remote-tracking branch 'origin/5.9' into 5.10
Conflicts:
.qmake.conf
src/render/backend/trianglesvisitor.cpp
src/render/backend/uniform.cpp
src/render/jobs/calcboundingvolumejob.cpp
src/render/jobs/pickboundingvolumejob.cpp
src/render/jobs/pickboundingvolumeutils.cpp
Change-Id: Ib8305011c51710a3538c0b29f7022388f5244a38
Diffstat (limited to 'src/core/nodes')
-rw-r--r-- | src/core/nodes/qcomponent.cpp | 4 | ||||
-rw-r--r-- | src/core/nodes/qnode.cpp | 64 | ||||
-rw-r--r-- | src/core/nodes/qnode_p.h | 4 |
3 files changed, 52 insertions, 20 deletions
diff --git a/src/core/nodes/qcomponent.cpp b/src/core/nodes/qcomponent.cpp index 8e337adf6..f4e59e058 100644 --- a/src/core/nodes/qcomponent.cpp +++ b/src/core/nodes/qcomponent.cpp @@ -73,7 +73,7 @@ void QComponentPrivate::addEntity(QEntity *entity) m_scene->addEntityForComponent(m_id, entity->id()); } - const auto componentAddedChange = QComponentAddedChangePtr::create(entity, q); + const auto componentAddedChange = QComponentAddedChangePtr::create(q, entity); notifyObservers(componentAddedChange); Q_EMIT q->addedToEntity(entity); } @@ -86,7 +86,7 @@ void QComponentPrivate::removeEntity(QEntity *entity) m_entities.removeAll(entity); - const auto componentRemovedChange = QComponentRemovedChangePtr::create(entity, q); + const auto componentRemovedChange = QComponentRemovedChangePtr::create(q, entity); notifyObservers(componentRemovedChange); Q_EMIT q->removedFromEntity(entity); } diff --git a/src/core/nodes/qnode.cpp b/src/core/nodes/qnode.cpp index dbe3fd102..083fda7df 100644 --- a/src/core/nodes/qnode.cpp +++ b/src/core/nodes/qnode.cpp @@ -74,6 +74,7 @@ QNodePrivate::QNodePrivate() , m_blockNotifications(false) , m_hasBackendNode(false) , m_enabled(true) + , m_notifiedParent(false) , m_defaultPropertyTrackMode(QNode::TrackFinalValues) , m_propertyChangesSetup(false) , m_signals(this) @@ -210,13 +211,19 @@ void QNodePrivate::_q_addChild(QNode *childNode) Q_ASSERT(childNode); Q_ASSERT_X(childNode->parent() == q_func(), Q_FUNC_INFO, "not a child of this node"); + // Have we already notified the parent about its new child? If so, bail out + // early so that we do not send more than one new child event to the backend + QNodePrivate *childD = QNodePrivate::get(childNode); + if (childD->m_notifiedParent == true) + return; + // Store our id as the parentId in the child so that even if the child gets // removed from the scene as part of the destruction of the parent, when the // parent's children are deleted in the QObject dtor, we still have access to // the parentId. If we didn't store this, we wouldn't have access at that time // because the parent would then only be a QObject, the QNode part would have // been destroyed already. - QNodePrivate::get(childNode)->m_parentId = m_id; + childD->m_parentId = m_id; if (!m_scene) return; @@ -224,6 +231,11 @@ void QNodePrivate::_q_addChild(QNode *childNode) // We need to send a QPropertyNodeAddedChange to the backend // to notify the backend that we have a new child if (m_changeArbiter != nullptr) { + // Flag that we have notified the parent. We do this immediately before + // creating the change because that recurses back into this function and + // we need to catch that to avoid sending more than one new child event + // to the backend. + childD->m_notifiedParent = true; const auto change = QPropertyNodeAddedChangePtr::create(m_id, childNode); change->setPropertyName("children"); notifyObservers(change); @@ -299,6 +311,9 @@ void QNodePrivate::_q_setParentHelper(QNode *parent) notifyDestructionChangesAndRemoveFromScene(); } + // Flag that we need to notify any new parent + m_notifiedParent = false; + // Basically QObject::setParent but for QObjectPrivate QObjectPrivate::setParent_helper(parent); QNode *newParentNode = q->parentNode(); @@ -373,28 +388,43 @@ void QNodePrivate::propertyChanged(int propertyIndex) if (m_blockNotifications) return; + const auto toBackendValue = [this](const QVariant &data) -> QVariant + { + 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 + // 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. + if (node) + QNodePrivate::get(node)->_q_postConstructorInit(); + + const QNodeId id = node ? node->id() : QNodeId(); + return QVariant::fromValue(id); + } + + return data; + }; + Q_Q(QNode); const QMetaProperty property = q->metaObject()->property(propertyIndex); const QVariant data = property.read(q); - 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 - // 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. - if (node) - QNodePrivate::get(node)->_q_postConstructorInit(); - - const QNodeId id = node ? node->id() : QNodeId(); - notifyPropertyChange(property.name(), QVariant::fromValue(id)); + + if (data.type() == QVariant::List) { + QSequentialIterable iterable = data.value<QSequentialIterable>(); + QVariantList variants; + variants.reserve(iterable.size()); + for (const auto &v : iterable) + variants.append(toBackendValue(v)); + notifyPropertyChange(property.name(), variants); } else { - notifyPropertyChange(property.name(), data); + notifyPropertyChange(property.name(), toBackendValue(data)); } } diff --git a/src/core/nodes/qnode_p.h b/src/core/nodes/qnode_p.h index ad9d2376e..87a0226f1 100644 --- a/src/core/nodes/qnode_p.h +++ b/src/core/nodes/qnode_p.h @@ -100,6 +100,7 @@ public: bool m_blockNotifications; bool m_hasBackendNode; bool m_enabled; + bool m_notifiedParent; QNode::PropertyTrackingMode m_defaultPropertyTrackMode; QHash<QString, QNode::PropertyTrackingMode> m_trackedPropertiesOverrides; @@ -137,10 +138,11 @@ public: static const QMetaObject *findStaticMetaObject(const QMetaObject *metaObject); + void _q_postConstructorInit(); + private: void notifyCreationChange(); void notifyDestructionChangesAndRemoveFromScene(); - void _q_postConstructorInit(); void _q_addChild(QNode *childNode); void _q_removeChild(QNode *childNode); void _q_setParentHelper(QNode *parent); |