summaryrefslogtreecommitdiffstats
path: root/src/core/qchangearbiter.cpp
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2014-09-11 09:35:55 +0200
committerSean Harmer <sean.harmer@kdab.com>2014-09-29 13:16:55 +0200
commit2de56c8b9f6ebc275ce7d5ec97599e8548e81d14 (patch)
tree85f9b534f8bf430d015ca2893ddb25a1ef2ea0c5 /src/core/qchangearbiter.cpp
parentbb65f92dcd780b753124314d72ef761944c99353 (diff)
QChangeArbiter overhauled
Change-Id: I46e81f4f428171db5304d11985ddbbb78ab09030 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/core/qchangearbiter.cpp')
-rw-r--r--src/core/qchangearbiter.cpp92
1 files changed, 32 insertions, 60 deletions
diff --git a/src/core/qchangearbiter.cpp b/src/core/qchangearbiter.cpp
index 4506d6e45..120612bbb 100644
--- a/src/core/qchangearbiter.cpp
+++ b/src/core/qchangearbiter.cpp
@@ -56,12 +56,31 @@ QT_BEGIN_NAMESPACE
namespace Qt3D {
+/*!
+ * \class QChangeArbiter
+ * \namespace Qt3D
+ * \since 5.4
+ *
+ * \brief Act as a messages router between observables and observers.
+ * Observables can be of two types : QNode observables and QObservableInterfaces.
+ * QNode observables notifications are sent from the frontend QNode to the backend observers.
+ * QObservableInterface notifications are sent from backend to backend observers and/or backend to QPostman,
+ * the QPostman to deliver the messages to the frontend QNode.
+ *
+ * QNode observables are registered automatically. However QObservableInterface have to be registered manually
+ * by providing the QUuid of the frontend QNode that observables is mapped to.
+ *
+ * Observers can be registered to receive messages from a QObservableInterface/QNode observable by providing a QNode QUuid.
+ * When a notification from a QObservableInterface is received, it is then sent to all observers observing the
+ * QNode QUuid as well as the QPostman to update the frontend QNode.
+ */
QChangeArbiterPrivate::QChangeArbiterPrivate(QChangeArbiter *qq)
: QObjectPrivate()
, m_mutex(QMutex::Recursive)
, m_jobManager(Q_NULLPTR)
, m_postman(Q_NULLPTR)
+ , m_scene(Q_NULLPTR)
{
q_ptr = qq;
}
@@ -126,12 +145,15 @@ void QChangeArbiter::distributeQueueChanges(ChangeQueue *changeQueue)
case QSceneChange::Observable: {
QObservableInterface *subject = change->subject().m_observable;
- if (d->m_aspectObservations.contains(subject)) {
- QObserverList &observers = d->m_aspectObservations[subject];
- Q_FOREACH (const QObserverPair &observer, observers) {
+ QUuid nodeId = d->m_observableToNodeId.value(subject);
+ if (d->m_nodeObservations.contains(nodeId)) {
+ QObserverList &observers = d->m_nodeObservations[nodeId];
+ Q_FOREACH (const QObserverPair&observer, observers) {
if ((change->type() & observer.first))
observer.second->sceneChangeEvent(change);
}
+ // Also send change to the postman
+ d->m_postman->sceneChangeEvent(change);
}
break;
}
@@ -185,36 +207,20 @@ void QChangeArbiter::syncChanges()
}
}
-void QChangeArbiter::registerObserver(QObserverInterface *observer,
- const QUuid &nodeId,
- ChangeFlags changeFlags)
-{
- Q_D(QChangeArbiter);
- QMutexLocker locker(&d->m_mutex);
- QObserverList &observerList = d->m_nodeObservations[nodeId];
- observerList.append(QObserverPair(changeFlags, observer));
-}
-
-void QChangeArbiter::registerObserver(QObserverInterface *observer,
- QObservableInterface *observable,
- ChangeFlags changeFlags)
+void QChangeArbiter::setScene(QSceneInterface *scene)
{
Q_D(QChangeArbiter);
- QMutexLocker locker(&d->m_mutex);
- QObserverList &observerList = d->m_aspectObservations[observable];
- registerObserverHelper(observerList, observer, observable, changeFlags);
+ d->m_scene = scene;
}
void QChangeArbiter::registerObserver(QObserverInterface *observer,
- QNode *observable,
+ const QUuid &nodeId,
ChangeFlags changeFlags)
{
Q_D(QChangeArbiter);
QMutexLocker locker(&d->m_mutex);
- if (!observable)
- return;
- QObserverList &observerList = d->m_nodeObservations[observable->uuid()];
- registerObserverHelper(observerList, observer, observable, changeFlags);
+ QObserverList &observerList = d->m_nodeObservations[nodeId];
+ observerList.append(QObserverPair(changeFlags, observer));
}
// Called from the QAspectThread context, no need to lock
@@ -229,42 +235,6 @@ void QChangeArbiter::registerSceneObserver(QSceneObserverInterface *observer)
d->m_sceneObservers << observer;
}
-void QChangeArbiter::registerObserverHelper(QObserverList &observerList,
- QObserverInterface *observer,
- QObservableInterface *observable,
- ChangeFlags changeFlags)
-{
- Q_ASSERT(observer);
- Q_ASSERT(observable);
- qCDebug(ChangeArbiter) << Q_FUNC_INFO << observable;
-
- // Store info about which observers are watching which observables.
- // Protect access as this could be called from any thread
- observerList.append(QObserverPair(changeFlags, observer));
-
- // Register ourselves with the observable as the intermediary
- observable->registerObserver(this);
-}
-
-void QChangeArbiter::unregisterObserver(QObserverInterface *observer,
- QObservableInterface *subject)
-{
- Q_D(QChangeArbiter);
- QMutexLocker locker(&d->m_mutex);
- if (d->m_aspectObservations.contains(subject)) {
- QObserverList &observers = d->m_aspectObservations[subject];
- for (int i = observers.count() - 1; i >= 0; i--) {
- if (observers[i].second == observer)
- observers.removeAt(i);
- }
- }
-}
-
-void QChangeArbiter::unregisterObserver(QObserverInterface *observer, QNode *subject)
-{
- unregisterObserver(observer, subject->uuid());
-}
-
void QChangeArbiter::unregisterObserver(QObserverInterface *observer, const QUuid &nodeId)
{
Q_D(QChangeArbiter);
@@ -305,6 +275,8 @@ void QChangeArbiter::sceneChangeEventWithLock(const QSceneChangePtr &e)
sceneChangeEvent(e);
}
+// 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(QPostman *postman)
{
Q_D(QChangeArbiter);