Mercurial > minori
diff src/gui/pages/anime_list.cc @ 273:f31305b9f60a
*: various code safety changes
this also makes the code build on Qt 5.7. I can't test it though
because I don't have it working... FAIL!
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Thu, 18 Apr 2024 16:53:17 -0400 |
parents | 862d0d8619f6 |
children | f6a756c19bfb |
line wrap: on
line diff
--- a/src/gui/pages/anime_list.cc Thu Apr 18 16:51:35 2024 -0400 +++ b/src/gui/pages/anime_list.cc Thu Apr 18 16:53:17 2024 -0400 @@ -27,11 +27,32 @@ #include <QShortcut> #include <QStylePainter> #include <QStyledItemDelegate> -#include <QThread> +#include <QThreadPool> +#include <QRunnable> #include <QTreeView> #include <set> +AnimeListPageUpdateEntryThread::AnimeListPageUpdateEntryThread(AnimeListPage* parent) : QThread(parent) { + page_ = parent; +} + +void AnimeListPageUpdateEntryThread::AddToQueue(int id) { + if (isRunning()) + return; /* don't let us fuck ourselves */ + + queue_.push(id); +} + +/* processes the queue... */ +void AnimeListPageUpdateEntryThread::run() { + while (!queue_.empty() && !isInterruptionRequested()) { + Services::UpdateAnimeEntry(queue_.front()); + queue_.pop(); + } + page_->Refresh(); +} + AnimeListPageSortFilter::AnimeListPageSortFilter(QObject* parent) : QSortFilterProxyModel(parent) { } @@ -111,7 +132,7 @@ case AL_TITLE: return Strings::ToQString(list[index.row()].GetUserPreferredTitle()); case AL_PROGRESS: return QString::number(list[index.row()].GetUserProgress()) + "/" + - QString::number(list[index.row()].GetEpisodes()); + QString::number(list[index.row()].GetEpisodes()); case AL_EPISODES: return list[index.row()].GetEpisodes(); case AL_SCORE: return Strings::ToQString(list[index.row()].GetUserPresentableScore()); case AL_TYPE: return Strings::ToQString(Translate::ToString(list[index.row()].GetFormat())); @@ -120,7 +141,7 @@ if (!year) return "Unknown Unknown"; return Strings::ToQString(Translate::ToLocalString(list[index.row()].GetSeason()) + " " + - Strings::ToUtf8String(year.value())); + Strings::ToUtf8String(year.value())); } case AL_AVG_SCORE: return QString::number(list[index.row()].GetAudienceScore()) + "%"; case AL_STARTED: return list[index.row()].GetUserDateStarted().GetAsQDate(); @@ -219,12 +240,14 @@ } void AnimeListPage::UpdateAnime(int id) { - QThread* thread = QThread::create([this, id] { Services::UpdateAnimeEntry(id); }); + /* this ought to just add to the thread's buffer. */ + if (update_entry_thread_.isRunning()) { + update_entry_thread_.requestInterruption(); + update_entry_thread_.wait(); + } - connect(thread, &QThread::finished, this, &AnimeListPage::Refresh); - connect(thread, &QThread::finished, thread, &QThread::deleteLater); - - thread->start(); + update_entry_thread_.AddToQueue(id); + update_entry_thread_.start(); } void AnimeListPage::RemoveAnime(int id) { @@ -243,7 +266,7 @@ if (i == AnimeListPageModel::AL_TITLE) continue; const auto column_name = - sort_models[tab_bar->currentIndex()]->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); + sort_models[tab_bar->currentIndex()]->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); QAction* action = menu->addAction(column_name, this, [this, i](const bool checked) { if (!checked && (VisibleColumnsCount() <= 1)) @@ -277,9 +300,9 @@ menu->setToolTipsVisible(true); AnimeListPageModel* source_model = - reinterpret_cast<AnimeListPageModel*>(sort_models[tab_bar->currentIndex()]->sourceModel()); + reinterpret_cast<AnimeListPageModel*>(sort_models[tab_bar->currentIndex()]->sourceModel()); const QItemSelection selection = - sort_models[tab_bar->currentIndex()]->mapSelectionToSource(tree_view->selectionModel()->selection()); + sort_models[tab_bar->currentIndex()]->mapSelectionToSource(tree_view->selectionModel()->selection()); std::set<Anime::Anime*> animes; for (const auto& index : selection.indexes()) { @@ -293,7 +316,7 @@ menu->addAction(tr("Information"), [this, animes] { for (auto& anime : animes) { InformationDialog* dialog = new InformationDialog( - *anime, [this, anime] { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MAIN_INFO, this); + *anime, [this, anime] { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MAIN_INFO, this); dialog->show(); dialog->raise(); @@ -304,7 +327,7 @@ menu->addAction(tr("Edit"), [this, animes] { for (auto& anime : animes) { InformationDialog* dialog = new InformationDialog( - *anime, [this, anime] { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MY_LIST, this); + *anime, [this, anime] { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MY_LIST, this); dialog->show(); dialog->raise(); @@ -322,19 +345,19 @@ void AnimeListPage::ItemDoubleClicked() { /* throw out any other garbage */ const QItemSelection selection = - sort_models[tab_bar->currentIndex()]->mapSelectionToSource(tree_view->selectionModel()->selection()); + sort_models[tab_bar->currentIndex()]->mapSelectionToSource(tree_view->selectionModel()->selection()); if (!selection.indexes().first().isValid()) { return; } AnimeListPageModel* source_model = - reinterpret_cast<AnimeListPageModel*>(sort_models[tab_bar->currentIndex()]->sourceModel()); + reinterpret_cast<AnimeListPageModel*>(sort_models[tab_bar->currentIndex()]->sourceModel()); const QModelIndex index = source_model->index(selection.indexes().first().row()); Anime::Anime* anime = source_model->GetAnimeFromIndex(index); InformationDialog* dialog = new InformationDialog( - *anime, [this, anime] { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MAIN_INFO, this); + *anime, [this, anime] { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MAIN_INFO, this); dialog->show(); dialog->raise(); @@ -349,7 +372,7 @@ void AnimeListPage::RefreshTabs() { for (unsigned int i = 0; i < sort_models.size(); i++) tab_bar->setTabText(i, Strings::ToQString(Translate::ToString(Anime::ListStatuses[i])) + " (" + - QString::number(Anime::db.GetListsAnimeAmount(Anime::ListStatuses[i])) + ")"); + QString::number(Anime::db.GetListsAnimeAmount(Anime::ListStatuses[i])) + ")"); } void AnimeListPage::Refresh() { @@ -424,7 +447,7 @@ /* --------- QTabWidget replication end ---------- */ -AnimeListPage::AnimeListPage(QWidget* parent) : QWidget(parent) { +AnimeListPage::AnimeListPage(QWidget* parent) : QWidget(parent), update_entry_thread_(this) { /* Tab bar */ tab_bar = new QTabBar(this); tab_bar->setExpanding(false); @@ -445,7 +468,7 @@ for (unsigned int i = 0; i < sort_models.size(); i++) { tab_bar->addTab(Strings::ToQString(Translate::ToString(Anime::ListStatuses[i])) + " (" + - QString::number(Anime::db.GetListsAnimeAmount(Anime::ListStatuses[i])) + ")"); + QString::number(Anime::db.GetListsAnimeAmount(Anime::ListStatuses[i])) + ")"); sort_models[i] = new AnimeListPageSortFilter(tree_view); sort_models[i]->setSourceModel(new AnimeListPageModel(this, Anime::ListStatuses[i])); sort_models[i]->setSortRole(Qt::UserRole); @@ -476,10 +499,10 @@ /* Enter & return keys */ connect(new QShortcut(Qt::Key_Return, tree_view, nullptr, nullptr, Qt::WidgetShortcut), &QShortcut::activated, this, - &AnimeListPage::ItemDoubleClicked); + &AnimeListPage::ItemDoubleClicked); connect(new QShortcut(Qt::Key_Enter, tree_view, nullptr, nullptr, Qt::WidgetShortcut), &QShortcut::activated, this, - &AnimeListPage::ItemDoubleClicked); + &AnimeListPage::ItemDoubleClicked); tree_view->header()->setStretchLastSection(false); tree_view->header()->setContextMenuPolicy(Qt::CustomContextMenu);