comparison src/gui/pages/seasons.cc @ 325:78929794e7d8

pages/seasons: run seasons search in a separate thread
author Paper <paper@paper.us.eu.org>
date Thu, 13 Jun 2024 00:36:41 -0400
parents 2115488eb302
children 10096c5489e3
comparison
equal deleted inserted replaced
324:5d3c9b31aa6e 325:78929794e7d8
14 #include <QMenu> 14 #include <QMenu>
15 #include <QToolBar> 15 #include <QToolBar>
16 #include <QToolButton> 16 #include <QToolButton>
17 #include <QVBoxLayout> 17 #include <QVBoxLayout>
18 18
19 SeasonsPageSearchThread::SeasonsPageSearchThread(QObject* parent) : QThread(parent) {
20 }
21
22 void SeasonsPageSearchThread::AddToQueue(Anime::SeriesSeason season, Date::Year year) {
23 queue_mutex_.lock();
24 queue_.push({season, year});
25 queue_mutex_.unlock();
26 }
27
28 void SeasonsPageSearchThread::run() {
29 queue_mutex_.lock();
30
31 while (!queue_.empty() && !isInterruptionRequested()) {
32 Season season = queue_.front();
33
34 /* unlock the mutex for a long blocking operation, so items
35 * can be added without worry */
36 queue_mutex_.unlock();
37
38 if (Services::GetSeason(season.season, season.year))
39 emit ReceivedSeason(season.season, season.year);
40
41 queue_mutex_.lock();
42
43 queue_.pop();
44 }
45
46 queue_mutex_.unlock();
47 }
48
49 static SeasonsPageSearchThread search_thread_;
50
51 /* ------------------------------------------------------------------------------------- */
52
19 static constexpr Date::Year GetClosestDecade(Date::Year year) { 53 static constexpr Date::Year GetClosestDecade(Date::Year year) {
20 return year - (year % 10); 54 return year - (year % 10);
21 } 55 }
22 56
23 void SeasonsPage::SetSeason(Anime::SeriesSeason season, Date::Year year) { 57 void SeasonsPage::Refresh() {
58 setUpdatesEnabled(false);
59
24 if (!buttons || !season_button) 60 if (!buttons || !season_button)
25 return; 61 return;
26 62
27 buttons->clear(); 63 buttons->clear();
28 64
29 for (const auto& id : Anime::Season::GetAllAnimeForSeason(season, year)) { 65 for (const auto& id : Anime::Season::GetAllAnimeForSeason(season_, year_)) {
30 QListWidgetItem* item = new QListWidgetItem; 66 QListWidgetItem* item = new QListWidgetItem;
31 AnimeButton* button = new AnimeButton(this); 67 AnimeButton* button = new AnimeButton(this);
32 button->SetAnime(Anime::db.items[id]); 68 button->SetAnime(Anime::db.items[id]);
33 item->setSizeHint(button->sizeHint()); 69 item->setSizeHint(button->sizeHint());
34 buttons->addItem(item); 70 buttons->addItem(item);
35 buttons->setItemWidget(item, button); 71 buttons->setItemWidget(item, button);
36 } 72 }
37 73
38 season_button->setText(Strings::ToQString(Translate::ToLocalString(season)) + " " + QString::number(year)); 74 season_button->setText(Strings::ToQString(Translate::ToLocalString(season_)) + " " + QString::number(year_));
75
76 setUpdatesEnabled(true);
77 }
78
79 void SeasonsPage::SetSeason(Anime::SeriesSeason season, Date::Year year) {
80 season_ = season;
81 year_ = year;
82
83 Refresh();
39 } 84 }
40 85
41 SeasonsPage::SeasonsPage(QWidget* parent) : QFrame(parent) { 86 SeasonsPage::SeasonsPage(QWidget* parent) : QFrame(parent) {
42 setBackgroundRole(QPalette::Base); 87 setBackgroundRole(QPalette::Base);
43 setFrameShape(QFrame::Box); 88 setFrameShape(QFrame::Box);
51 toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); 96 toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
52 toolbar->setIconSize(QSize(16, 16)); 97 toolbar->setIconSize(QSize(16, 16));
53 toolbar->setMovable(false); 98 toolbar->setMovable(false);
54 99
55 { 100 {
56 /* todo: clean this up... this sucks... */
57 static constexpr Date::Year last_year = 1960; 101 static constexpr Date::Year last_year = 1960;
58 102
59 auto create_year_menu = [this](QWidget* parent, QMenu* parent_menu, Date::Year year){ 103 auto create_year_menu = [this](QWidget* parent, QMenu* parent_menu, Date::Year year){
60 const QString year_s = QString::number(year); 104 const QString year_s = QString::number(year);
61 105
62 QMenu* menu = new QMenu(year_s, parent); 106 QMenu* menu = new QMenu(year_s, parent);
63 for (const auto& season : Anime::SeriesSeasons) { 107 for (const auto& season : Anime::SeriesSeasons) {
64 QAction* action = menu->addAction(Strings::ToQString(Translate::ToLocalString(season)) + " " + year_s); 108 QAction* action = menu->addAction(Strings::ToQString(Translate::ToLocalString(season)) + " " + year_s);
65 connect(action, &QAction::triggered, this, [this, season, year]{ 109 connect(action, &QAction::triggered, this, [this, season, year] {
66 SetSeason(season, year); 110 SetSeason(season, year);
67 }); 111 });
68 } 112 }
69 parent_menu->addMenu(menu); 113 parent_menu->addMenu(menu);
70 }; 114 };
98 142
99 toolbar->addSeparator(); 143 toolbar->addSeparator();
100 144
101 { 145 {
102 toolbar->addAction(QIcon(":/icons/16x16/arrow-circle-315.png"), tr("Refresh data"), [this]{ 146 toolbar->addAction(QIcon(":/icons/16x16/arrow-circle-315.png"), tr("Refresh data"), [this]{
103 Services::GetSeason(Anime::SeriesSeason::Summer, 2011U); 147 search_thread_.AddToQueue(season_, year_);
104 SetSeason(Anime::SeriesSeason::Summer, 2011U); 148 if (!search_thread_.isRunning())
149 search_thread_.start();
105 }); 150 });
106 } 151 }
107 152
108 toolbar->addSeparator(); 153 toolbar->addSeparator();
109 154
188 } 233 }
189 234
190 full_layout->setContentsMargins(0, 0, 0, 0); 235 full_layout->setContentsMargins(0, 0, 0, 0);
191 full_layout->setSpacing(0); 236 full_layout->setSpacing(0);
192 237
238 connect(&search_thread_, &SeasonsPageSearchThread::ReceivedSeason, this, [this](Anime::SeriesSeason season, Date::Year year) {
239 if (season == season_ && year == year_)
240 Refresh();
241 });
242
193 /* Do NOT move this up in this function, buttons HAS to be initialized */ 243 /* Do NOT move this up in this function, buttons HAS to be initialized */
194 SetSeason(Anime::SeriesSeason::Summer, 2011U); 244 SetSeason(Anime::SeriesSeason::Summer, 2011U);
195 } 245 }