AlbumCoverManager: Queue album cover loading using timer
Helps reduce memory growth.
This commit is contained in:
parent
155485173b
commit
de62552ad1
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
@ -93,6 +94,8 @@
|
||||||
|
|
||||||
#include "ui_albumcovermanager.h"
|
#include "ui_albumcovermanager.h"
|
||||||
|
|
||||||
|
using namespace std::literals::chrono_literals;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
constexpr char kSettingsGroup[] = "CoverManager";
|
constexpr char kSettingsGroup[] = "CoverManager";
|
||||||
constexpr int kThumbnailSize = 120;
|
constexpr int kThumbnailSize = 120;
|
||||||
|
@ -105,6 +108,7 @@ AlbumCoverManager::AlbumCoverManager(Application *app, SharedPtr<CollectionBacke
|
||||||
app_(app),
|
app_(app),
|
||||||
collection_backend_(collection_backend),
|
collection_backend_(collection_backend),
|
||||||
album_cover_choice_controller_(new AlbumCoverChoiceController(this)),
|
album_cover_choice_controller_(new AlbumCoverChoiceController(this)),
|
||||||
|
timer_album_cover_load_(new QTimer(this)),
|
||||||
filter_all_(nullptr),
|
filter_all_(nullptr),
|
||||||
filter_with_covers_(nullptr),
|
filter_with_covers_(nullptr),
|
||||||
filter_without_covers_(nullptr),
|
filter_without_covers_(nullptr),
|
||||||
|
@ -125,6 +129,10 @@ AlbumCoverManager::AlbumCoverManager(Application *app, SharedPtr<CollectionBacke
|
||||||
ui_->setupUi(this);
|
ui_->setupUi(this);
|
||||||
ui_->albums->set_cover_manager(this);
|
ui_->albums->set_cover_manager(this);
|
||||||
|
|
||||||
|
timer_album_cover_load_->setSingleShot(false);
|
||||||
|
timer_album_cover_load_->setInterval(10ms);
|
||||||
|
QObject::connect(timer_album_cover_load_, &QTimer::timeout, this, &AlbumCoverManager::LoadAlbumCovers);
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
ui_->action_fetch->setIcon(IconLoader::Load(QStringLiteral("download")));
|
ui_->action_fetch->setIcon(IconLoader::Load(QStringLiteral("download")));
|
||||||
ui_->export_covers->setIcon(IconLoader::Load(QStringLiteral("document-save")));
|
ui_->export_covers->setIcon(IconLoader::Load(QStringLiteral("document-save")));
|
||||||
|
@ -316,6 +324,7 @@ void AlbumCoverManager::CancelRequests() {
|
||||||
#else
|
#else
|
||||||
app_->album_cover_loader()->CancelTasks(QSet<quint64>::fromList(cover_loading_tasks_.keys()));
|
app_->album_cover_loader()->CancelTasks(QSet<quint64>::fromList(cover_loading_tasks_.keys()));
|
||||||
#endif
|
#endif
|
||||||
|
cover_loading_pending_.clear();
|
||||||
cover_loading_tasks_.clear();
|
cover_loading_tasks_.clear();
|
||||||
cover_save_tasks_.clear();
|
cover_save_tasks_.clear();
|
||||||
|
|
||||||
|
@ -346,7 +355,7 @@ void AlbumCoverManager::Reset() {
|
||||||
all_artists_ = new QListWidgetItem(all_artists_icon_, tr("All artists"), ui_->artists, All_Artists);
|
all_artists_ = new QListWidgetItem(all_artists_icon_, tr("All artists"), ui_->artists, All_Artists);
|
||||||
new AlbumItem(artist_icon_, tr("Various artists"), ui_->artists, Various_Artists);
|
new AlbumItem(artist_icon_, tr("Various artists"), ui_->artists, Various_Artists);
|
||||||
|
|
||||||
QStringList artists(collection_backend_->GetAllArtistsWithAlbums());
|
QStringList artists = collection_backend_->GetAllArtistsWithAlbums();
|
||||||
std::stable_sort(artists.begin(), artists.end(), CompareNocase);
|
std::stable_sort(artists.begin(), artists.end(), CompareNocase);
|
||||||
|
|
||||||
for (const QString &artist : std::as_const(artists)) {
|
for (const QString &artist : std::as_const(artists)) {
|
||||||
|
@ -422,7 +431,7 @@ void AlbumCoverManager::ArtistChanged(QListWidgetItem *current) {
|
||||||
album_item->setData(Role_ArtUnset, album_info.art_unset);
|
album_item->setData(Role_ArtUnset, album_info.art_unset);
|
||||||
|
|
||||||
if (album_info.art_embedded || !album_info.art_automatic.isEmpty() || !album_info.art_manual.isEmpty()) {
|
if (album_info.art_embedded || !album_info.art_automatic.isEmpty() || !album_info.art_manual.isEmpty()) {
|
||||||
LoadAlbumCoverAsync(album_item);
|
QueueAlbumCoverLoad(album_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -431,6 +440,40 @@ void AlbumCoverManager::ArtistChanged(QListWidgetItem *current) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AlbumCoverManager::QueueAlbumCoverLoad(AlbumItem *album_item) {
|
||||||
|
|
||||||
|
cover_loading_pending_.enqueue(album_item);
|
||||||
|
|
||||||
|
if (!timer_album_cover_load_->isActive()) {
|
||||||
|
timer_album_cover_load_->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlbumCoverManager::LoadAlbumCovers() {
|
||||||
|
|
||||||
|
if (cover_loading_pending_.isEmpty()) {
|
||||||
|
if (timer_album_cover_load_->isActive()) {
|
||||||
|
timer_album_cover_load_->stop();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadAlbumCoverAsync(cover_loading_pending_.dequeue());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlbumCoverManager::LoadAlbumCoverAsync(AlbumItem *album_item) {
|
||||||
|
|
||||||
|
AlbumCoverLoaderOptions cover_options(AlbumCoverLoaderOptions::Option::ScaledImage | AlbumCoverLoaderOptions::Option::PadScaledImage);
|
||||||
|
cover_options.types = cover_types_;
|
||||||
|
cover_options.desired_scaled_size = QSize(kThumbnailSize, kThumbnailSize);
|
||||||
|
cover_options.device_pixel_ratio = devicePixelRatioF();
|
||||||
|
quint64 cover_load_id = app_->album_cover_loader()->LoadImageAsync(cover_options, album_item->data(Role_ArtEmbedded).toBool(), album_item->data(Role_ArtAutomatic).toUrl(), album_item->data(Role_ArtManual).toUrl(), album_item->data(Role_ArtUnset).toBool(), album_item->urls.constFirst());
|
||||||
|
cover_loading_tasks_.insert(cover_load_id, album_item);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void AlbumCoverManager::AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderResult &result) {
|
void AlbumCoverManager::AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderResult &result) {
|
||||||
|
|
||||||
if (!cover_loading_tasks_.contains(id)) return;
|
if (!cover_loading_tasks_.contains(id)) return;
|
||||||
|
@ -1076,13 +1119,3 @@ void AlbumCoverManager::SaveEmbeddedCoverFinished(TagReaderReply *reply, AlbumIt
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AlbumCoverManager::LoadAlbumCoverAsync(AlbumItem *album_item) {
|
|
||||||
|
|
||||||
AlbumCoverLoaderOptions cover_options(AlbumCoverLoaderOptions::Option::ScaledImage | AlbumCoverLoaderOptions::Option::PadScaledImage);
|
|
||||||
cover_options.types = cover_types_;
|
|
||||||
cover_options.desired_scaled_size = QSize(kThumbnailSize, kThumbnailSize);
|
|
||||||
cover_options.device_pixel_ratio = devicePixelRatioF();
|
|
||||||
quint64 cover_load_id = app_->album_cover_loader()->LoadImageAsync(cover_options, album_item->data(Role_ArtEmbedded).toBool(), album_item->data(Role_ArtAutomatic).toUrl(), album_item->data(Role_ArtManual).toUrl(), album_item->data(Role_ArtUnset).toBool(), album_item->urls.constFirst());
|
|
||||||
cover_loading_tasks_.insert(cover_load_id, album_item);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <QListWidgetItem>
|
#include <QListWidgetItem>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QMultiMap>
|
#include <QMultiMap>
|
||||||
|
#include <QQueue>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
@ -44,7 +45,7 @@
|
||||||
#include "albumcoverchoicecontroller.h"
|
#include "albumcoverchoicecontroller.h"
|
||||||
#include "coversearchstatistics.h"
|
#include "coversearchstatistics.h"
|
||||||
|
|
||||||
class QWidget;
|
class QTimer;
|
||||||
class QMimeData;
|
class QMimeData;
|
||||||
class QMenu;
|
class QMenu;
|
||||||
class QAction;
|
class QAction;
|
||||||
|
@ -136,6 +137,9 @@ class AlbumCoverManager : public QMainWindow {
|
||||||
Song AlbumItemAsSong(QListWidgetItem *list_widget_item) { return AlbumItemAsSong(static_cast<AlbumItem*>(list_widget_item)); }
|
Song AlbumItemAsSong(QListWidgetItem *list_widget_item) { return AlbumItemAsSong(static_cast<AlbumItem*>(list_widget_item)); }
|
||||||
static Song AlbumItemAsSong(AlbumItem *album_item);
|
static Song AlbumItemAsSong(AlbumItem *album_item);
|
||||||
|
|
||||||
|
void QueueAlbumCoverLoad(AlbumItem *album_item);
|
||||||
|
void LoadAlbumCoverAsync(AlbumItem *album_item);
|
||||||
|
|
||||||
void UpdateStatusText();
|
void UpdateStatusText();
|
||||||
bool ShouldHide(const AlbumItem &album_item, const QString &filter, const HideCovers hide_covers) const;
|
bool ShouldHide(const AlbumItem &album_item, const QString &filter, const HideCovers hide_covers) const;
|
||||||
void SaveAndSetCover(AlbumItem *album_item, const AlbumCoverImageResult &result);
|
void SaveAndSetCover(AlbumItem *album_item, const AlbumCoverImageResult &result);
|
||||||
|
@ -147,14 +151,13 @@ class AlbumCoverManager : public QMainWindow {
|
||||||
|
|
||||||
bool ItemHasCover(const AlbumItem &album_item) const;
|
bool ItemHasCover(const AlbumItem &album_item) const;
|
||||||
|
|
||||||
void LoadAlbumCoverAsync(AlbumItem *album_item);
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void Error(const QString &error);
|
void Error(const QString &error);
|
||||||
void AddToPlaylist(QMimeData *data);
|
void AddToPlaylist(QMimeData *data);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void ArtistChanged(QListWidgetItem *current);
|
void ArtistChanged(QListWidgetItem *current);
|
||||||
|
void LoadAlbumCovers();
|
||||||
void AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderResult &result);
|
void AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderResult &result);
|
||||||
void UpdateFilter();
|
void UpdateFilter();
|
||||||
void FetchAlbumCovers();
|
void FetchAlbumCovers();
|
||||||
|
@ -190,11 +193,13 @@ class AlbumCoverManager : public QMainWindow {
|
||||||
Application *app_;
|
Application *app_;
|
||||||
SharedPtr<CollectionBackend> collection_backend_;
|
SharedPtr<CollectionBackend> collection_backend_;
|
||||||
AlbumCoverChoiceController *album_cover_choice_controller_;
|
AlbumCoverChoiceController *album_cover_choice_controller_;
|
||||||
|
QTimer *timer_album_cover_load_;
|
||||||
|
|
||||||
QAction *filter_all_;
|
QAction *filter_all_;
|
||||||
QAction *filter_with_covers_;
|
QAction *filter_with_covers_;
|
||||||
QAction *filter_without_covers_;
|
QAction *filter_without_covers_;
|
||||||
|
|
||||||
|
QQueue<AlbumItem*> cover_loading_pending_;
|
||||||
QMap<quint64, AlbumItem*> cover_loading_tasks_;
|
QMap<quint64, AlbumItem*> cover_loading_tasks_;
|
||||||
|
|
||||||
AlbumCoverFetcher *cover_fetcher_;
|
AlbumCoverFetcher *cover_fetcher_;
|
||||||
|
|
Loading…
Reference in New Issue