summaryrefslogtreecommitdiffstats
path: root/src/core/nodes
diff options
context:
space:
mode:
authorMike Krus <mike.krus@kdab.com>2019-08-06 15:30:01 +0100
committerPaul Lemire <paul.lemire@kdab.com>2019-08-28 06:30:29 +0200
commitf3268fcb2a4e73d99dbd66aa5e262a118b5a5480 (patch)
tree374bd9ace2fccaa33534f338950185368ab5598b /src/core/nodes
parent91dc1e1a61651a82a0ee5ce6ad3b24e82f526be6 (diff)
Do direct notification of backend nodeswip/refactor
Since aspect manager is now on main thread, we can directly update backend nodes safely. Track nodes which have changed properties and notify the backend nodes as part of the frame loop. This avoid allocating and delivering many change messages. To follow: - implement on all nodes - look at backend to frontend syncing - figure out what to do with non property messages (components added/removed, commands, ...) Change-Id: Ia0c442b0528e728c4324d168200bae021bc29266 Reviewed-by: Mike Krus <mike.krus@kdab.com> Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src/core/nodes')
-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
5 files changed, 39 insertions, 59 deletions
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.