From fb003150f5bc55ec4aa04285d3b0fa1b531b445b Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Tue, 17 Nov 2020 16:34:02 +0100 Subject: [PATCH] qt: medialib: implement separate data loaders When the database queries are executed asynchronously, we must still be able to delete a list model from the main thread without blocking. As a consequence, the data loader must be able to outlive the list model instance; this implies that loading data must not involve calling methods on the list model itself (fetch() and countTotalElements()). Nevertheless, the actual data to load depends on the list model (the content is not the same between a list of videos and a list of albums). To be able to detach the lifetime of the data loader from the one of the list model, make the list models provide loader instances on demand, instead of implementing the loading methods directly. Signed-off-by: Pierre Lamot --- modules/gui/qt/medialibrary/mlalbummodel.cpp | 50 +++++++++------ modules/gui/qt/medialibrary/mlalbummodel.hpp | 12 +++- modules/gui/qt/medialibrary/mlalbumtrackmodel.cpp | 64 ++++++++++-------- modules/gui/qt/medialibrary/mlalbumtrackmodel.hpp | 12 +++- modules/gui/qt/medialibrary/mlartistmodel.cpp | 63 ++++++++++-------- modules/gui/qt/medialibrary/mlartistmodel.hpp | 12 +++- modules/gui/qt/medialibrary/mlbasemodel.hpp | 57 ++++++++-------- modules/gui/qt/medialibrary/mlgenremodel.cpp | 54 +++++++++------- modules/gui/qt/medialibrary/mlgenremodel.hpp | 12 +++- modules/gui/qt/medialibrary/mlrecentsmodel.cpp | 74 ++++++++++++--------- modules/gui/qt/medialibrary/mlrecentsmodel.hpp | 20 +++++- .../gui/qt/medialibrary/mlrecentsvideomodel.cpp | 75 +++++++++++++--------- .../gui/qt/medialibrary/mlrecentsvideomodel.hpp | 24 ++++++- modules/gui/qt/medialibrary/mlurlmodel.cpp | 55 +++++++++------- modules/gui/qt/medialibrary/mlurlmodel.hpp | 12 +++- modules/gui/qt/medialibrary/mlvideomodel.cpp | 51 +++++++++------ modules/gui/qt/medialibrary/mlvideomodel.hpp | 12 +++- 17 files changed, 404 insertions(+), 255 deletions(-) diff --git a/modules/gui/qt/medialibrary/mlalbummodel.cpp b/modules/gui/qt/medialibrary/mlalbummodel.cpp index 6af6079975..23bb3e74d4 100644 --- a/modules/gui/qt/medialibrary/mlalbummodel.cpp +++ b/modules/gui/qt/medialibrary/mlalbummodel.cpp @@ -88,23 +88,6 @@ QHash MLAlbumModel::roleNames() const }; } -std::vector> MLAlbumModel::fetch(const MLQueryParams ¶ms) const -{ - auto queryParams = params.toCQueryParams(); - - ml_unique_ptr album_list; - if ( m_parent.id <= 0 ) - album_list.reset( vlc_ml_list_albums(m_ml, &queryParams) ); - else - album_list.reset( vlc_ml_list_albums_of(m_ml, &queryParams, m_parent.type, m_parent.id ) ); - if ( album_list == nullptr ) - return {}; - std::vector> res; - for( const vlc_ml_album_t& album: ml_range_iterate( album_list ) ) - res.emplace_back( std::make_unique( m_ml, &album ) ); - return res; -} - vlc_ml_sorting_criteria_t MLAlbumModel::nameToCriteria(QByteArray name) const { return M_names_to_criteria.value(name, VLC_ML_SORTING_DEFAULT); @@ -163,12 +146,37 @@ vlc_ml_sorting_criteria_t MLAlbumModel::roleToCriteria(int role) const } } -size_t MLAlbumModel::countTotalElements(const MLQueryParams ¶ms) const +ListCacheLoader> * +MLAlbumModel::createLoader() const +{ + return new Loader(*this); +} + +size_t MLAlbumModel::Loader::count() const { - vlc_ml_query_params_t queryParams = params.toCQueryParams(); - queryParams.i_offset = 0; - queryParams.i_nbResults = 0; + MLQueryParams params = getParams(); + auto queryParams = params.toCQueryParams(); + if ( m_parent.id <= 0 ) return vlc_ml_count_albums(m_ml, &queryParams); return vlc_ml_count_albums_of(m_ml, &queryParams, m_parent.type, m_parent.id); } + +std::vector> +MLAlbumModel::Loader::load(size_t index, size_t count) const +{ + MLQueryParams params = getParams(index, count); + auto queryParams = params.toCQueryParams(); + + ml_unique_ptr album_list; + if ( m_parent.id <= 0 ) + album_list.reset( vlc_ml_list_albums(m_ml, &queryParams) ); + else + album_list.reset( vlc_ml_list_albums_of(m_ml, &queryParams, m_parent.type, m_parent.id ) ); + if ( album_list == nullptr ) + return {}; + std::vector> res; + for( const vlc_ml_album_t& album: ml_range_iterate( album_list ) ) + res.emplace_back( std::make_unique( m_ml, &album ) ); + return res; +} diff --git a/modules/gui/qt/medialibrary/mlalbummodel.hpp b/modules/gui/qt/medialibrary/mlalbummodel.hpp index 3aba91def7..9f57d77b78 100644 --- a/modules/gui/qt/medialibrary/mlalbummodel.hpp +++ b/modules/gui/qt/medialibrary/mlalbummodel.hpp @@ -57,9 +57,10 @@ public: Q_INVOKABLE QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; Q_INVOKABLE QHash roleNames() const override; +protected: + ListCacheLoader> *createLoader() const override; + private: - std::vector> fetch(const MLQueryParams ¶ms) const override; - size_t countTotalElements(const MLQueryParams ¶ms) const override; vlc_ml_sorting_criteria_t roleToCriteria(int role) const override; vlc_ml_sorting_criteria_t nameToCriteria(QByteArray name) const override; QByteArray criteriaToName(vlc_ml_sorting_criteria_t criteria) const override; @@ -67,6 +68,13 @@ private: void thumbnailUpdated(int idx) override; static QHash M_names_to_criteria; + + struct Loader : public BaseLoader + { + Loader(const MLAlbumModel &model) : BaseLoader(model) {} + size_t count() const override; + std::vector> load(size_t index, size_t count) const override; + }; }; diff --git a/modules/gui/qt/medialibrary/mlalbumtrackmodel.cpp b/modules/gui/qt/medialibrary/mlalbumtrackmodel.cpp index e40d069884..fab64930f8 100644 --- a/modules/gui/qt/medialibrary/mlalbumtrackmodel.cpp +++ b/modules/gui/qt/medialibrary/mlalbumtrackmodel.cpp @@ -93,34 +93,6 @@ QHash MLAlbumTrackModel::roleNames() const }; } -size_t MLAlbumTrackModel::countTotalElements(const MLQueryParams ¶ms) const -{ - auto queryParams = params.toCQueryParams(); - queryParams.i_offset = 0; - queryParams.i_nbResults = 0; - if ( m_parent.id <= 0 ) - return vlc_ml_count_audio_media(m_ml, &queryParams); - return vlc_ml_count_media_of(m_ml, &queryParams, m_parent.type, m_parent.id ); -} - -std::vector> MLAlbumTrackModel::fetch(const MLQueryParams ¶ms) const -{ - auto queryParams = params.toCQueryParams(); - - ml_unique_ptr media_list; - - if ( m_parent.id <= 0 ) - media_list.reset( vlc_ml_list_audio_media(m_ml, &queryParams) ); - else - media_list.reset( vlc_ml_list_media_of(m_ml, &queryParams, m_parent.type, m_parent.id ) ); - if ( media_list == nullptr ) - return {}; - std::vector> res; - for( const vlc_ml_media_t& media: ml_range_iterate( media_list ) ) - res.emplace_back( std::make_unique( m_ml, &media ) ); - return res; -} - vlc_ml_sorting_criteria_t MLAlbumTrackModel::roleToCriteria(int role) const { switch (role) { @@ -178,3 +150,39 @@ void MLAlbumTrackModel::onVlcMlEvent(const MLEvent &event) } MLBaseModel::onVlcMlEvent( event ); } + +ListCacheLoader> * +MLAlbumTrackModel::createLoader() const +{ + return new Loader(*this); +} + +size_t MLAlbumTrackModel::Loader::count() const +{ + MLQueryParams params = getParams(); + auto queryParams = params.toCQueryParams(); + + if ( m_parent.id <= 0 ) + return vlc_ml_count_audio_media(m_ml, &queryParams); + return vlc_ml_count_media_of(m_ml, &queryParams, m_parent.type, m_parent.id ); +} + +std::vector> +MLAlbumTrackModel::Loader::load(size_t index, size_t count) const +{ + MLQueryParams params = getParams(index, count); + auto queryParams = params.toCQueryParams(); + + ml_unique_ptr media_list; + + if ( m_parent.id <= 0 ) + media_list.reset( vlc_ml_list_audio_media(m_ml, &queryParams) ); + else + media_list.reset( vlc_ml_list_media_of(m_ml, &queryParams, m_parent.type, m_parent.id ) ); + if ( media_list == nullptr ) + return {}; + std::vector> res; + for( const vlc_ml_media_t& media: ml_range_iterate( media_list ) ) + res.emplace_back( std::make_unique( m_ml, &media ) ); + return res; +} diff --git a/modules/gui/qt/medialibrary/mlalbumtrackmodel.hpp b/modules/gui/qt/medialibrary/mlalbumtrackmodel.hpp index 6fe867c319..e494b597cb 100644 --- a/modules/gui/qt/medialibrary/mlalbumtrackmodel.hpp +++ b/modules/gui/qt/medialibrary/mlalbumtrackmodel.hpp @@ -57,14 +57,22 @@ public: QVariant data(const QModelIndex &index, int role) const override; QHash roleNames() const override; +protected: + ListCacheLoader> *createLoader() const override; + private: - std::vector> fetch(const MLQueryParams ¶ms) const override; - size_t countTotalElements(const MLQueryParams ¶ms) const override; vlc_ml_sorting_criteria_t roleToCriteria(int role) const override; vlc_ml_sorting_criteria_t nameToCriteria(QByteArray name) const override; QByteArray criteriaToName(vlc_ml_sorting_criteria_t criteria) const override; virtual void onVlcMlEvent( const MLEvent &event ) override; static QHash M_names_to_criteria; + + struct Loader : public BaseLoader + { + Loader(const MLAlbumTrackModel &model) : BaseLoader(model) {} + size_t count() const override; + std::vector> load(size_t index, size_t count) const override; + }; }; #endif // MLTRACKMODEL_HPP diff --git a/modules/gui/qt/medialibrary/mlartistmodel.cpp b/modules/gui/qt/medialibrary/mlartistmodel.cpp index e264120cee..7422709096 100644 --- a/modules/gui/qt/medialibrary/mlartistmodel.cpp +++ b/modules/gui/qt/medialibrary/mlartistmodel.cpp @@ -67,34 +67,6 @@ QHash MLArtistModel::roleNames() const }; } -std::vector> MLArtistModel::fetch(const MLQueryParams ¶ms) const -{ - auto queryParams = params.toCQueryParams(); - - ml_unique_ptr artist_list; - if ( m_parent.id <= 0 ) - artist_list.reset( vlc_ml_list_artists(m_ml, &queryParams, false) ); - else - artist_list.reset( vlc_ml_list_artist_of(m_ml, &queryParams, m_parent.type, m_parent.id) ); - if ( artist_list == nullptr ) - return {}; - std::vector> res; - for( const vlc_ml_artist_t& artist: ml_range_iterate( artist_list ) ) - res.emplace_back( std::make_unique( &artist ) ); - return res; -} - -size_t MLArtistModel::countTotalElements(const MLQueryParams ¶ms) const -{ - auto queryParams = params.toCQueryParams(); - queryParams.i_offset = 0; - queryParams.i_nbResults = 0; - - if ( m_parent.id <= 0 ) - return vlc_ml_count_artists(m_ml, &queryParams, false); - return vlc_ml_count_artists_of(m_ml, &queryParams, m_parent.type, m_parent.id ); -} - vlc_ml_sorting_criteria_t MLArtistModel::roleToCriteria(int role) const { switch (role) @@ -138,3 +110,38 @@ void MLArtistModel::thumbnailUpdated(int idx) { emit dataChanged(index(idx), index(idx), {ARTIST_COVER}); } + +ListCacheLoader> * +MLArtistModel::createLoader() const +{ + return new Loader(*this); +} + +size_t MLArtistModel::Loader::count() const +{ + MLQueryParams params = getParams(); + auto queryParams = params.toCQueryParams(); + + if ( m_parent.id <= 0 ) + return vlc_ml_count_artists(m_ml, &queryParams, false); + return vlc_ml_count_artists_of(m_ml, &queryParams, m_parent.type, m_parent.id ); +} + +std::vector> +MLArtistModel::Loader::load(size_t index, size_t count) const +{ + MLQueryParams params = getParams(index, count); + auto queryParams = params.toCQueryParams(); + + ml_unique_ptr artist_list; + if ( m_parent.id <= 0 ) + artist_list.reset( vlc_ml_list_artists(m_ml, &queryParams, false) ); + else + artist_list.reset( vlc_ml_list_artist_of(m_ml, &queryParams, m_parent.type, m_parent.id) ); + if ( artist_list == nullptr ) + return {}; + std::vector> res; + for( const vlc_ml_artist_t& artist: ml_range_iterate( artist_list ) ) + res.emplace_back( std::make_unique( &artist ) ); + return res; +} diff --git a/modules/gui/qt/medialibrary/mlartistmodel.hpp b/modules/gui/qt/medialibrary/mlartistmodel.hpp index d0fe4d1baa..8926731b87 100644 --- a/modules/gui/qt/medialibrary/mlartistmodel.hpp +++ b/modules/gui/qt/medialibrary/mlartistmodel.hpp @@ -48,9 +48,10 @@ public: QVariant data(const QModelIndex &index, int role) const override; QHash roleNames() const override; +protected: + ListCacheLoader> *createLoader() const override; + private: - std::vector> fetch(const MLQueryParams ¶ms) const override; - size_t countTotalElements(const MLQueryParams ¶ms) const override; vlc_ml_sorting_criteria_t roleToCriteria(int role) const override; vlc_ml_sorting_criteria_t nameToCriteria(QByteArray name) const override; QByteArray criteriaToName(vlc_ml_sorting_criteria_t criteria) const override; @@ -58,6 +59,13 @@ private: void thumbnailUpdated(int idx) override; static QHash M_names_to_criteria; + + struct Loader : public BaseLoader + { + Loader(const MLArtistModel &model) : BaseLoader(model) {} + size_t count() const override; + std::vector> load(size_t index, size_t count) const override; + }; }; #endif // MLARTISTMODEL_HPP diff --git a/modules/gui/qt/medialibrary/mlbasemodel.hpp b/modules/gui/qt/medialibrary/mlbasemodel.hpp index 70e1524c20..39a67cdd46 100644 --- a/modules/gui/qt/medialibrary/mlbasemodel.hpp +++ b/modules/gui/qt/medialibrary/mlbasemodel.hpp @@ -212,12 +212,14 @@ public: } protected: + virtual ListCacheLoader> *createLoader() const = 0; + void validateCache() const { if (m_cache) return; - auto loader = new Loader(*this); + auto loader = createLoader(); m_cache.reset(new ListCache>(loader)); connect(&*m_cache, &BaseListCache::localDataChanged, this, &MLSlidingWindowModel::onLocalDataChanged); @@ -290,48 +292,41 @@ protected: MLBaseModel::onVlcMlEvent( event ); } -private: - virtual size_t countTotalElements(const MLQueryParams ¶ms) const = 0; - virtual std::vector> fetch(const MLQueryParams ¶ms) const = 0; - virtual void thumbnailUpdated( int ) {} - /* Data loader for the cache */ - struct Loader : public ListCacheLoader> + struct BaseLoader : public ListCacheLoader> { - Loader(const MLSlidingWindowModel &model) - : m_model(model) - , m_searchPattern(model.m_search_pattern) - , m_sort(model.m_sort) - , m_sort_desc(model.m_sort_desc) + BaseLoader(vlc_medialibrary_t *ml, MLParentId parent, QString searchPattern, + vlc_ml_sorting_criteria_t sort, bool sort_desc) + : m_ml(ml) + , m_parent(parent) + , m_searchPattern(searchPattern) + , m_sort(sort) + , m_sort_desc(sort_desc) { } - size_t count() const override; - std::vector> load(size_t index, size_t count) const override; + BaseLoader(const MLSlidingWindowModel &model) + : BaseLoader(model.m_ml, model.m_parent, model.m_search_pattern, model.m_sort, model.m_sort_desc) + { + } + + MLQueryParams getParams(size_t index = 0, size_t count = 0) const + { + return { m_searchPattern.toUtf8(), m_sort, m_sort_desc, index, count }; + } - private: - const MLSlidingWindowModel &m_model; + protected: + vlc_medialibrary_t *m_ml; + MLParentId m_parent; QString m_searchPattern; vlc_ml_sorting_criteria_t m_sort; bool m_sort_desc; }; +private: + virtual void thumbnailUpdated( int ) {} + mutable std::unique_ptr>> m_cache; }; -template -size_t MLSlidingWindowModel::Loader::count() const -{ - MLQueryParams params{ m_searchPattern.toUtf8(), m_sort, m_sort_desc }; - return m_model.countTotalElements(params); -} - -template -std::vector> -MLSlidingWindowModel::Loader::load(size_t index, size_t count) const -{ - MLQueryParams params{ m_searchPattern.toUtf8(), m_sort, m_sort_desc, index, count }; - return m_model.fetch(params); -} - #endif // MLBASEMODEL_HPP diff --git a/modules/gui/qt/medialibrary/mlgenremodel.cpp b/modules/gui/qt/medialibrary/mlgenremodel.cpp index 9ae0186761..b9c562a5f8 100644 --- a/modules/gui/qt/medialibrary/mlgenremodel.cpp +++ b/modules/gui/qt/medialibrary/mlgenremodel.cpp @@ -68,28 +68,6 @@ QHash MLGenreModel::roleNames() const }; } -std::vector> MLGenreModel::fetch(const MLQueryParams ¶ms) const -{ - auto queryParams = params.toCQueryParams(); - ml_unique_ptr genre_list( - vlc_ml_list_genres(m_ml, &queryParams) - ); - if ( genre_list == nullptr ) - return {}; - std::vector> res; - for( const vlc_ml_genre_t& genre: ml_range_iterate( genre_list ) ) - res.emplace_back( std::make_unique( m_ml, &genre ) ); - return res; -} - -size_t MLGenreModel::countTotalElements(const MLQueryParams ¶ms) const -{ - auto queryParams = params.toCQueryParams(); - queryParams.i_offset = 0; - queryParams.i_nbResults = 0; - return vlc_ml_count_genres( m_ml, &queryParams ); -} - void MLGenreModel::onVlcMlEvent(const MLEvent &event) { switch (event.i_type) @@ -123,3 +101,35 @@ vlc_ml_sorting_criteria_t MLGenreModel::nameToCriteria(QByteArray name) const { return M_names_to_criteria.value(name, VLC_ML_SORTING_DEFAULT); } + +ListCacheLoader> * +MLGenreModel::createLoader() const +{ + return new Loader(*this); +} + +size_t MLGenreModel::Loader::count() const +{ + MLQueryParams params = getParams(); + auto queryParams = params.toCQueryParams(); + + return vlc_ml_count_genres( m_ml, &queryParams ); +} + +std::vector> +MLGenreModel::Loader::load(size_t index, size_t count) const +{ + MLQueryParams params = getParams(index, count); + auto queryParams = params.toCQueryParams(); + + ml_unique_ptr genre_list( + vlc_ml_list_genres(m_ml, &queryParams) + ); + if ( genre_list == nullptr ) + return {}; + std::vector> res; + for( const vlc_ml_genre_t& genre: ml_range_iterate( genre_list ) ) + res.emplace_back( std::make_unique( m_ml, &genre ) ); + return res; + +} diff --git a/modules/gui/qt/medialibrary/mlgenremodel.hpp b/modules/gui/qt/medialibrary/mlgenremodel.hpp index 33dc8c89db..10e0ae8daa 100644 --- a/modules/gui/qt/medialibrary/mlgenremodel.hpp +++ b/modules/gui/qt/medialibrary/mlgenremodel.hpp @@ -51,9 +51,10 @@ public: QHash roleNames() const override; QVariant data(const QModelIndex &index, int role) const override; +protected: + ListCacheLoader> *createLoader() const override; + private: - std::vector> fetch(const MLQueryParams ¶ms) const override; - size_t countTotalElements(const MLQueryParams ¶ms) const override; void onVlcMlEvent(const MLEvent &event) override; void thumbnailUpdated(int idx) override; vlc_ml_sorting_criteria_t roleToCriteria(int role) const override; @@ -61,6 +62,13 @@ private: static QHash M_names_to_criteria; + + struct Loader : public BaseLoader + { + Loader(const MLGenreModel &model) : BaseLoader(model) {} + size_t count() const override; + std::vector> load(size_t index, size_t count) const override; + }; }; diff --git a/modules/gui/qt/medialibrary/mlrecentsmodel.cpp b/modules/gui/qt/medialibrary/mlrecentsmodel.cpp index 8bd538d20c..7d4b5cc7e2 100644 --- a/modules/gui/qt/medialibrary/mlrecentsmodel.cpp +++ b/modules/gui/qt/medialibrary/mlrecentsmodel.cpp @@ -79,38 +79,6 @@ void MLRecentsModel::clearHistory() vlc_ml_clear_history(m_ml); } -std::vector > MLRecentsModel::fetch(const MLQueryParams ¶ms) const -{ - std::vector> res; - auto queryParams = params.toCQueryParams(); - if (m_numberOfItemsToShow >= 0) - { - if (queryParams.i_offset <= static_cast(m_numberOfItemsToShow)) - queryParams.i_nbResults = static_cast(m_numberOfItemsToShow) - queryParams.i_offset; - else - return res; - } - - ml_unique_ptr media_list{ vlc_ml_list_history( - m_ml, &queryParams ) }; - if ( media_list == nullptr ) - return {}; - for( vlc_ml_media_t &media: ml_range_iterate( media_list ) ) - res.emplace_back( std::make_unique( &media ) ); - return res; -} - -size_t MLRecentsModel::countTotalElements(const MLQueryParams ¶ms) const -{ - auto queryParams = params.toCQueryParams(); - queryParams.i_offset = 0; - queryParams.i_nbResults = m_numberOfItemsToShow; - size_t realCount = vlc_ml_count_history( m_ml, &queryParams ); - if (m_numberOfItemsToShow >= 0) - return std::min( realCount, static_cast(m_numberOfItemsToShow) ); - return realCount; -} - void MLRecentsModel::onVlcMlEvent( const MLEvent &event ) { switch ( event.i_type ) @@ -127,7 +95,49 @@ void MLRecentsModel::onVlcMlEvent( const MLEvent &event ) } void MLRecentsModel::setNumberOfItemsToShow( int n ){ m_numberOfItemsToShow = n; + invalidateCache(); } int MLRecentsModel::getNumberOfItemsToShow() const { return m_numberOfItemsToShow; } + +ListCacheLoader> * +MLRecentsModel::createLoader() const +{ + return new Loader(*this, m_numberOfItemsToShow); +} + +size_t MLRecentsModel::Loader::count() const +{ + MLQueryParams params = getParams(); + auto queryParams = params.toCQueryParams(); + + size_t realCount = vlc_ml_count_history( m_ml, &queryParams ); + if (m_numberOfItemsToShow >= 0) + return std::min( realCount, static_cast(m_numberOfItemsToShow) ); + return realCount; +} + +std::vector> +MLRecentsModel::Loader::load(size_t index, size_t count) const +{ + MLQueryParams params = getParams(index, count); + auto queryParams = params.toCQueryParams(); + + std::vector> res; + if (m_numberOfItemsToShow >= 0) + { + if (queryParams.i_offset <= static_cast(m_numberOfItemsToShow)) + queryParams.i_nbResults = static_cast(m_numberOfItemsToShow) - queryParams.i_offset; + else + return res; + } + + ml_unique_ptr media_list{ vlc_ml_list_history( + m_ml, &queryParams ) }; + if ( media_list == nullptr ) + return {}; + for( vlc_ml_media_t &media: ml_range_iterate( media_list ) ) + res.emplace_back( std::make_unique( &media ) ); + return res; +} diff --git a/modules/gui/qt/medialibrary/mlrecentsmodel.hpp b/modules/gui/qt/medialibrary/mlrecentsmodel.hpp index 1cd2e17abe..b58ebea042 100644 --- a/modules/gui/qt/medialibrary/mlrecentsmodel.hpp +++ b/modules/gui/qt/medialibrary/mlrecentsmodel.hpp @@ -75,9 +75,10 @@ public: void setNumberOfItemsToShow(int); int getNumberOfItemsToShow() const; +protected: + ListCacheLoader> *createLoader() const override; + private: - std::vector> fetch(const MLQueryParams ¶ms) const override; - size_t countTotalElements(const MLQueryParams ¶ms) const override; vlc_ml_sorting_criteria_t roleToCriteria( int /* role */ ) const override{ return VLC_ML_SORTING_DEFAULT; } @@ -85,6 +86,21 @@ private: return VLC_ML_SORTING_DEFAULT; } virtual void onVlcMlEvent( const MLEvent &event ) override; + + struct Loader : public BaseLoader + { + Loader(const MLRecentsModel &model, int numberOfItemsToShow) + : BaseLoader(model) + , m_numberOfItemsToShow(numberOfItemsToShow) + { + } + + size_t count() const override; + std::vector> load(size_t index, size_t count) const override; + + private: + int m_numberOfItemsToShow; + }; }; #endif // ML_RECENTS_MODEL_H diff --git a/modules/gui/qt/medialibrary/mlrecentsvideomodel.cpp b/modules/gui/qt/medialibrary/mlrecentsvideomodel.cpp index 643c351515..8324affa33 100644 --- a/modules/gui/qt/medialibrary/mlrecentsvideomodel.cpp +++ b/modules/gui/qt/medialibrary/mlrecentsvideomodel.cpp @@ -92,37 +92,6 @@ QHash MLRecentsVideoModel::roleNames() const }; } -std::vector > MLRecentsVideoModel::fetch(const MLQueryParams ¶ms) const -{ - auto queryParams = params.toCQueryParams(); - ml_unique_ptr media_list{ vlc_ml_list_history( - m_ml, &queryParams ) }; - if ( media_list == nullptr ) - return {}; - std::vector> res; - m_video_count = 0; - for( vlc_ml_media_t &media: ml_range_iterate( media_list ) ) - if( media.i_type == VLC_ML_MEDIA_TYPE_VIDEO ) - { - m_video_count++; - res.emplace_back( std::make_unique( m_ml, &media ) ); - } - return res; -} - -size_t MLRecentsVideoModel::countTotalElements(const MLQueryParams ¶ms) const -{ - // FIXME: countTotalElements() may not depend on fetch(), since the call to - // fetch() depends on countTotalElements() - - (void) params; - - if(numberOfItemsToShow == -1){ - return m_video_count; - } - return std::min(m_video_count,numberOfItemsToShow); -} - void MLRecentsVideoModel::onVlcMlEvent( const MLEvent &event ) { switch ( event.i_type ) @@ -139,7 +108,51 @@ void MLRecentsVideoModel::onVlcMlEvent( const MLEvent &event ) } void MLRecentsVideoModel::setNumberOfItemsToShow( int n ){ numberOfItemsToShow = n; + invalidateCache(); } int MLRecentsVideoModel::getNumberOfItemsToShow(){ return numberOfItemsToShow; } + +ListCacheLoader> * +MLRecentsVideoModel::createLoader() const +{ + return new Loader(*this, numberOfItemsToShow); +} + +size_t MLRecentsVideoModel::Loader::count() const +{ + MLQueryParams params = getParams(); + auto queryParams = params.toCQueryParams(); + + // FIXME: count() may not depend on load(), since the call to load() + // depends on count() + + (void) queryParams; + + if (m_numberOfItemsToShow == -1) { + return m_video_count; + } + return std::min(m_video_count, m_numberOfItemsToShow); +} + +std::vector> +MLRecentsVideoModel::Loader::load(size_t index, size_t count) const +{ + MLQueryParams params = getParams(index, count); + auto queryParams = params.toCQueryParams(); + + ml_unique_ptr media_list{ vlc_ml_list_history( + m_ml, &queryParams ) }; + if ( media_list == nullptr ) + return {}; + std::vector> res; + m_video_count = 0; + for( vlc_ml_media_t &media: ml_range_iterate( media_list ) ) + if( media.i_type == VLC_ML_MEDIA_TYPE_VIDEO ) + { + m_video_count++; + res.emplace_back( std::make_unique( m_ml, &media ) ); + } + return res; +} diff --git a/modules/gui/qt/medialibrary/mlrecentsvideomodel.hpp b/modules/gui/qt/medialibrary/mlrecentsvideomodel.hpp index 9a68459d42..64525ec0aa 100644 --- a/modules/gui/qt/medialibrary/mlrecentsvideomodel.hpp +++ b/modules/gui/qt/medialibrary/mlrecentsvideomodel.hpp @@ -44,9 +44,10 @@ public: QHash roleNames() const override; int numberOfItemsToShow = 10; +protected: + ListCacheLoader> *createLoader() const override; + private: - std::vector> fetch(const MLQueryParams ¶ms) const override; - size_t countTotalElements(const MLQueryParams ¶ms) const override; vlc_ml_sorting_criteria_t roleToCriteria( int /* role */ ) const override{ return VLC_ML_SORTING_DEFAULT; } @@ -56,7 +57,24 @@ private: virtual void onVlcMlEvent( const MLEvent &event ) override; void setNumberOfItemsToShow(int); int getNumberOfItemsToShow(); - mutable int m_video_count; + + struct Loader : public BaseLoader + { + Loader(const MLRecentsVideoModel &model, int numberOfItemsToShow) + : BaseLoader(model) + , m_numberOfItemsToShow(numberOfItemsToShow) + { + } + + size_t count() const override; + std::vector> load(size_t index, size_t count) const override; + + private: + int m_numberOfItemsToShow; + // FIXME: count() may not depend on load(), since the call to load() + // depends on count() + mutable int m_video_count; + }; }; #endif // ML_RECENTS_VIDEO_MODEL_H diff --git a/modules/gui/qt/medialibrary/mlurlmodel.cpp b/modules/gui/qt/medialibrary/mlurlmodel.cpp index eb2f219d4b..662842ffa6 100644 --- a/modules/gui/qt/medialibrary/mlurlmodel.cpp +++ b/modules/gui/qt/medialibrary/mlurlmodel.cpp @@ -72,30 +72,6 @@ void MLUrlModel::addAndPlay( const QString &url ) }); } -size_t MLUrlModel::countTotalElements(const MLQueryParams ¶ms) const -{ - auto queryParams = params.toCQueryParams(); - queryParams.i_offset = 0; - queryParams.i_nbResults = 0; - auto s = vlc_ml_count_stream_history( m_ml, &queryParams ); - return s; -} - -std::vector> MLUrlModel::fetch(const MLQueryParams ¶ms) const -{ - auto queryParams = params.toCQueryParams(); - - ml_unique_ptr media_list; - media_list.reset( vlc_ml_list_stream_history(m_ml, &queryParams) ); - if ( media_list == nullptr ) - return {}; - - std::vector> res; - for( const vlc_ml_media_t& media: ml_range_iterate( media_list ) ) - res.emplace_back( std::make_unique( &media ) ); - return res; -} - vlc_ml_sorting_criteria_t MLUrlModel::roleToCriteria(int role) const { switch (role) { @@ -149,3 +125,34 @@ QString MLUrl::getLastPlayedDate() const MLUrl *MLUrl::clone() const { return new MLUrl( *this ); } + +ListCacheLoader> * +MLUrlModel::createLoader() const +{ + return new Loader(*this); +} + +size_t MLUrlModel::Loader::count() const +{ + MLQueryParams params = getParams(); + auto queryParams = params.toCQueryParams(); + + return vlc_ml_count_stream_history( m_ml, &queryParams ); +} + +std::vector> +MLUrlModel::Loader::load(size_t index, size_t count) const +{ + MLQueryParams params = getParams(index, count); + auto queryParams = params.toCQueryParams(); + + ml_unique_ptr media_list; + media_list.reset( vlc_ml_list_stream_history(m_ml, &queryParams) ); + if ( media_list == nullptr ) + return {}; + + std::vector> res; + for( const vlc_ml_media_t& media: ml_range_iterate( media_list ) ) + res.emplace_back( std::make_unique( &media ) ); + return res; +} diff --git a/modules/gui/qt/medialibrary/mlurlmodel.hpp b/modules/gui/qt/medialibrary/mlurlmodel.hpp index 1828f15c89..b647d49234 100644 --- a/modules/gui/qt/medialibrary/mlurlmodel.hpp +++ b/modules/gui/qt/medialibrary/mlurlmodel.hpp @@ -69,11 +69,19 @@ public: Q_INVOKABLE void addAndPlay( const QString& url ); +protected: + ListCacheLoader> *createLoader() const override; + private: - std::vector> fetch(const MLQueryParams ¶ms) const override; - size_t countTotalElements(const MLQueryParams ¶ms) const override; vlc_ml_sorting_criteria_t roleToCriteria(int role) const override; virtual void onVlcMlEvent( const MLEvent &event ) override; + + struct Loader : public BaseLoader + { + Loader(const MLUrlModel &model) : BaseLoader(model) {} + size_t count() const override; + std::vector> load(size_t index, size_t count) const override; + }; }; #endif // MLURLMODEL_H diff --git a/modules/gui/qt/medialibrary/mlvideomodel.cpp b/modules/gui/qt/medialibrary/mlvideomodel.cpp index 1e861d2714..27e1414e4b 100644 --- a/modules/gui/qt/medialibrary/mlvideomodel.cpp +++ b/modules/gui/qt/medialibrary/mlvideomodel.cpp @@ -92,27 +92,6 @@ QHash MLVideoModel::roleNames() const }; } -std::vector > MLVideoModel::fetch(const MLQueryParams ¶ms) const -{ - auto queryParams = params.toCQueryParams(); - ml_unique_ptr media_list{ vlc_ml_list_video_media( - m_ml, &queryParams ) }; - if ( media_list == nullptr ) - return {}; - std::vector> res; - for( vlc_ml_media_t &media: ml_range_iterate( media_list ) ) - res.emplace_back( std::make_unique(m_ml, &media) ); - return res; -} - -size_t MLVideoModel::countTotalElements(const MLQueryParams ¶ms) const -{ - auto queryParams = params.toCQueryParams(); - queryParams.i_offset = 0; - queryParams.i_nbResults = 0; - return vlc_ml_count_video_media(m_ml, &queryParams); -} - vlc_ml_sorting_criteria_t MLVideoModel::roleToCriteria(int role) const { switch(role) @@ -157,3 +136,33 @@ void MLVideoModel::thumbnailUpdated(int idx) { emit dataChanged(index(idx), index(idx), {VIDEO_THUMBNAIL}); } + +ListCacheLoader> * +MLVideoModel::createLoader() const +{ + return new Loader(*this); +} + +size_t MLVideoModel::Loader::count() const +{ + MLQueryParams params = getParams(); + auto queryParams = params.toCQueryParams(); + + return vlc_ml_count_video_media(m_ml, &queryParams); +} + +std::vector> +MLVideoModel::Loader::load(size_t index, size_t count) const +{ + MLQueryParams params = getParams(index, count); + auto queryParams = params.toCQueryParams(); + + ml_unique_ptr media_list{ vlc_ml_list_video_media( + m_ml, &queryParams ) }; + if ( media_list == nullptr ) + return {}; + std::vector> res; + for( vlc_ml_media_t &media: ml_range_iterate( media_list ) ) + res.emplace_back( std::make_unique(m_ml, &media) ); + return res; +} diff --git a/modules/gui/qt/medialibrary/mlvideomodel.hpp b/modules/gui/qt/medialibrary/mlvideomodel.hpp index 2d60df10b6..2f3fda89fa 100644 --- a/modules/gui/qt/medialibrary/mlvideomodel.hpp +++ b/modules/gui/qt/medialibrary/mlvideomodel.hpp @@ -62,9 +62,10 @@ public: QVariant data(const QModelIndex& index, int role) const override; QHash roleNames() const override; +protected: + ListCacheLoader> *createLoader() const override; + private: - std::vector> fetch(const MLQueryParams ¶ms) const override; - size_t countTotalElements(const MLQueryParams ¶ms) const override; vlc_ml_sorting_criteria_t roleToCriteria(int role) const override; vlc_ml_sorting_criteria_t nameToCriteria(QByteArray name) const override; virtual void onVlcMlEvent( const MLEvent &event ) override; @@ -72,6 +73,13 @@ private: static QHash M_names_to_criteria; QByteArray criteriaToName(vlc_ml_sorting_criteria_t criteria) const override; + + struct Loader : public BaseLoader + { + Loader(const MLVideoModel &model) : BaseLoader(model) {} + size_t count() const override; + std::vector> load(size_t index, size_t count) const override; + }; }; #endif // MCVIDEOMODEL_H -- 2.11.4.GIT