diff --git a/src/blackmisc/valuecache.cpp b/src/blackmisc/valuecache.cpp index 27099e94f..a8bd21509 100644 --- a/src/blackmisc/valuecache.cpp +++ b/src/blackmisc/valuecache.cpp @@ -108,11 +108,11 @@ namespace BlackMisc return **m_elements.insert(pos, key, ElementPtr(new Element(key))); } - std::pair CValueCache::getValue(const QString &key) + std::tuple CValueCache::getValue(const QString &key) { QMutexLocker lock(&m_mutex); const auto &element = getElement(key); - return std::make_pair(element.m_value, element.m_timestamp.load()); + return std::make_tuple(element.m_value, element.m_timestamp.load(), element.m_saved); } CVariantMap CValueCache::getAllValues(const QString &keyPrefix) const @@ -369,6 +369,7 @@ namespace BlackMisc const CVariant m_default; const NotifySlot m_notifySlot = nullptr; int m_pendingChanges = 0; + bool m_saved = false; }; CValuePage::Element &CValuePage::createElement(const QString &key, int metaType, Validator validator, const CVariant &defaultValue, NotifySlot slot) @@ -378,7 +379,7 @@ namespace BlackMisc Q_ASSERT_X(defaultValue.isValid() && validator ? validator(defaultValue) : true, "CValuePage", "Validator rejects default value"); auto &element = *(m_elements[key] = ElementPtr(new Element(key, metaType, validator, defaultValue, slot))); - std::forward_as_tuple(element.m_value.uniqueWrite(), element.m_timestamp) = m_cache->getValue(key); + std::forward_as_tuple(element.m_value.uniqueWrite(), element.m_timestamp, element.m_saved) = m_cache->getValue(key); auto error = validate(element, element.m_value.read()); if (! error.isEmpty()) @@ -411,6 +412,7 @@ namespace BlackMisc { Q_ASSERT(isSafeToIncrement(element.m_pendingChanges)); element.m_pendingChanges++; + element.m_saved = false; element.m_value.uniqueWrite() = value; emit valuesWantToCache({ { { element.m_key, value } }, QDateTime::currentMSecsSinceEpoch() }); @@ -433,13 +435,23 @@ namespace BlackMisc return element.m_timestamp; } + bool CValuePage::isSaved(const Element &element) const + { + return element.m_saved && ! element.m_pendingChanges; + } + + bool CValuePage::isSaving(const Element &element) const + { + return element.m_saved && element.m_pendingChanges; + } + void CValuePage::setValuesFromCache(const CValueCachePacket &values, QObject *changedBy) { Q_ASSERT(QThread::currentThread() == thread()); QList notifySlots; - forEachIntersection(m_elements, values, [changedBy, this, ¬ifySlots](const QString &, const ElementPtr &element, CValueCachePacket::const_iterator it) + forEachIntersection(m_elements, values, [changedBy, this, ¬ifySlots, &values](const QString &, const ElementPtr &element, CValueCachePacket::const_iterator it) { if (changedBy == this) // round trip { @@ -453,6 +465,7 @@ namespace BlackMisc { element->m_value.uniqueWrite() = it.value(); element->m_timestamp = it.timestamp(); + element->m_saved = values.isSaved(); if (element->m_notifySlot && ! notifySlots.contains(element->m_notifySlot)) { notifySlots.push_back(element->m_notifySlot); } } else @@ -498,6 +511,7 @@ namespace BlackMisc element->m_pendingChanges++; element->m_value.uniqueWrite() = it.value(); element->m_timestamp = timestamp; + element->m_saved = false; }); emit valuesWantToCache({ m_batchedValues, timestamp }); } diff --git a/src/blackmisc/valuecache.h b/src/blackmisc/valuecache.h index 574afe521..5675e08d6 100644 --- a/src/blackmisc/valuecache.h +++ b/src/blackmisc/valuecache.h @@ -221,7 +221,7 @@ namespace BlackMisc Element &getElement(const QString &key); Element &getElement(const QString &key, QMap::const_iterator pos); - std::pair getValue(const QString &key); + std::tuple getValue(const QString &key); signals: //! \private @@ -280,6 +280,12 @@ namespace BlackMisc //! Return the time when this value was updated. QDateTime getTimestamp() const { return m_page.getTimestamp(m_element); } + //! Return true if this value was already saved. + bool isSaved() const { return m_page.isSaved(m_element); } + + //! Return true if this value is currently saving. + bool isSaving() const { return m_page.isSaving(m_element); } + //! Deleted copy constructor. CCached(const CCached &) = delete; diff --git a/src/blackmisc/valuecacheprivate.h b/src/blackmisc/valuecacheprivate.h index 43b7d82bc..89e0cc5e6 100644 --- a/src/blackmisc/valuecacheprivate.h +++ b/src/blackmisc/valuecacheprivate.h @@ -70,6 +70,12 @@ namespace BlackMisc //! Get the timestamp corresponding to the element. qint64 getTimestamp(const Element &element) const; + //! Get whether this element is already saved to disk. + bool isSaved(const Element &element) const; + + //! Get whether this element is currently being saved to disk. + bool isSaving(const Element &element) const; + //! Synchronize with a change caused by another page. //! Connected to signal CValueCache::valuesChanged. //! \param values The new values.