diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-10-19 03:04:13 +0200 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-10-19 03:04:13 +0200 |
commit | 896619133fc338052702ce6f97ba765725f05e43 (patch) | |
tree | 2b7bd04baf654ebbefabb4a86c1c6352dcc0c03e /src/core | |
parent | ecbf5e9a0f331314b554077f3903b621a74f590b (diff) | |
parent | 3c551b2e2f4f433894d5c70de6e260fddadbb12d (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Change-Id: I45be7ae8399e3b27d1ac55ccfed2fa42a872ac23
Diffstat (limited to 'src/core')
26 files changed, 256 insertions, 40 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 diff --git a/src/core/aspects/qabstractaspect.h b/src/core/aspects/qabstractaspect.h index a9f4f03fc..8c191c1d8 100644 --- a/src/core/aspects/qabstractaspect.h +++ b/src/core/aspects/qabstractaspect.h @@ -42,6 +42,7 @@ #include <Qt3DCore/qt3dcore_global.h> #include <Qt3DCore/qnodeid.h> +#include <Qt3DCore/qscenechange.h> #include <QtCore/QObject> #include <QtCore/QSharedPointer> @@ -86,6 +87,7 @@ protected: private: void syncDirtyFrontEndNodes(const QVector<QNode *> &nodes); + void syncDirtyFrontEndSubNodes(const QVector<NodeRelationshipChange> &nodes); void registerBackendType(const QMetaObject &obj, const QBackendNodeMapperPtr &functor, bool supportsSyncing); virtual QVariant executeCommand(const QStringList &args); diff --git a/src/core/aspects/qabstractaspect_p.h b/src/core/aspects/qabstractaspect_p.h index 8bd26cf00..670302cfa 100644 --- a/src/core/aspects/qabstractaspect_p.h +++ b/src/core/aspects/qabstractaspect_p.h @@ -130,6 +130,7 @@ public: QBackendNode *createBackendNode(const NodeTreeChange &change) const; void clearBackendNode(const NodeTreeChange &change) const; void syncDirtyFrontEndNodes(const QVector<QNode *> &nodes); + void syncDirtyFrontEndSubNodes(const QVector<NodeRelationshipChange> &nodes); virtual void syncDirtyFrontEndNode(QNode *node, QBackendNode *backend, bool firstTime) const; void sendPropertyMessages(QNode *node, QBackendNode *backend) const; diff --git a/src/core/aspects/qaspectmanager.cpp b/src/core/aspects/qaspectmanager.cpp index a33f771e9..71e05b34f 100644 --- a/src/core/aspects/qaspectmanager.cpp +++ b/src/core/aspects/qaspectmanager.cpp @@ -62,6 +62,7 @@ #include <Qt3DCore/private/qtickclockservice_p.h> #include <Qt3DCore/private/qnodevisitor_p.h> #include <Qt3DCore/private/qnode_p.h> +#include <Qt3DCore/private/qscene_p.h> #include <QtCore/QCoreApplication> @@ -379,6 +380,24 @@ void QAspectManager::setPostConstructorInit(NodePostConstructorInit *postConstru m_postConstructorInit = postConstructorInit; } +QNode *QAspectManager::lookupNode(QNodeId id) const +{ + if (!m_root) + return nullptr; + + QNodePrivate *d = QNodePrivate::get(m_root); + return d->m_scene ? d->m_scene->lookupNode(id) : nullptr; +} + +QVector<QNode *> QAspectManager::lookupNodes(const QVector<QNodeId> &ids) const +{ + if (!m_root) + return {}; + + QNodePrivate *d = QNodePrivate::get(m_root); + return d->m_scene ? d->m_scene->lookupNodes(ids) : QVector<QNode *>{}; +} + /*! \internal \brief Drives the Qt3D simulation loop in the main thread @@ -456,11 +475,18 @@ void QAspectManager::processFrame() } } + // Sync node / subnode relationship changes + const auto dirtySubNodes = m_changeArbiter->takeDirtyFrontEndSubNodes(); + if (dirtySubNodes.size()) + for (QAbstractAspect *aspect : qAsConst(m_aspects)) + aspect->syncDirtyFrontEndSubNodes(dirtySubNodes); + // Sync property updates const auto dirtyFrontEndNodes = m_changeArbiter->takeDirtyFrontEndNodes(); if (dirtyFrontEndNodes.size()) for (QAbstractAspect *aspect : qAsConst(m_aspects)) aspect->syncDirtyFrontEndNodes(dirtyFrontEndNodes); + // TO DO: Having this done in the main thread actually means aspects could just // as simply read info out of the Frontend classes without risk of introducing // races. This could therefore be removed for Qt 6. diff --git a/src/core/aspects/qaspectmanager_p.h b/src/core/aspects/qaspectmanager_p.h index 38ddbc55d..d9a6c41ec 100644 --- a/src/core/aspects/qaspectmanager_p.h +++ b/src/core/aspects/qaspectmanager_p.h @@ -108,6 +108,9 @@ public: QServiceLocator *serviceLocator() const; void setPostConstructorInit(NodePostConstructorInit *postConstructorInit); + QNode *lookupNode(QNodeId id) const; + QVector<QNode *> lookupNodes(const QVector<QNodeId> &ids) const; + private: bool event(QEvent *event) override; void requestNextFrame(); diff --git a/src/core/changes/qscenechange.h b/src/core/changes/qscenechange.h index 7d88d334f..e8c0ea748 100644 --- a/src/core/changes/qscenechange.h +++ b/src/core/changes/qscenechange.h @@ -63,6 +63,15 @@ enum ChangeFlag { Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag) Q_DECLARE_OPERATORS_FOR_FLAGS(ChangeFlags) +class QNode; +//! internal +struct NodeRelationshipChange { + QNode *node; + QNode *subNode; + ChangeFlag change; + const char *property; +}; + class QSceneChangePrivate; class Q_3DCORESHARED_EXPORT QSceneChange diff --git a/src/core/jobs/qaspectjob.cpp b/src/core/jobs/qaspectjob.cpp index ccb9c3a0e..00ad1ace8 100644 --- a/src/core/jobs/qaspectjob.cpp +++ b/src/core/jobs/qaspectjob.cpp @@ -59,11 +59,18 @@ QAspectJobPrivate::QAspectJobPrivate() { } +QAspectJobPrivate::~QAspectJobPrivate() = default; + QAspectJobPrivate *QAspectJobPrivate::get(QAspectJob *job) { return job->d_func(); } +void QAspectJobPrivate::postFrame(QAspectManager *aspectManager) +{ + Q_UNUSED(aspectManager) +} + QAspectJob::QAspectJob() : d_ptr(new QAspectJobPrivate) { @@ -133,6 +140,13 @@ QVector<QWeakPointer<QAspectJob> > QAspectJob::dependencies() const return d->m_dependencies; } +void QAspectJob::postFrame(QAspectManager *aspectManager) +{ + Q_D(QAspectJob); + if (aspectManager) + d->postFrame(aspectManager); +} + } // namespace Qt3DCore QT_END_NAMESPACE diff --git a/src/core/jobs/qaspectjob.h b/src/core/jobs/qaspectjob.h index 5c088fd1a..7cc784e0f 100644 --- a/src/core/jobs/qaspectjob.h +++ b/src/core/jobs/qaspectjob.h @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE namespace Qt3DCore { class QAspectJobPrivate; +class QAspectManager; class Q_3DCORESHARED_EXPORT QAspectJob { @@ -62,14 +63,15 @@ public: QVector<QWeakPointer<QAspectJob> > dependencies() const; virtual void run() = 0; + void postFrame(QAspectManager *aspectManager); protected: explicit QAspectJob(QAspectJobPrivate &dd); + QAspectJobPrivate *d_ptr; private: Q_DISABLE_COPY(QAspectJob) Q_DECLARE_PRIVATE(QAspectJob) - QAspectJobPrivate *d_ptr; }; typedef QSharedPointer<QAspectJob> QAspectJobPtr; diff --git a/src/core/jobs/qaspectjob_p.h b/src/core/jobs/qaspectjob_p.h index 7aa3151a0..b16c3cad2 100644 --- a/src/core/jobs/qaspectjob_p.h +++ b/src/core/jobs/qaspectjob_p.h @@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE namespace Qt3DCore { class QAspectJob; +class QAspectManager; #if QT_CONFIG(qt3d_profile_jobs) struct FrameHeader @@ -107,9 +108,12 @@ class Q_3DCORE_PRIVATE_EXPORT QAspectJobPrivate { public: QAspectJobPrivate(); + virtual ~QAspectJobPrivate(); static QAspectJobPrivate *get(QAspectJob *job); + virtual void postFrame(QAspectManager *aspectManager); + QVector<QWeakPointer<QAspectJob> > m_dependencies; #if QT_CONFIG(qt3d_profile_jobs) JobRunStats m_stats; diff --git a/src/core/nodes/qbackendnode.cpp b/src/core/nodes/qbackendnode.cpp index 3eb1cd9f7..e5f93e96f 100644 --- a/src/core/nodes/qbackendnode.cpp +++ b/src/core/nodes/qbackendnode.cpp @@ -95,6 +95,26 @@ QBackendNodePrivate *QBackendNodePrivate::get(QBackendNode *n) return n->d_func(); } +void QBackendNodePrivate::addedToEntity(QNode *frontend) +{ + Q_UNUSED(frontend) +} + +void QBackendNodePrivate::removedFromEntity(QNode *frontend) +{ + Q_UNUSED(frontend) +} + +void QBackendNodePrivate::componentAdded(QNode *frontend) +{ + Q_UNUSED(frontend) +} + +void QBackendNodePrivate::componentRemoved(QNode *frontend) +{ + Q_UNUSED(frontend) +} + /*! * \class Qt3DCore::QBackendNodeMapper * \inheaderfile Qt3DCore/QBackendNodeMapper diff --git a/src/core/nodes/qbackendnode_p.h b/src/core/nodes/qbackendnode_p.h index dde86fa48..260eef087 100644 --- a/src/core/nodes/qbackendnode_p.h +++ b/src/core/nodes/qbackendnode_p.h @@ -63,6 +63,8 @@ QT_BEGIN_NAMESPACE namespace Qt3DCore { +class QNode; + class Q_3DCORE_PRIVATE_EXPORT QBackendNodePrivate : public QObserverInterface , public QObservableInterface @@ -85,6 +87,11 @@ public: QNodeId m_peerId; bool m_enabled; + virtual void addedToEntity(QNode *frontend); + virtual void removedFromEntity(QNode *frontend); + virtual void componentAdded(QNode *frontend); + virtual void componentRemoved(QNode *frontend); + private: Q_DISABLE_COPY(QBackendNodePrivate) }; diff --git a/src/core/nodes/qcomponent.cpp b/src/core/nodes/qcomponent.cpp index 2fe3c8094..79bba229d 100644 --- a/src/core/nodes/qcomponent.cpp +++ b/src/core/nodes/qcomponent.cpp @@ -40,9 +40,6 @@ #include "qcomponent.h" #include "qcomponent_p.h" -#include <Qt3DCore/qpropertyupdatedchange.h> -#include <Qt3DCore/qcomponentaddedchange.h> -#include <Qt3DCore/qcomponentremovedchange.h> #include <Qt3DCore/qentity.h> #include <Qt3DCore/private/qentity_p.h> @@ -73,8 +70,6 @@ void QComponentPrivate::addEntity(QEntity *entity) m_scene->addEntityForComponent(m_id, entity->id()); } - const auto componentAddedChange = QComponentAddedChangePtr::create(q, entity); // TODOSYNC notify backend directly - notifyObservers(componentAddedChange); Q_EMIT q->addedToEntity(entity); } @@ -86,8 +81,6 @@ void QComponentPrivate::removeEntity(QEntity *entity) m_entities.removeAll(entity); - const auto componentRemovedChange = QComponentRemovedChangePtr::create(q, entity); // TODOSYNC notify backend directly - notifyObservers(componentRemovedChange); Q_EMIT q->removedFromEntity(entity); } diff --git a/src/core/nodes/qentity.cpp b/src/core/nodes/qentity.cpp index 0ff8c4646..024991387 100644 --- a/src/core/nodes/qentity.cpp +++ b/src/core/nodes/qentity.cpp @@ -41,10 +41,7 @@ #include "qentity_p.h" #include <Qt3DCore/qcomponent.h> -#include <Qt3DCore/qcomponentaddedchange.h> -#include <Qt3DCore/qcomponentremovedchange.h> #include <Qt3DCore/qnodecreatedchange.h> -#include <Qt3DCore/qpropertyupdatedchange.h> #include <QtCore/QMetaObject> #include <QtCore/QMetaProperty> @@ -102,13 +99,8 @@ void QEntityPrivate::removeDestroyedComponent(QComponent *comp) Q_CHECK_PTR(comp); qCDebug(Nodes) << Q_FUNC_INFO << comp; - Q_Q(QEntity); - - if (m_changeArbiter) { - const auto componentRemovedChange = QComponentRemovedChangePtr::create(q, comp); // TODOSYNC notify backend directly - notifyObservers(componentRemovedChange); - } + updateNode(comp, nullptr, ComponentRemoved); m_components.removeOne(comp); // Remove bookkeeping connection @@ -187,10 +179,7 @@ void QEntity::addComponent(QComponent *comp) // Ensures proper bookkeeping d->registerPrivateDestructionHelper(comp, &QEntityPrivate::removeDestroyedComponent); - if (d->m_changeArbiter) { - const auto componentAddedChange = QComponentAddedChangePtr::create(this, comp); // TODOSYNC notify backend directly - d->notifyObservers(componentAddedChange); - } + d->updateNode(comp, nullptr, ComponentAdded); static_cast<QComponentPrivate *>(QComponentPrivate::get(comp))->addEntity(this); } @@ -205,10 +194,7 @@ void QEntity::removeComponent(QComponent *comp) static_cast<QComponentPrivate *>(QComponentPrivate::get(comp))->removeEntity(this); - if (d->m_changeArbiter) { - const auto componentRemovedChange = QComponentRemovedChangePtr::create(this, comp); - d->notifyObservers(componentRemovedChange); - } + d->updateNode(comp, nullptr, ComponentRemoved); d->m_components.removeOne(comp); diff --git a/src/core/nodes/qnode.cpp b/src/core/nodes/qnode.cpp index 2cea47372..cfe83f4db 100644 --- a/src/core/nodes/qnode.cpp +++ b/src/core/nodes/qnode.cpp @@ -526,10 +526,11 @@ void QNodePrivate::_q_ensureBackendNodeCreated() * Sends the \a change QSceneChangePtr to any QBackendNodes in the registered * aspects that correspond to this QNode. * - * For the common case of a QObject property change, QNode handles this for you - * automatically by sending a QPropertyUpdatedChange event to the backend nodes. * You only need to call this function if you wish to send a specific type of * change in place of the automatic handling. + * + * Note: as of Qt 5.14, change messages are deprecated and should not be used, + * in particular for properties. */ void QNode::notifyObservers(const QSceneChangePtr &change) { @@ -679,6 +680,14 @@ void QNodePrivate::update() } } +void QNodePrivate::updateNode(QNode *node, const char *property, ChangeFlag change) +{ + if (m_changeArbiter) { + Q_Q(QNode); + m_changeArbiter->addDirtyFrontEndNode(q, node, property, change); + } +} + /*! \internal */ diff --git a/src/core/nodes/qnode_p.h b/src/core/nodes/qnode_p.h index 839751a5e..a7a300a5e 100644 --- a/src/core/nodes/qnode_p.h +++ b/src/core/nodes/qnode_p.h @@ -90,6 +90,7 @@ public: void updatePropertyTrackMode(); void update(); + void updateNode(QNode *node, const char* property, ChangeFlag change); Q_DECLARE_PUBLIC(QNode) diff --git a/src/core/qchangearbiter.cpp b/src/core/qchangearbiter.cpp index 60cdc3bd2..e5745b017 100644 --- a/src/core/qchangearbiter.cpp +++ b/src/core/qchangearbiter.cpp @@ -249,13 +249,24 @@ void QChangeArbiter::sceneChangeEventWithLock(const QSceneChangeList &e) void QChangeArbiter::addDirtyFrontEndNode(QNode *node) { - if (!m_dirtyFrontEndNodes.contains(node)) + if (!m_dirtyFrontEndNodes.contains(node)) { m_dirtyFrontEndNodes += node; + emit receivedChange(); + } +} + +void QChangeArbiter::addDirtyFrontEndNode(QNode *node, QNode *subNode, const char *property, ChangeFlag change) +{ + addDirtyFrontEndNode(node); + m_dirtySubNodeChanges.push_back({node, subNode, change, property}); } void QChangeArbiter::removeDirtyFrontEndNode(QNode *node) { m_dirtyFrontEndNodes.removeOne(node); + m_dirtySubNodeChanges.erase(std::remove_if(m_dirtySubNodeChanges.begin(), m_dirtySubNodeChanges.end(), [node](const NodeRelationshipChange &elt) { + return elt.node == node || elt.subNode == node; + }), m_dirtySubNodeChanges.end()); } QVector<QNode *> QChangeArbiter::takeDirtyFrontEndNodes() @@ -263,6 +274,11 @@ QVector<QNode *> QChangeArbiter::takeDirtyFrontEndNodes() return std::move(m_dirtyFrontEndNodes); } +QVector<NodeRelationshipChange> QChangeArbiter::takeDirtyFrontEndSubNodes() +{ + return std::move(m_dirtySubNodeChanges); +} + // Either we have the postman or we could make the QChangeArbiter agnostic to the postman // but that would require adding it to every QObserverList in m_aspectObservations. void QChangeArbiter::setPostman(QAbstractPostman *postman) diff --git a/src/core/qchangearbiter_p.h b/src/core/qchangearbiter_p.h index 0a6196756..f31480685 100644 --- a/src/core/qchangearbiter_p.h +++ b/src/core/qchangearbiter_p.h @@ -83,6 +83,7 @@ public: virtual QAbstractPostman *postman() const = 0; virtual void addDirtyFrontEndNode(QNode *node) = 0; virtual void removeDirtyFrontEndNode(QNode *node) = 0; + virtual void addDirtyFrontEndNode(QNode *node, QNode *subNode, const char *property, ChangeFlag change) = 0; }; class Q_3DCORE_PRIVATE_EXPORT QChangeArbiter final @@ -109,8 +110,10 @@ public: void sceneChangeEventWithLock(const QSceneChangeList &e) override; // QLockableObserverInterface impl void addDirtyFrontEndNode(QNode *node) override; + void addDirtyFrontEndNode(QNode *node, QNode *subNode, const char *property, ChangeFlag change) override; void removeDirtyFrontEndNode(QNode *node) override; QVector<QNode *> takeDirtyFrontEndNodes(); + QVector<NodeRelationshipChange> takeDirtyFrontEndSubNodes(); void setPostman(Qt3DCore::QAbstractPostman *postman); void setScene(Qt3DCore::QScene *scene); @@ -159,6 +162,7 @@ private: QScene *m_scene; QVector<QNode *> m_dirtyFrontEndNodes; + QVector<NodeRelationshipChange> m_dirtySubNodeChanges; }; } // namespace Qt3DCore diff --git a/src/core/qscheduler.cpp b/src/core/qscheduler.cpp index cc2f9081e..edfbb391c 100644 --- a/src/core/qscheduler.cpp +++ b/src/core/qscheduler.cpp @@ -91,6 +91,9 @@ void QScheduler::scheduleAndWaitForFrameAspectJobs(qint64 time) // whilst the threadpool works its way through the jobs m_aspectManager->jobManager()->waitForAllJobs(); + + for (auto &job : qAsConst(jobQueue)) + job->postFrame(m_aspectManager); } } // namespace Qt3DCore diff --git a/src/core/transforms/qabstractskeleton.cpp b/src/core/transforms/qabstractskeleton.cpp index 1bc7247a7..5f3b05eb8 100644 --- a/src/core/transforms/qabstractskeleton.cpp +++ b/src/core/transforms/qabstractskeleton.cpp @@ -60,6 +60,14 @@ const QAbstractSkeletonPrivate *QAbstractSkeletonPrivate::get(const QAbstractSke } /*! + \internal + */ +QAbstractSkeletonPrivate *QAbstractSkeletonPrivate::get(QAbstractSkeleton *q) +{ + return q->d_func(); +} + +/*! \qmltype AbstractSkeleton \inqmlmodule Qt3D.Core \inherits Node diff --git a/src/core/transforms/qabstractskeleton_p.h b/src/core/transforms/qabstractskeleton_p.h index 51d57f8c4..35d0df755 100644 --- a/src/core/transforms/qabstractskeleton_p.h +++ b/src/core/transforms/qabstractskeleton_p.h @@ -53,12 +53,13 @@ #include <Qt3DCore/private/qnode_p.h> #include <Qt3DCore/private/qskeletoncreatedchange_p.h> +#include <Qt3DCore/private/sqt_p.h> QT_BEGIN_NAMESPACE namespace Qt3DCore { -class QAbstractSkeletonPrivate : public Qt3DCore::QNodePrivate +class Q_3DCORE_PRIVATE_EXPORT QAbstractSkeletonPrivate : public Qt3DCore::QNodePrivate { public: QAbstractSkeletonPrivate(); @@ -67,10 +68,13 @@ public: Q_DECLARE_PUBLIC(QAbstractSkeleton) static const QAbstractSkeletonPrivate *get(const QAbstractSkeleton *q); + static QAbstractSkeletonPrivate *get(QAbstractSkeleton *q); QSkeletonCreatedChangeBase::SkeletonType m_type; int m_jointCount; + QVector<Sqt> m_localPoses; + QVector<QString> m_jointNames; }; } // namespace Qt3DCore diff --git a/src/core/transforms/qarmature_p.h b/src/core/transforms/qarmature_p.h index 1fc241dc2..3474349a6 100644 --- a/src/core/transforms/qarmature_p.h +++ b/src/core/transforms/qarmature_p.h @@ -60,7 +60,7 @@ namespace Qt3DCore { class QAbstractSkeleton; -class QArmaturePrivate : public Qt3DCore::QComponentPrivate +class Q_3DCORE_PRIVATE_EXPORT QArmaturePrivate : public Qt3DCore::QComponentPrivate { public: QArmaturePrivate(); diff --git a/src/core/transforms/qjoint.cpp b/src/core/transforms/qjoint.cpp index 553fbd654..408d42f6d 100644 --- a/src/core/transforms/qjoint.cpp +++ b/src/core/transforms/qjoint.cpp @@ -41,9 +41,6 @@ #include "qjoint_p.h" #include <Qt3DCore/qnodecreatedchange.h> -#include <Qt3DCore/qpropertynodeaddedchange.h> -#include <Qt3DCore/qpropertynoderemovedchange.h> -#include <Qt3DCore/qpropertyupdatedchange.h> QT_BEGIN_NAMESPACE @@ -353,7 +350,7 @@ void QJoint::addChildJoint(QJoint *joint) d->registerDestructionHelper(joint, &QJoint::removeChildJoint, d->m_childJoints); if (d->m_changeArbiter != nullptr) - d->update(); + d->updateNode(joint, "childJoint", PropertyValueAdded); } } @@ -365,9 +362,8 @@ void QJoint::removeChildJoint(QJoint *joint) { Q_D(QJoint); if (d->m_childJoints.contains(joint)) { - if (d->m_changeArbiter != nullptr) - d->update(); + d->updateNode(joint, "childJoint", PropertyValueRemoved); d->m_childJoints.removeOne(joint); diff --git a/src/core/transforms/qjoint_p.h b/src/core/transforms/qjoint_p.h index 82439d55a..cb0bfe847 100644 --- a/src/core/transforms/qjoint_p.h +++ b/src/core/transforms/qjoint_p.h @@ -60,7 +60,7 @@ namespace Qt3DCore { class QJoint; -class QJointPrivate : public QNodePrivate +class Q_3DCORE_PRIVATE_EXPORT QJointPrivate : public QNodePrivate { public: QJointPrivate(); diff --git a/src/core/transforms/qskeleton_p.h b/src/core/transforms/qskeleton_p.h index c8b6554f9..2ce5fce07 100644 --- a/src/core/transforms/qskeleton_p.h +++ b/src/core/transforms/qskeleton_p.h @@ -60,7 +60,7 @@ namespace Qt3DCore { class QJoint; -class QSkeletonPrivate : public QAbstractSkeletonPrivate +class Q_3DCORE_PRIVATE_EXPORT QSkeletonPrivate : public QAbstractSkeletonPrivate { public: QSkeletonPrivate(); diff --git a/src/core/transforms/qskeletonloader_p.h b/src/core/transforms/qskeletonloader_p.h index ab0babe00..5c415745b 100644 --- a/src/core/transforms/qskeletonloader_p.h +++ b/src/core/transforms/qskeletonloader_p.h @@ -64,7 +64,7 @@ namespace Qt3DCore { class QJoint; -class QSkeletonLoaderPrivate : public QAbstractSkeletonPrivate +class Q_3DCORE_PRIVATE_EXPORT QSkeletonLoaderPrivate : public QAbstractSkeletonPrivate { public: QSkeletonLoaderPrivate(); diff --git a/src/core/transforms/qtransform_p.h b/src/core/transforms/qtransform_p.h index 028a9aba7..56053309e 100644 --- a/src/core/transforms/qtransform_p.h +++ b/src/core/transforms/qtransform_p.h @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE namespace Qt3DCore { -class QTransformPrivate : public QComponentPrivate +class Q_3DCORE_PRIVATE_EXPORT QTransformPrivate : public QComponentPrivate { Q_DECLARE_PUBLIC(QTransform) |