summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-10-19 03:04:13 +0200
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-10-19 03:04:13 +0200
commit896619133fc338052702ce6f97ba765725f05e43 (patch)
tree2b7bd04baf654ebbefabb4a86c1c6352dcc0c03e /src/core
parentecbf5e9a0f331314b554077f3903b621a74f590b (diff)
parent3c551b2e2f4f433894d5c70de6e260fddadbb12d (diff)
Merge remote-tracking branch 'origin/5.15' into dev
Diffstat (limited to 'src/core')
-rw-r--r--src/core/aspects/qabstractaspect.cpp108
-rw-r--r--src/core/aspects/qabstractaspect.h2
-rw-r--r--src/core/aspects/qabstractaspect_p.h1
-rw-r--r--src/core/aspects/qaspectmanager.cpp26
-rw-r--r--src/core/aspects/qaspectmanager_p.h3
-rw-r--r--src/core/changes/qscenechange.h9
-rw-r--r--src/core/jobs/qaspectjob.cpp14
-rw-r--r--src/core/jobs/qaspectjob.h4
-rw-r--r--src/core/jobs/qaspectjob_p.h4
-rw-r--r--src/core/nodes/qbackendnode.cpp20
-rw-r--r--src/core/nodes/qbackendnode_p.h7
-rw-r--r--src/core/nodes/qcomponent.cpp7
-rw-r--r--src/core/nodes/qentity.cpp20
-rw-r--r--src/core/nodes/qnode.cpp13
-rw-r--r--src/core/nodes/qnode_p.h1
-rw-r--r--src/core/qchangearbiter.cpp18
-rw-r--r--src/core/qchangearbiter_p.h4
-rw-r--r--src/core/qscheduler.cpp3
-rw-r--r--src/core/transforms/qabstractskeleton.cpp8
-rw-r--r--src/core/transforms/qabstractskeleton_p.h6
-rw-r--r--src/core/transforms/qarmature_p.h2
-rw-r--r--src/core/transforms/qjoint.cpp8
-rw-r--r--src/core/transforms/qjoint_p.h2
-rw-r--r--src/core/transforms/qskeleton_p.h2
-rw-r--r--src/core/transforms/qskeletonloader_p.h2
-rw-r--r--src/core/transforms/qtransform_p.h2
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)