vlc | branch: master | Romain Vimont <[email protected]> | Thu Nov 19 17:39:40 2020 +0100| [1eb4f1c49d700bd9f86c02bd4d5e522f34f981ed] | committer: Pierre Lamot
qt: medialib: make cache count() asynchronous Make the list cache use an async task for executing the count() call. Signed-off-by: Pierre Lamot <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=1eb4f1c49d700bd9f86c02bd4d5e522f34f981ed --- 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 22ae5e6300..ba0d0b950a 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, &MLSlidingWindowModel<T>::onLocalSizeAboutToBeChanged); + connect(&*m_cache, &BaseListCache::localSizeChanged, + this, &MLSlidingWindowModel<T>::onLocalSizeChanged); connect(&*m_cache, &BaseListCache::localDataChanged, this, &MLSlidingWindowModel<T>::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 fb9cfb5814..141ed7f6b9 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, &ListCache<T>::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>> { _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
