From 06ad77ee9df1556b143777352a1b63fa93524901 Mon Sep 17 00:00:00 2001 From: Mathew Sutcliffe Date: Wed, 9 Mar 2016 20:46:39 +0000 Subject: [PATCH] refs #601 CDataCache overrides connectPage to provide a queue that is more flexible than the usual Qt::QueuedConnection. --- src/blackmisc/datacache.cpp | 37 +++++++++++++++++++++++++++++++++++++ src/blackmisc/datacache.h | 30 ++++++++++++++++++++++++++++++ src/blackmisc/valuecache.h | 3 ++- 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/blackmisc/datacache.cpp b/src/blackmisc/datacache.cpp index d2091fb93..ea8bd5c2a 100644 --- a/src/blackmisc/datacache.cpp +++ b/src/blackmisc/datacache.cpp @@ -14,11 +14,15 @@ #include "blackmisc/identifier.h" #include "blackmisc/atomicfile.h" #include +#include #include namespace BlackMisc { + using Private::CValuePage; + using Private::CDataPageQueue; + class CDataCacheRevision::LockGuard { public: @@ -149,6 +153,39 @@ namespace BlackMisc }); } + void CDataCache::connectPage(CValuePage *page) + { + auto *queue = new CDataPageQueue(page); + connect(page, &CValuePage::valuesWantToCache, this, &CDataCache::changeValues); + connect(this, &CDataCache::valuesChanged, queue, &CDataPageQueue::queueValuesFromCache, Qt::DirectConnection); + + auto *timer = new QTimer(page); + connect(timer, &QTimer::timeout, queue, &CDataPageQueue::trySetQueuedValuesFromCache); + timer->start(0); + } + + void CDataPageQueue::queueValuesFromCache(const CValueCachePacket &values, QObject *changedBy) + { + QMutexLocker lock(&m_mutex); + m_queue.push_back(std::make_pair(values, changedBy)); + } + + void CDataPageQueue::trySetQueuedValuesFromCache() + { + bool locked = m_mutex.tryLock(0); + if (locked) + { + decltype(m_queue) queue; + qSwap(m_queue, queue); + m_mutex.unlock(); + + for (const auto &pair : queue) + { + m_page->setValuesFromCache(pair.first, pair.second); + } + } + } + CDataCacheSerializer::CDataCacheSerializer(CDataCache *owner, const QString &revisionFileName) : CContinuousWorker(owner), m_cache(owner), diff --git a/src/blackmisc/datacache.h b/src/blackmisc/datacache.h index 9c1304fd2..3a8a9b487 100644 --- a/src/blackmisc/datacache.h +++ b/src/blackmisc/datacache.h @@ -22,6 +22,34 @@ namespace BlackMisc { + namespace Private + { + /*! + * Decorator for CValuePage which allows incoming remote changes to be queued to allow for more + * flexibility to control how the queue is popped compared to the usual Qt::QueuedConnection. + */ + class BLACKMISC_EXPORT CDataPageQueue : public QObject + { + Q_OBJECT + + public: + //! Constructor. + CDataPageQueue(CValuePage *parent) : QObject(parent), m_page(parent) {} + + //! Add to the queue to synchronize with a change caused by another page. + //! \threadsafe + void queueValuesFromCache(const BlackMisc::CValueCachePacket &values, QObject *changedBy); + + //! Synchronize with changes queued by queueValuesFromCache, if the mutex is not currently locked. + void trySetQueuedValuesFromCache(); + + private: + CValuePage *m_page = nullptr; + QList> m_queue; + QMutex m_mutex; + }; + } + class CDataCache; /*! @@ -169,6 +197,8 @@ namespace BlackMisc void saveToStoreAsync(const BlackMisc::CValueCachePacket &values); void loadFromStoreAsync(); + virtual void connectPage(Private::CValuePage *page) override; + QFileSystemWatcher m_watcher; const QString m_revisionFileName { persistentStore() + "/.rev" }; diff --git a/src/blackmisc/valuecache.h b/src/blackmisc/valuecache.h index 2645ec43c..98abee759 100644 --- a/src/blackmisc/valuecache.h +++ b/src/blackmisc/valuecache.h @@ -246,7 +246,8 @@ namespace BlackMisc //! \private void valuesChanged(const BlackMisc::CValueCachePacket &values, QObject *changedBy); - private slots: + protected slots: + //! \private void changeValues(const BlackMisc::CValueCachePacket &values); };