refs #759, #761 Track when a cache value notify slot is a member function to avoid duplicate calls.

This commit is contained in:
Mathew Sutcliffe
2016-09-09 17:48:56 +01:00
committed by Roland Winklmeier
parent ad0a7f9526
commit aeb15ea7be
4 changed files with 10 additions and 7 deletions

View File

@@ -672,7 +672,7 @@ namespace BlackMisc
Q_ASSERT(QThread::currentThread() == thread()); Q_ASSERT(QThread::currentThread() == thread());
Q_ASSERT_X(values.valuesChanged(), Q_FUNC_INFO, "packet with unchanged values should not reach here"); Q_ASSERT_X(values.valuesChanged(), Q_FUNC_INFO, "packet with unchanged values should not reach here");
QList<NotifySlot *> notifySlots; CSequence<NotifySlot *> notifySlots;
forEachIntersection(m_elements, values, [changedBy, this, &notifySlots, &values](const QString &, const ElementPtr & element, CValueCachePacket::const_iterator it) forEachIntersection(m_elements, values, [changedBy, this, &notifySlots, &values](const QString &, const ElementPtr & element, CValueCachePacket::const_iterator it)
{ {
@@ -689,7 +689,7 @@ namespace BlackMisc
element->m_value.uniqueWrite() = it.value(); element->m_value.uniqueWrite() = it.value();
element->m_timestamp = it.timestamp(); element->m_timestamp = it.timestamp();
element->m_saved = values.isSaved(); 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); 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() void CValuePage::beginBatch()

View File

@@ -367,7 +367,7 @@ namespace BlackMisc
{ {
using U = typename Private::TClassOfPointerToMember<F>::type; using U = typename Private::TClassOfPointerToMember<F>::type;
Q_ASSERT_X(m_page.parent()->inherits(U::staticMetaObject.className()), Q_FUNC_INFO, "Slot is member function of wrong class"); 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<U *>(obj)); }); m_page.setNotifySlot(m_element, { [slot](QObject *obj) { Private::invokeSlot(slot, static_cast<U *>(obj)); }, makeId(slot) });
} }
//! Read the current value. //! 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<T>()); }; } static Private::CValuePage::Validator wrap(F func) { return [func](const CVariant &value)->bool { return func(value.to<T>()); }; }
static Private::CValuePage::Validator wrap(std::nullptr_t) { return {}; } static Private::CValuePage::Validator wrap(std::nullptr_t) { return {}; }
template <typename F>
static auto makeId(F &&) { return nullptr; }
template <typename U, typename M>
static auto makeId(M U::* slot) { return static_cast<std::tuple_element_t<1, Private::CValuePage::NotifySlot>>(slot); }
const QVariant &getVariant() const { return m_page.getValue(m_element).getQVariant(); } const QVariant &getVariant() const { return m_page.getValue(m_element).getQVariant(); }
QVariant getVariantCopy() const { return m_page.getValueCopy(m_element).getQVariant(); } QVariant getVariantCopy() const { return m_page.getValueCopy(m_element).getQVariant(); }
bool isValid() const { return m_page.isValid(m_element, qMetaTypeId<T>()); } bool isValid() const { return m_page.isValid(m_element, qMetaTypeId<T>()); }

View File

@@ -63,7 +63,7 @@ namespace BlackMisc
using Validator = std::function<bool(const CVariant &)>; using Validator = std::function<bool(const CVariant &)>;
//! Functor used to notify parent of changes. //! Functor used to notify parent of changes.
using NotifySlot = std::function<void(QObject *)>; using NotifySlot = std::pair<std::function<void(QObject *)>, void (QObject::*)()>;
//! Returns a new instance of the opaque Element type for use by CCached<T> to interact with CValuePage. //! Returns a new instance of the opaque Element type for use by CCached<T> to interact with CValuePage.
//! \param key The key string of the value in the cache. //! \param key The key string of the value in the cache.

View File

@@ -191,7 +191,6 @@ namespace BlackMiscTest
void CTestValueCache::batched() void CTestValueCache::batched()
{ {
#if 0 // MS temp disabled 2016-09-09
CValueCache cache; CValueCache cache;
for (int i = 0; i < 2; ++i) { QTest::ignoreMessage(QtDebugMsg, QRegularExpression("Empty cache value")); } for (int i = 0; i < 2; ++i) { QTest::ignoreMessage(QtDebugMsg, QRegularExpression("Empty cache value")); }
CValueCacheUser user1(&cache); CValueCacheUser user1(&cache);
@@ -209,7 +208,6 @@ namespace BlackMiscTest
QVERIFY(user2.m_value1.get() == 42); QVERIFY(user2.m_value1.get() == 42);
QVERIFY(user2.m_value2.get() == 42); QVERIFY(user2.m_value2.get() == 42);
}); });
#endif
} }
void CTestValueCache::json() void CTestValueCache::json()