diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2014-09-11 09:35:55 +0200 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2014-09-29 13:16:55 +0200 |
commit | 2de56c8b9f6ebc275ce7d5ec97599e8548e81d14 (patch) | |
tree | 85f9b534f8bf430d015ca2893ddb25a1ef2ea0c5 /src/core/qchangearbiter.cpp | |
parent | bb65f92dcd780b753124314d72ef761944c99353 (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.cpp | 92 |
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); |