diff options
author | Mike Krus <mike.krus@kdab.com> | 2019-09-17 15:47:59 +0100 |
---|---|---|
committer | Mike Krus <mike.krus@kdab.com> | 2019-10-04 07:10:20 +0100 |
commit | 53efe4ea5a26e67b5a37a7a79744872af1ec34bb (patch) | |
tree | d513b42dfabcb87cbb40e9f9a3397a2555ecfda2 /src/core/aspects/qabstractaspect.cpp | |
parent | 703f7964f88df116d0dd3fdd0a8005b9abef8737 (diff) |
Remove use of node/components added/removed messages
Introduce mechanism to notify backend nodes of changes in relationship
between nodes. If a component is added or removed from an entity,
or if a node is added or removed from a property of another node, then
just rely on the node being marked as dirty when syncing takes place.
For nodes that do not support syncing, messages are delivered as before
but allocated on the stack rather than the heap.
Change-Id: I06affac77e42a9998d9c7f44e231c7724c52b320
Reviewed-by: Mike Krus <mike.krus@kdab.com>
Diffstat (limited to 'src/core/aspects/qabstractaspect.cpp')
-rw-r--r-- | src/core/aspects/qabstractaspect.cpp | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/core/aspects/qabstractaspect.cpp b/src/core/aspects/qabstractaspect.cpp index 866a0ce25..05afdd293 100644 --- a/src/core/aspects/qabstractaspect.cpp +++ b/src/core/aspects/qabstractaspect.cpp @@ -43,8 +43,13 @@ #include <QMetaObject> #include <QMetaProperty> +#include <Qt3DCore/qcomponent.h> #include <Qt3DCore/qentity.h> #include <Qt3DCore/qpropertyupdatedchange.h> +#include <Qt3DCore/qpropertyvalueaddedchange.h> +#include <Qt3DCore/qpropertyvalueremovedchange.h> +#include <Qt3DCore/qcomponentaddedchange.h> +#include <Qt3DCore/qcomponentremovedchange.h> #include <Qt3DCore/private/corelogging_p.h> #include <Qt3DCore/private/qaspectjobmanager_p.h> @@ -209,6 +214,12 @@ void QAbstractAspect::syncDirtyFrontEndNodes(const QVector<QNode *> &nodes) d->syncDirtyFrontEndNodes(nodes); } +void QAbstractAspect::syncDirtyFrontEndSubNodes(const QVector<NodeRelationshipChange> &nodes) +{ + Q_D(QAbstractAspect); + d->syncDirtyFrontEndSubNodes(nodes); +} + QAbstractAspectPrivate::BackendNodeMapperAndInfo QAbstractAspectPrivate::mapperForNode(const QMetaObject *metaObj) const { Q_ASSERT(metaObj); @@ -243,6 +254,103 @@ void QAbstractAspectPrivate::syncDirtyFrontEndNodes(const QVector<QNode *> &node } } +void QAbstractAspectPrivate::syncDirtyFrontEndSubNodes(const QVector<NodeRelationshipChange> &nodes) +{ + for (const auto &nodeChange: qAsConst(nodes)) { + auto getBackend = [this](QNode *node) -> std::tuple<QBackendNode *, bool> { + const QMetaObject *metaObj = QNodePrivate::get(node)->m_typeInfo; + const BackendNodeMapperAndInfo backendNodeMapperInfo = mapperForNode(metaObj); + const QBackendNodeMapperPtr backendNodeMapper = backendNodeMapperInfo.first; + + if (!backendNodeMapper) + return {}; + + QBackendNode *backend = backendNodeMapper->get(node->id()); + if (!backend) + return {}; + + const bool supportsSyncing = backendNodeMapperInfo.second & SupportsSyncing; + + return std::tuple<QBackendNode *, bool>(backend, supportsSyncing); + }; + + auto nodeInfo = getBackend(nodeChange.node); + if (!std::get<0>(nodeInfo)) + continue; + + auto subNodeInfo = getBackend(nodeChange.subNode); + if (!std::get<0>(subNodeInfo)) + continue; + + switch (nodeChange.change) { + case PropertyValueAdded: { + if (std::get<1>(nodeInfo)) + break; // do nothing as the node will be dirty anyway + + QPropertyValueAddedChange change(nodeChange.node->id()); + change.setPropertyName(nodeChange.property); + change.setAddedValue(QVariant::fromValue(nodeChange.subNode->id())); + QPropertyValueAddedChangePtr pChange(&change, [](QPropertyValueAddedChange *) { }); + std::get<0>(nodeInfo)->sceneChangeEvent(pChange); + } + break; + case PropertyValueRemoved: { + if (std::get<1>(nodeInfo)) + break; // do nothing as the node will be dirty anyway + + QPropertyValueRemovedChange change(nodeChange.node->id()); + change.setPropertyName(nodeChange.property); + change.setRemovedValue(QVariant::fromValue(nodeChange.subNode->id())); + QPropertyValueRemovedChangePtr pChange(&change, [](QPropertyValueRemovedChange *) { }); + std::get<0>(nodeInfo)->sceneChangeEvent(pChange); + } + break; + case ComponentAdded: { + // let the entity know it has a new component + if (std::get<1>(nodeInfo)) { + QBackendNodePrivate::get(std::get<0>(nodeInfo))->componentAdded(nodeChange.subNode); + } else { + QComponentAddedChange change(qobject_cast<Qt3DCore::QComponent *>(nodeChange.subNode), qobject_cast<Qt3DCore::QEntity *>(nodeChange.node)); + QComponentAddedChangePtr pChange(&change, [](QComponentAddedChange *) { }); + std::get<0>(nodeInfo)->sceneChangeEvent(pChange); + } + + // let the component know it was added to an entity + if (std::get<1>(subNodeInfo)) { + QBackendNodePrivate::get(std::get<0>(subNodeInfo))->addedToEntity(nodeChange.node); + } else { + QComponentAddedChange change(qobject_cast<Qt3DCore::QComponent *>(nodeChange.subNode), qobject_cast<Qt3DCore::QEntity *>(nodeChange.node)); + QComponentAddedChangePtr pChange(&change, [](QComponentAddedChange *) { }); + std::get<0>(subNodeInfo)->sceneChangeEvent(pChange); + } + } + break; + case ComponentRemoved: { + // let the entity know a component was removed + if (std::get<1>(nodeInfo)) { + QBackendNodePrivate::get(std::get<0>(nodeInfo))->componentRemoved(nodeChange.subNode); + } else { + QComponentRemovedChange change(qobject_cast<Qt3DCore::QComponent *>(nodeChange.subNode), qobject_cast<Qt3DCore::QEntity *>(nodeChange.node)); + QComponentRemovedChangePtr pChange(&change, [](QComponentRemovedChange *) { }); + std::get<0>(nodeInfo)->sceneChangeEvent(pChange); + } + + // let the component know it was removed from an entity + if (std::get<1>(subNodeInfo)) { + QBackendNodePrivate::get(std::get<0>(subNodeInfo))->removedFromEntity(nodeChange.node); + } else { + QComponentRemovedChange change(qobject_cast<Qt3DCore::QEntity *>(nodeChange.node), qobject_cast<Qt3DCore::QComponent *>(nodeChange.subNode)); + QComponentRemovedChangePtr pChange(&change, [](QComponentRemovedChange *) { }); + std::get<0>(nodeInfo)->sceneChangeEvent(pChange); + } + } + break; + default: + break; + } + } +} + void QAbstractAspectPrivate::syncDirtyFrontEndNode(QNode *node, QBackendNode *backend, bool firstTime) const { Q_ASSERT(false); // overload in derived class |