summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/aspects/qabstractaspect.cpp102
-rw-r--r--src/core/aspects/qabstractaspect.h13
-rw-r--r--src/core/aspects/qabstractaspect_p.h10
-rw-r--r--src/core/aspects/qaspectengine.cpp11
-rw-r--r--src/core/aspects/qaspectengine_p.h3
-rw-r--r--src/core/aspects/qaspectmanager.cpp6
-rw-r--r--src/core/nodes/qbackendnode.cpp16
-rw-r--r--src/core/nodes/qcomponent.cpp4
-rw-r--r--src/core/nodes/qentity.cpp4
-rw-r--r--src/core/nodes/qnode.cpp72
-rw-r--r--src/core/nodes/qnode_p.h2
-rw-r--r--src/core/qchangearbiter.cpp16
-rw-r--r--src/core/qchangearbiter_p.h10
-rw-r--r--src/core/qscene.cpp6
-rw-r--r--src/core/qscene_p.h5
15 files changed, 199 insertions, 81 deletions
diff --git a/src/core/aspects/qabstractaspect.cpp b/src/core/aspects/qabstractaspect.cpp
index 7b08dec81..7636fd666 100644
--- a/src/core/aspects/qabstractaspect.cpp
+++ b/src/core/aspects/qabstractaspect.cpp
@@ -40,6 +40,9 @@
#include "qabstractaspect.h"
#include "qabstractaspect_p.h"
+#include <QMetaObject>
+#include <QMetaProperty>
+
#include <Qt3DCore/qentity.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
@@ -48,6 +51,7 @@
#include <Qt3DCore/private/qaspectmanager_p.h>
#include <Qt3DCore/private/qchangearbiter_p.h>
#include <Qt3DCore/private/qnodevisitor_p.h>
+#include <Qt3DCore/private/qnode_p.h>
#include <Qt3DCore/private/qscene_p.h>
QT_BEGIN_NAMESPACE
@@ -170,7 +174,14 @@ QNodeId QAbstractAspect::rootEntityId() const Q_DECL_NOEXCEPT
void QAbstractAspect::registerBackendType(const QMetaObject &obj, const QBackendNodeMapperPtr &functor)
{
Q_D(QAbstractAspect);
- d->m_backendCreatorFunctors.insert(&obj, functor);
+ d->m_backendCreatorFunctors.insert(&obj, {functor, QAbstractAspectPrivate::DefaultMapper});
+}
+
+void QAbstractAspect::registerBackendType(const QMetaObject &obj, const QBackendNodeMapperPtr &functor, bool supportsSyncing)
+{
+ Q_D(QAbstractAspect);
+ const auto f = supportsSyncing ? QAbstractAspectPrivate::SupportsSyncing : QAbstractAspectPrivate::DefaultMapper;
+ d->m_backendCreatorFunctors.insert(&obj, {functor, f});
}
void QAbstractAspect::unregisterBackendType(const QMetaObject &obj)
@@ -203,12 +214,96 @@ QVector<QAspectJobPtr> QAbstractAspect::jobsToExecute(qint64 time)
return QVector<QAspectJobPtr>();
}
+void QAbstractAspect::syncDirtyFrontEndNodes(const QVector<QNode *> &nodes)
+{
+ Q_D(QAbstractAspect);
+ d->syncDirtyFrontEndNodes(nodes);
+}
+
+void QAbstractAspectPrivate::syncDirtyFrontEndNodes(const QVector<QNode *> &nodes)
+{
+ for (auto node: qAsConst(nodes)) {
+ const QMetaObject *metaObj = node->metaObject();
+ QBackendNodeMapperPtr backendNodeMapper;
+ bool supportsSyncing = false;
+ while (metaObj != nullptr && backendNodeMapper.isNull()) {
+ auto v = m_backendCreatorFunctors.value(metaObj);
+ backendNodeMapper = v.first;
+ supportsSyncing = v.second & SupportsSyncing;
+ metaObj = metaObj->superClass();
+ }
+
+ if (!backendNodeMapper)
+ continue;
+
+ QBackendNode *backend = backendNodeMapper->get(node->id());
+ if (!backend)
+ continue;
+ if (supportsSyncing)
+ syncDirtyFrontEndNode(node, backend, false);
+ else
+ sendPropertyMessages(node, backend);
+ }
+}
+
+void QAbstractAspectPrivate::syncDirtyFrontEndNode(QNode *node, QBackendNode *backend, bool firstTime) const
+{
+ Q_UNUSED(firstTime);
+ Q_ASSERT(false); // overload in derived class
+ sendPropertyMessages(node, backend);
+}
+
+void QAbstractAspectPrivate::sendPropertyMessages(QNode *node, QBackendNode *backend) const
+{
+ const int offset = QNode::staticMetaObject.propertyOffset();
+ const auto metaObj = node->metaObject();
+ const int count = metaObj->propertyCount();
+
+ const auto toBackendValue = [](const QVariant &data) -> QVariant
+ {
+ if (data.canConvert<QNode*>()) {
+ QNode *node = data.value<QNode*>();
+
+ // Ensure the node and all ancestors have issued their node creation changes.
+ // 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. We need to do this for all ancestors,
+ // since the subtree of this node otherwise can end up on the backend
+ // with a reference to a non-existent parent.
+ if (node)
+ QNodePrivate::get(node)->_q_ensureBackendNodeCreated();
+
+ const QNodeId id = node ? node->id() : QNodeId();
+ return QVariant::fromValue(id);
+ }
+
+ return data;
+ };
+
+ QPropertyUpdatedChange change(node->id());
+ QPropertyUpdatedChangePtr pchange(&change, [](QPropertyUpdatedChange *) { });
+ for (int index = offset; index < count; index++) {
+ const QMetaProperty pro = metaObj->property(index);
+ change.setPropertyName(pro.name());
+ change.setValue(toBackendValue(pro.read(node)));
+ backend->sceneChangeEvent(pchange);
+ }
+
+ auto const dynamicProperties = node->dynamicPropertyNames();
+ for (const QByteArray &name: dynamicProperties) {
+ change.setPropertyName(name.data());
+ change.setValue(toBackendValue(node->property(name.data())));
+ backend->sceneChangeEvent(pchange);
+ }
+}
+
QBackendNode *QAbstractAspectPrivate::createBackendNode(const QNodeCreatedChangeBasePtr &change) const
{
const QMetaObject *metaObj = change->metaObject();
QBackendNodeMapperPtr backendNodeMapper;
while (metaObj != nullptr && backendNodeMapper.isNull()) {
- backendNodeMapper = m_backendCreatorFunctors.value(metaObj);
+ backendNodeMapper = m_backendCreatorFunctors.value(metaObj).first;
metaObj = metaObj->superClass();
}
@@ -248,6 +343,7 @@ QBackendNode *QAbstractAspectPrivate::createBackendNode(const QNodeCreatedChange
return backend;
}
+
void QAbstractAspectPrivate::clearBackendNode(const QNodeDestroyedChangePtr &change) const
{
// Each QNodeDestroyedChange may contain info about a whole sub-tree of nodes that
@@ -259,7 +355,7 @@ void QAbstractAspectPrivate::clearBackendNode(const QNodeDestroyedChangePtr &cha
// Find backend node mapper for this type
while (metaObj != nullptr && backendNodeMapper.isNull()) {
- backendNodeMapper = m_backendCreatorFunctors.value(metaObj);
+ backendNodeMapper = m_backendCreatorFunctors.value(metaObj).first;
metaObj = metaObj->superClass();
}
diff --git a/src/core/aspects/qabstractaspect.h b/src/core/aspects/qabstractaspect.h
index 1ae85e4e6..a9f4f03fc 100644
--- a/src/core/aspects/qabstractaspect.h
+++ b/src/core/aspects/qabstractaspect.h
@@ -77,12 +77,17 @@ protected:
template<class Frontend>
void registerBackendType(const QBackendNodeMapperPtr &functor);
- void registerBackendType(const QMetaObject &, const QBackendNodeMapperPtr &functor);
+ template<class Frontend, bool supportsSyncing>
+ void registerBackendType(const QBackendNodeMapperPtr &functor);
+ void registerBackendType(const QMetaObject &obj, const QBackendNodeMapperPtr &functor);
template<class Frontend>
void unregisterBackendType();
void unregisterBackendType(const QMetaObject &);
private:
+ void syncDirtyFrontEndNodes(const QVector<QNode *> &nodes);
+ void registerBackendType(const QMetaObject &obj, const QBackendNodeMapperPtr &functor, bool supportsSyncing);
+
virtual QVariant executeCommand(const QStringList &args);
virtual QVector<QAspectJobPtr> jobsToExecute(qint64 time);
@@ -104,6 +109,12 @@ void QAbstractAspect::registerBackendType(const QBackendNodeMapperPtr &functor)
registerBackendType(Frontend::staticMetaObject, functor);
}
+template<class Frontend, bool supportsSyncing>
+void QAbstractAspect::registerBackendType(const QBackendNodeMapperPtr &functor)
+{
+ registerBackendType(Frontend::staticMetaObject, functor, supportsSyncing);
+}
+
template<class Frontend>
void QAbstractAspect::unregisterBackendType()
{
diff --git a/src/core/aspects/qabstractaspect_p.h b/src/core/aspects/qabstractaspect_p.h
index e743dc63a..668b9670c 100644
--- a/src/core/aspects/qabstractaspect_p.h
+++ b/src/core/aspects/qabstractaspect_p.h
@@ -121,6 +121,9 @@ public:
QBackendNode *createBackendNode(const QNodeCreatedChangeBasePtr &change) const override;
void clearBackendNode(const QNodeDestroyedChangePtr &change) const;
+ void syncDirtyFrontEndNodes(const QVector<QNode *> &nodes);
+ virtual void syncDirtyFrontEndNode(QNode *node, QBackendNode *backend, bool firstTime) const;
+ void sendPropertyMessages(QNode *node, QBackendNode *backend) const;
void sceneNodeAdded(Qt3DCore::QSceneChangePtr &e) override;
void sceneNodeRemoved(Qt3DCore::QSceneChangePtr &e) override;
@@ -134,12 +137,17 @@ public:
Q_DECLARE_PUBLIC(QAbstractAspect)
+ enum NodeMapperInfo {
+ DefaultMapper = 0,
+ SupportsSyncing = 1 << 0
+ };
+
QEntity *m_root;
QNodeId m_rootId;
QAspectManager *m_aspectManager;
QAbstractAspectJobManager *m_jobManager;
QChangeArbiter *m_arbiter;
- QHash<const QMetaObject*, QBackendNodeMapperPtr> m_backendCreatorFunctors;
+ QHash<const QMetaObject*, QPair<QBackendNodeMapperPtr, NodeMapperInfo>> m_backendCreatorFunctors;
QMutex m_singleShotMutex;
QVector<QAspectJobPtr> m_singleShotJobs;
diff --git a/src/core/aspects/qaspectengine.cpp b/src/core/aspects/qaspectengine.cpp
index 9c98e9613..c5e4b2b26 100644
--- a/src/core/aspects/qaspectengine.cpp
+++ b/src/core/aspects/qaspectengine.cpp
@@ -120,12 +120,6 @@ void QAspectEnginePrivate::initEntity(QEntity *entity)
}
}
-void QAspectEnginePrivate::generateCreationChanges(QNode *root)
-{
- const QNodeCreatedChangeGenerator generator(root);
- m_creationChanges = generator.creationChanges();
-}
-
/*!
* \class Qt3DCore::QAspectEngine
* \inheaderfile Qt3DCore/QAspectEngine
@@ -444,7 +438,8 @@ void QAspectEngine::setRootEntity(QEntityPtr root)
d->initNodeTree(root.data());
// Traverse tree to generate a vector of creation changes
- d->generateCreationChanges(root.data());
+ const QNodeCreatedChangeGenerator generator(root.data());
+ auto creationChanges = generator.creationChanges();
// Specify if the AspectManager should be driving the simulation loop or not
d->m_aspectManager->setRunMode(d->m_runMode);
@@ -456,7 +451,7 @@ void QAspectEngine::setRootEntity(QEntityPtr root)
// TODO: Pass the creation changes via the arbiter rather than relying upon
// an invokeMethod call.
qCDebug(Aspects) << "Begin setting scene root on aspect manager";
- d->m_aspectManager->setRootEntity(root.data(), d->m_creationChanges);
+ d->m_aspectManager->setRootEntity(root.data(), creationChanges);
qCDebug(Aspects) << "Done setting scene root on aspect manager";
d->m_aspectManager->enterSimulationLoop();
}
diff --git a/src/core/aspects/qaspectengine_p.h b/src/core/aspects/qaspectengine_p.h
index e1aaa9de9..7dad2a352 100644
--- a/src/core/aspects/qaspectengine_p.h
+++ b/src/core/aspects/qaspectengine_p.h
@@ -106,9 +106,6 @@ public:
void initNode(QNode *node);
void initEntity(QEntity *entity);
- void generateCreationChanges(QNode *rootNode);
- QVector<QNodeCreatedChangeBasePtr> m_creationChanges;
-
static QAspectEnginePrivate *get(QAspectEngine *engine);
};
diff --git a/src/core/aspects/qaspectmanager.cpp b/src/core/aspects/qaspectmanager.cpp
index 6502590d8..0c16de882 100644
--- a/src/core/aspects/qaspectmanager.cpp
+++ b/src/core/aspects/qaspectmanager.cpp
@@ -370,6 +370,10 @@ void QAspectManager::processFrame()
changeArbiterStats.threadId = reinterpret_cast<quint64>(QThread::currentThreadId());
changeArbiterStats.startTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed();
#endif
+ 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.
@@ -390,6 +394,8 @@ void QAspectManager::processFrame()
#if defined(QT3D_CORE_JOB_TIMING)
qDebug() << "Jobs took" << timer.nsecsElapsed() / 1.0e6;
#endif
+
+ // TODO sync backend changes to frontend
}
} // namespace Qt3DCore
diff --git a/src/core/nodes/qbackendnode.cpp b/src/core/nodes/qbackendnode.cpp
index f10bf5769..3eb1cd9f7 100644
--- a/src/core/nodes/qbackendnode.cpp
+++ b/src/core/nodes/qbackendnode.cpp
@@ -256,16 +256,16 @@ void QBackendNode::setEnabled(bool enabled) Q_DECL_NOTHROW
void QBackendNode::sceneChangeEvent(const QSceneChangePtr &e)
{
Q_D(QBackendNode);
- auto propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
switch (e->type()) {
- case PropertyUpdated: {
- if (propertyChange->propertyName() == QByteArrayLiteral("enabled"))
- d->m_enabled = propertyChange->value().toBool();
- break;
- }
- default:
- break;
+ case PropertyUpdated: {
+ auto propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
+ if (propertyChange->propertyName() == QByteArrayLiteral("enabled"))
+ d->m_enabled = propertyChange->value().toBool();
+ break;
+ }
+ default:
+ break;
}
}
diff --git a/src/core/nodes/qcomponent.cpp b/src/core/nodes/qcomponent.cpp
index f67989b1e..2fe3c8094 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(q, entity);
+ const auto componentAddedChange = QComponentAddedChangePtr::create(q, entity); // TODOSYNC notify backend directly
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(q, 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 1d16e828e..a1f7d2859 100644
--- a/src/core/nodes/qentity.cpp
+++ b/src/core/nodes/qentity.cpp
@@ -105,7 +105,7 @@ void QEntityPrivate::removeDestroyedComponent(QComponent *comp)
Q_Q(QEntity);
if (m_changeArbiter) {
- const auto componentRemovedChange = QComponentRemovedChangePtr::create(q, comp);
+ const auto componentRemovedChange = QComponentRemovedChangePtr::create(q, comp); // TODOSYNC notify backend directly
notifyObservers(componentRemovedChange);
}
@@ -187,7 +187,7 @@ void QEntity::addComponent(QComponent *comp)
d->registerPrivateDestructionHelper(comp, &QEntityPrivate::removeDestroyedComponent);
if (d->m_changeArbiter) {
- const auto componentAddedChange = QComponentAddedChangePtr::create(this, comp);
+ const auto componentAddedChange = QComponentAddedChangePtr::create(this, comp); // TODOSYNC notify backend directly
d->notifyObservers(componentAddedChange);
}
static_cast<QComponentPrivate *>(QComponentPrivate::get(comp))->addEntity(this);
diff --git a/src/core/nodes/qnode.cpp b/src/core/nodes/qnode.cpp
index 900c3f8ce..45d58bd8c 100644
--- a/src/core/nodes/qnode.cpp
+++ b/src/core/nodes/qnode.cpp
@@ -385,48 +385,13 @@ void QNodePrivate::unregisterNotifiedProperties()
void QNodePrivate::propertyChanged(int propertyIndex)
{
+ Q_UNUSED(propertyIndex);
+
// Bail out early if we can to avoid the cost below
if (m_blockNotifications)
return;
- const auto toBackendValue = [](const QVariant &data) -> QVariant
- {
- if (data.canConvert<QNode*>()) {
- QNode *node = data.value<QNode*>();
-
- // Ensure the node and all ancestors have issued their node creation changes.
- // 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. We need to do this for all ancestors,
- // since the subtree of this node otherwise can end up on the backend
- // with a reference to a non-existent parent.
- if (node)
- QNodePrivate::get(node)->_q_ensureBackendNodeCreated();
-
- 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.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(), toBackendValue(data));
- }
+ update();
}
/*!
@@ -498,8 +463,13 @@ void QNodePrivate::addEntityComponentToScene(QNode *root)
// Called in the main thread by QScene -> following QEvent::childAdded / addChild
void QNodePrivate::setArbiter(QLockableObserverInterface *arbiter)
{
- if (m_changeArbiter && m_changeArbiter != arbiter)
+ if (m_changeArbiter && m_changeArbiter != arbiter) {
unregisterNotifiedProperties();
+
+ // Remove node from dirtyFrontendNodeList on old arbiter
+ Q_Q(QNode);
+ m_changeArbiter->removeDirtyFrontEndNode(q);
+ }
m_changeArbiter = static_cast<QAbstractArbiter *>(arbiter);
if (m_changeArbiter)
registerNotifiedProperties();
@@ -626,26 +596,26 @@ QScene *QNodePrivate::scene() const
*/
void QNodePrivate::notifyPropertyChange(const char *name, const QVariant &value)
{
+ Q_UNUSED(name);
+ Q_UNUSED(value);
+
// Bail out early if we can to avoid operator new
if (m_blockNotifications)
return;
- auto e = QPropertyUpdatedChangePtr::create(m_id);
- e->setPropertyName(name);
- e->setValue(value);
- notifyObservers(e);
+ update();
}
void QNodePrivate::notifyDynamicPropertyChange(const QByteArray &name, const QVariant &value)
{
+ Q_UNUSED(name);
+ Q_UNUSED(value);
+
// Bail out early if we can to avoid operator new
if (m_blockNotifications)
return;
- auto e = QDynamicPropertyUpdatedChangePtr::create(m_id);
- e->setPropertyName(name);
- e->setValue(value);
- notifyObservers(e);
+ update();
}
/*!
@@ -704,6 +674,14 @@ void QNodePrivate::updatePropertyTrackMode()
}
}
+void QNodePrivate::update()
+{
+ if (m_changeArbiter) {
+ Q_Q(QNode);
+ m_changeArbiter->addDirtyFrontEndNode(q);
+ }
+}
+
/*!
\internal
*/
diff --git a/src/core/nodes/qnode_p.h b/src/core/nodes/qnode_p.h
index 511a0e562..990c2caeb 100644
--- a/src/core/nodes/qnode_p.h
+++ b/src/core/nodes/qnode_p.h
@@ -89,6 +89,8 @@ public:
void insertTree(QNode *treeRoot, int depth = 0);
void updatePropertyTrackMode();
+ void update();
+
Q_DECLARE_PUBLIC(QNode)
// For now this just protects access to the m_changeArbiter.
diff --git a/src/core/qchangearbiter.cpp b/src/core/qchangearbiter.cpp
index 8cfc4b066..6ad72c895 100644
--- a/src/core/qchangearbiter.cpp
+++ b/src/core/qchangearbiter.cpp
@@ -266,6 +266,22 @@ void QChangeArbiter::sceneChangeEventWithLock(const QSceneChangeList &e)
emit receivedChange();
}
+void QChangeArbiter::addDirtyFrontEndNode(QNode *node)
+{
+ if (!m_dirtyFrontEndNodes.contains(node))
+ m_dirtyFrontEndNodes += node;
+}
+
+void QChangeArbiter::removeDirtyFrontEndNode(QNode *node)
+{
+ m_dirtyFrontEndNodes.removeOne(node);
+}
+
+QVector<QNode *> QChangeArbiter::takeDirtyFrontEndNodes()
+{
+ return std::move(m_dirtyFrontEndNodes);
+}
+
// 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 c7d96b593..48fc4ca8c 100644
--- a/src/core/qchangearbiter_p.h
+++ b/src/core/qchangearbiter_p.h
@@ -81,6 +81,8 @@ class Q_3DCORE_PRIVATE_EXPORT QAbstractArbiter : public QLockableObserverInterfa
{
public:
virtual QAbstractPostman *postman() const = 0;
+ virtual void addDirtyFrontEndNode(QNode *node) = 0;
+ virtual void removeDirtyFrontEndNode(QNode *node) = 0;
};
class Q_3DCORE_PRIVATE_EXPORT QChangeArbiter final
@@ -89,7 +91,7 @@ class Q_3DCORE_PRIVATE_EXPORT QChangeArbiter final
{
Q_OBJECT
public:
- explicit QChangeArbiter(QObject *parent = 0);
+ explicit QChangeArbiter(QObject *parent = nullptr);
~QChangeArbiter();
void initialize(Qt3DCore::QAbstractAspectJobManager *jobManager);
@@ -109,6 +111,10 @@ public:
void sceneChangeEventWithLock(const QSceneChangePtr &e) override; // QLockableObserverInterface impl
void sceneChangeEventWithLock(const QSceneChangeList &e) override; // QLockableObserverInterface impl
+ void addDirtyFrontEndNode(QNode *node) override;
+ void removeDirtyFrontEndNode(QNode *node) override;
+ QVector<QNode *> takeDirtyFrontEndNodes();
+
void setPostman(Qt3DCore::QAbstractPostman *postman);
void setScene(Qt3DCore::QScene *scene);
@@ -155,6 +161,8 @@ private:
QList<QChangeQueue *> m_lockingChangeQueues;
QAbstractPostman *m_postman;
QScene *m_scene;
+
+ QVector<QNode *> m_dirtyFrontEndNodes;
};
} // namespace Qt3DCore
diff --git a/src/core/qscene.cpp b/src/core/qscene.cpp
index c94272e90..1b8996e8d 100644
--- a/src/core/qscene.cpp
+++ b/src/core/qscene.cpp
@@ -68,7 +68,7 @@ public:
QMultiHash<QNodeId, QObservableInterface *> m_observablesLookupTable;
QHash<QObservableInterface *, QNodeId> m_observableToUuid;
QHash<QNodeId, QScene::NodePropertyTrackData> m_nodePropertyTrackModeLookupTable;
- QLockableObserverInterface *m_arbiter;
+ QAbstractArbiter *m_arbiter;
QScopedPointer<NodePostConstructorInit> m_postConstructorInit;
mutable QReadWriteLock m_lock;
mutable QReadWriteLock m_nodePropertyTrackModeLock;
@@ -183,13 +183,13 @@ QNode *QScene::rootNode() const
return d->m_rootNode;
}
-void QScene::setArbiter(QLockableObserverInterface *arbiter)
+void QScene::setArbiter(QAbstractArbiter *arbiter)
{
Q_D(QScene);
d->m_arbiter = arbiter;
}
-QLockableObserverInterface *QScene::arbiter() const
+QAbstractArbiter *QScene::arbiter() const
{
Q_D(const QScene);
return d->m_arbiter;
diff --git a/src/core/qscene_p.h b/src/core/qscene_p.h
index afcfb9b40..cdb85ebe6 100644
--- a/src/core/qscene_p.h
+++ b/src/core/qscene_p.h
@@ -65,6 +65,7 @@ namespace Qt3DCore {
class QScenePrivate;
class QAspectEngine;
class NodePostConstructorInit;
+class QAbstractArbiter;
typedef QList<QObservableInterface *> QObservableList;
@@ -88,8 +89,8 @@ public:
QNode *rootNode() const;
- void setArbiter(Qt3DCore::QLockableObserverInterface *arbiter);
- Qt3DCore::QLockableObserverInterface *arbiter() const;
+ void setArbiter(QAbstractArbiter *arbiter);
+ QAbstractArbiter *arbiter() const;
// Component -> Entities
QVector<QNodeId> entitiesForComponent(QNodeId id) const;