From aeb15ea7be41062a7ceb0c23e35468eb401afdaa Mon Sep 17 00:00:00 2001 From: Mathew Sutcliffe Date: Fri, 9 Sep 2016 17:48:56 +0100 Subject: [PATCH] refs #759, #761 Track when a cache value notify slot is a member function to avoid duplicate calls. --- src/blackmisc/valuecache.cpp | 6 +++--- src/blackmisc/valuecache.h | 7 ++++++- src/blackmisc/valuecacheprivate.h | 2 +- tests/blackmisc/testvaluecache.cpp | 2 -- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/blackmisc/valuecache.cpp b/src/blackmisc/valuecache.cpp index e5930e80b..a06629571 100644 --- a/src/blackmisc/valuecache.cpp +++ b/src/blackmisc/valuecache.cpp @@ -672,7 +672,7 @@ namespace BlackMisc Q_ASSERT(QThread::currentThread() == thread()); Q_ASSERT_X(values.valuesChanged(), Q_FUNC_INFO, "packet with unchanged values should not reach here"); - QList notifySlots; + CSequence notifySlots; forEachIntersection(m_elements, values, [changedBy, this, ¬ifySlots, &values](const QString &, const ElementPtr & element, CValueCachePacket::const_iterator it) { @@ -689,7 +689,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)) + if (element->m_notifySlot.first && (! element->m_notifySlot.second || ! notifySlots.containsBy([ & ](auto slot) { return slot->second == element->m_notifySlot.second; }))) { notifySlots.push_back(&element->m_notifySlot); } @@ -701,7 +701,7 @@ namespace BlackMisc } }); - for (auto slot : notifySlots) { (*slot)(parent()); } + for (auto slot : notifySlots) { slot->first(parent()); } } void CValuePage::beginBatch() diff --git a/src/blackmisc/valuecache.h b/src/blackmisc/valuecache.h index ce3a328eb..25014bc1c 100644 --- a/src/blackmisc/valuecache.h +++ b/src/blackmisc/valuecache.h @@ -367,7 +367,7 @@ namespace BlackMisc { using U = typename Private::TClassOfPointerToMember::type; Q_ASSERT_X(m_page.parent()->inherits(U::staticMetaObject.className()), Q_FUNC_INFO, "Slot is member function of wrong class"); - m_page.setNotifySlot(m_element, [slot](QObject *obj) { Private::invokeSlot(slot, static_cast(obj)); }); + m_page.setNotifySlot(m_element, { [slot](QObject *obj) { Private::invokeSlot(slot, static_cast(obj)); }, makeId(slot) }); } //! Read the current value. @@ -419,6 +419,11 @@ namespace BlackMisc static Private::CValuePage::Validator wrap(F func) { return [func](const CVariant &value)->bool { return func(value.to()); }; } static Private::CValuePage::Validator wrap(std::nullptr_t) { return {}; } + template + static auto makeId(F &&) { return nullptr; } + template + static auto makeId(M U::* slot) { return static_cast>(slot); } + const QVariant &getVariant() const { return m_page.getValue(m_element).getQVariant(); } QVariant getVariantCopy() const { return m_page.getValueCopy(m_element).getQVariant(); } bool isValid() const { return m_page.isValid(m_element, qMetaTypeId()); } diff --git a/src/blackmisc/valuecacheprivate.h b/src/blackmisc/valuecacheprivate.h index 05fbf46f3..59dfd965d 100644 --- a/src/blackmisc/valuecacheprivate.h +++ b/src/blackmisc/valuecacheprivate.h @@ -63,7 +63,7 @@ namespace BlackMisc using Validator = std::function; //! Functor used to notify parent of changes. - using NotifySlot = std::function; + using NotifySlot = std::pair, void (QObject::*)()>; //! Returns a new instance of the opaque Element type for use by CCached to interact with CValuePage. //! \param key The key string of the value in the cache. diff --git a/tests/blackmisc/testvaluecache.cpp b/tests/blackmisc/testvaluecache.cpp index ba8c48134..1925d7cd4 100644 --- a/tests/blackmisc/testvaluecache.cpp +++ b/tests/blackmisc/testvaluecache.cpp @@ -191,7 +191,6 @@ namespace BlackMiscTest void CTestValueCache::batched() { -#if 0 // MS temp disabled 2016-09-09 CValueCache cache; for (int i = 0; i < 2; ++i) { QTest::ignoreMessage(QtDebugMsg, QRegularExpression("Empty cache value")); } CValueCacheUser user1(&cache); @@ -209,7 +208,6 @@ namespace BlackMiscTest QVERIFY(user2.m_value1.get() == 42); QVERIFY(user2.m_value2.get() == 42); }); -#endif } void CTestValueCache::json()