[vlc-devel] [PATCH v2 12/13] qt: medialib: make cache count() asynchronous
Romain Vimont
rom1v at videolabs.io
Thu Nov 26 17:10:44 CET 2020
Make the list cache use an async task for executing the count() call.
---
modules/gui/qt/medialibrary/mlbasemodel.cpp | 13 +++++
modules/gui/qt/medialibrary/mlbasemodel.hpp | 7 ++-
modules/gui/qt/util/listcache.hpp | 62 ++++++++++++++++++++-
3 files changed, 78 insertions(+), 4 deletions(-)
diff --git a/modules/gui/qt/medialibrary/mlbasemodel.cpp b/modules/gui/qt/medialibrary/mlbasemodel.cpp
index 24d1362078..65dc1939e1 100644
--- a/modules/gui/qt/medialibrary/mlbasemodel.cpp
+++ b/modules/gui/qt/medialibrary/mlbasemodel.cpp
@@ -66,6 +66,19 @@ void MLBaseModel::onResetRequested()
endResetModel();
}
+void MLBaseModel::onLocalSizeAboutToBeChanged(size_t size)
+{
+ (void) size;
+ beginResetModel();
+}
+
+void MLBaseModel::onLocalSizeChanged(size_t size)
+{
+ (void) size;
+ endResetModel();
+ emit countChanged(size);
+}
+
void MLBaseModel::onLocalDataChanged(size_t offset, size_t count)
{
assert(count);
diff --git a/modules/gui/qt/medialibrary/mlbasemodel.hpp b/modules/gui/qt/medialibrary/mlbasemodel.hpp
index 09e863961b..3868a34651 100644
--- a/modules/gui/qt/medialibrary/mlbasemodel.hpp
+++ b/modules/gui/qt/medialibrary/mlbasemodel.hpp
@@ -70,6 +70,8 @@ signals:
protected slots:
void onResetRequested();
+ void onLocalSizeAboutToBeChanged(size_t size);
+ void onLocalSizeChanged(size_t size);
void onLocalDataChanged(size_t index, size_t count);
private:
@@ -222,11 +224,14 @@ protected:
auto &threadPool = m_mediaLib->threadPool();
auto loader = createLoader();
m_cache.reset(new ListCache<std::unique_ptr<T>>(threadPool, loader));
+ connect(&*m_cache, &BaseListCache::localSizeAboutToBeChanged,
+ this, &MLBaseModel::onLocalSizeAboutToBeChanged);
+ connect(&*m_cache, &BaseListCache::localSizeChanged,
+ this, &MLBaseModel::onLocalSizeChanged);
connect(&*m_cache, &BaseListCache::localDataChanged,
this, &MLBaseModel::onLocalDataChanged);
m_cache->initCount();
- emit countChanged( static_cast<unsigned int>(m_cache->count()) );
}
void invalidateCache()
diff --git a/modules/gui/qt/util/listcache.hpp b/modules/gui/qt/util/listcache.hpp
index c476ee18d3..08722256d9 100644
--- a/modules/gui/qt/util/listcache.hpp
+++ b/modules/gui/qt/util/listcache.hpp
@@ -72,12 +72,20 @@ class BaseListCache : public QObject
Q_OBJECT
signals:
+ /* useful for signaling QAbstractItemModel::modelAboutToBeReset() */
+ void localSizeAboutToBeChanged(size_t size);
+
+ void localSizeChanged(size_t size);
void localDataChanged(size_t index, size_t count);
protected slots:
virtual void onLoadResult() = 0;
+ virtual void onCountResult() = 0;
};
+template <typename T>
+class CountTask;
+
template <typename T>
class LoadTask;
@@ -147,9 +155,11 @@ public:
void refer(size_t index);
private:
+ void asyncLoad(size_t offset, size_t count);
void onLoadResult() override;
- void asyncLoad(size_t offset, size_t count);
+ void asyncCount();
+ void onCountResult() override;
QThreadPool &m_threadPool;
/* Ownershipshared between this cache and the runnable spawned to execute
@@ -161,14 +171,18 @@ private:
ssize_t m_total_count = COUNT_UNINITIALIZED;
size_t m_offset = 0;
+ bool m_countRequested = false;
MLRange m_lastRangeRequested;
LoadTask<T> *m_loadTask = nullptr;
+ CountTask<T> *m_countTask = nullptr;
};
template <typename T>
ListCache<T>::~ListCache()
{
+ if (m_countTask)
+ m_countTask->abandon();
if (m_loadTask)
m_loadTask->abandon();
}
@@ -192,8 +206,8 @@ ssize_t ListCache<T>::count() const
template <typename T>
void ListCache<T>::initCount()
{
- assert(m_total_count == COUNT_UNINITIALIZED);
- m_total_count = static_cast<ssize_t>(m_loader->count());
+ assert(!m_countRequested);
+ asyncCount();
}
template <typename T>
@@ -221,6 +235,48 @@ void ListCache<T>::refer(size_t index)
}
}
+template <typename T>
+class CountTask : public AsyncTask<size_t>
+{
+public:
+ CountTask(QSharedPointer<ListCacheLoader<T>> loader) : m_loader(loader) {}
+
+ size_t execute() override
+ {
+ return m_loader->count();
+ }
+
+private:
+ QSharedPointer<ListCacheLoader<T>> m_loader;
+};
+
+template <typename T>
+void ListCache<T>::asyncCount()
+{
+ assert(!m_countTask);
+
+ m_countTask = new CountTask<T>(m_loader);
+ connect(m_countTask, &BaseAsyncTask::result,
+ this, &BaseListCache::onCountResult);
+ m_countRequested = true;
+ m_countTask->start(m_threadPool);
+}
+
+template <typename T>
+void ListCache<T>::onCountResult()
+{
+ CountTask<T> *task = static_cast<CountTask<T> *>(sender());
+ assert(task == m_countTask);
+
+ m_offset = 0;
+ m_list.clear();
+ m_total_count = static_cast<ssize_t>(task->takeResult());
+ emit localSizeChanged(m_total_count);
+
+ task->abandon();
+ m_countTask = nullptr;
+}
+
template <typename T>
class LoadTask : public AsyncTask<std::vector<T>>
{
--
2.29.2
More information about the vlc-devel
mailing list