From a360836fef94041f8584e039b1783b5accf08bbf Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sun, 11 Aug 2019 14:36:40 +0200 Subject: [PATCH] Qt: don't update the gui from QtConcurrent --- rpcs3/rpcs3qt/save_manager_dialog.cpp | 49 ++++++++++----- rpcs3/rpcs3qt/save_manager_dialog.h | 2 +- rpcs3/rpcs3qt/trophy_manager_dialog.cpp | 81 +++++++++++++++---------- rpcs3/rpcs3qt/trophy_manager_dialog.h | 2 +- 4 files changed, 85 insertions(+), 49 deletions(-) diff --git a/rpcs3/rpcs3qt/save_manager_dialog.cpp b/rpcs3/rpcs3qt/save_manager_dialog.cpp index cb70ff6799..ed4e1b733b 100644 --- a/rpcs3/rpcs3qt/save_manager_dialog.cpp +++ b/rpcs3/rpcs3qt/save_manager_dialog.cpp @@ -248,7 +248,7 @@ void save_manager_dialog::UpdateList() for (size_t i = 0; i < m_save_entries.size(); ++i) indices.append(static_cast(i)); - QtConcurrent::blockingMap(indices, [this, currNotes](int& row) + std::function get_icon = [this](const int& row) { const auto& entry = m_save_entries[row]; QPixmap icon = QPixmap(320, 176); @@ -258,27 +258,35 @@ void save_manager_dialog::UpdateList() icon = QPixmap(320, 176); icon.fill(m_icon_color); } + return icon; + }; + + QList icons = QtConcurrent::blockingMapped>(indices, get_icon); + + for (int i = 0; i < icons.count(); ++i) + { + const auto& entry = m_save_entries[i]; QString title = qstr(entry.title) + QStringLiteral("\n") + qstr(entry.subtitle); QString dirName = qstr(entry.dirName); custom_table_widget_item* iconItem = new custom_table_widget_item; - iconItem->setData(Qt::UserRole, icon); + iconItem->setData(Qt::UserRole, icons[i]); iconItem->setFlags(iconItem->flags() & ~Qt::ItemIsEditable); - m_list->setItem(row, 0, iconItem); + m_list->setItem(i, 0, iconItem); QTableWidgetItem* titleItem = new QTableWidgetItem(title); - titleItem->setData(Qt::UserRole, row); // For sorting to work properly + titleItem->setData(Qt::UserRole, i); // For sorting to work properly titleItem->setFlags(titleItem->flags() & ~Qt::ItemIsEditable); - m_list->setItem(row, 1, titleItem); + m_list->setItem(i, 1, titleItem); QTableWidgetItem* timeItem = new QTableWidgetItem(FormatTimestamp(entry.mtime)); timeItem->setFlags(timeItem->flags() & ~Qt::ItemIsEditable); - m_list->setItem(row, 2, timeItem); + m_list->setItem(i, 2, timeItem); QTableWidgetItem* dirNameItem = new QTableWidgetItem(dirName); dirNameItem->setFlags(dirNameItem->flags() & ~Qt::ItemIsEditable); - m_list->setItem(row, 3, dirNameItem); + m_list->setItem(i, 3, dirNameItem); QTableWidgetItem* noteItem = new QTableWidgetItem(); noteItem->setFlags(noteItem->flags() | Qt::ItemIsEditable); @@ -286,10 +294,10 @@ void save_manager_dialog::UpdateList() { noteItem->setText(currNotes[dirName].toString()); } - m_list->setItem(row, 4, noteItem); + m_list->setItem(i, 4, noteItem); + } - UpdateIcon(row); - }); + UpdateIcons(); m_list->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); m_list->verticalHeader()->resizeSections(QHeaderView::ResizeToContents); @@ -316,7 +324,7 @@ void save_manager_dialog::HandleRepaintUiRequest() resize(window_size); } -void save_manager_dialog::UpdateIcon(int i) +QPixmap save_manager_dialog::GetResizedIcon(int i) { const int dpr = devicePixelRatio(); const int width = m_icon_size.width() * dpr; @@ -325,7 +333,7 @@ void save_manager_dialog::UpdateIcon(int i) QTableWidgetItem* item = m_list->item(i, 0); if (!item) { - return; + return QPixmap(); } QPixmap data = item->data(Qt::UserRole).value(); @@ -335,7 +343,7 @@ void save_manager_dialog::UpdateIcon(int i) QPainter painter(&icon); painter.drawPixmap(0, 0, data); - item->setData(Qt::DecorationRole, icon.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation)); + return icon.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation); } void save_manager_dialog::UpdateIcons() @@ -344,10 +352,19 @@ void save_manager_dialog::UpdateIcons() for (int i = 0; i < m_list->rowCount(); ++i) indices.append(i); - QtConcurrent::blockingMap(indices, [this](int& i) + std::function get_scaled = [this](const int& i) { - UpdateIcon(i); - }); + return GetResizedIcon(i); + }; + + QList scaled = QtConcurrent::blockingMapped>(indices, get_scaled); + + for (int i = 0; i < m_list->rowCount() && i < scaled.count(); ++i) + { + QTableWidgetItem* icon_item = m_list->item(i, 0); + if (icon_item) + icon_item->setData(Qt::DecorationRole, scaled[i]); + } m_list->resizeRowsToContents(); m_list->resizeColumnToContents(0); diff --git a/rpcs3/rpcs3qt/save_manager_dialog.h b/rpcs3/rpcs3qt/save_manager_dialog.h index 5987ec3f29..2100233bc1 100644 --- a/rpcs3/rpcs3qt/save_manager_dialog.h +++ b/rpcs3/rpcs3qt/save_manager_dialog.h @@ -32,7 +32,7 @@ private Q_SLOTS: private: void Init(std::string dir); void UpdateList(); - void UpdateIcon(int i); + QPixmap GetResizedIcon(int i); void UpdateIcons(); void ShowContextMenu(const QPoint &pos); diff --git a/rpcs3/rpcs3qt/trophy_manager_dialog.cpp b/rpcs3/rpcs3qt/trophy_manager_dialog.cpp index c48bb9c797..06de2d0d72 100644 --- a/rpcs3/rpcs3qt/trophy_manager_dialog.cpp +++ b/rpcs3/rpcs3qt/trophy_manager_dialog.cpp @@ -478,12 +478,12 @@ void trophy_manager_dialog::HandleRepaintUiRequest() resize(window_size); } -void trophy_manager_dialog::ResizeGameIcon(int index) +QPixmap trophy_manager_dialog::GetResizedGameIcon(int index) { QTableWidgetItem* item = m_game_table->item(index, GameColumns::GameIcon); if (!item) { - return; + return QPixmap(); } const QPixmap icon = item->data(Qt::UserRole).value(); const int dpr = devicePixelRatio(); @@ -499,8 +499,7 @@ void trophy_manager_dialog::ResizeGameIcon(int index) painter.end(); } - const QPixmap scaled_icon = new_icon.scaled(m_game_icon_size * dpr, Qt::KeepAspectRatio, Qt::TransformationMode::SmoothTransformation); - item->setData(Qt::DecorationRole, scaled_icon); + return new_icon.scaled(m_game_icon_size * dpr, Qt::KeepAspectRatio, Qt::TransformationMode::SmoothTransformation); } void trophy_manager_dialog::ResizeGameIcons() @@ -512,10 +511,19 @@ void trophy_manager_dialog::ResizeGameIcons() for (int i = 0; i < m_game_table->rowCount(); ++i) indices.append(i); - QtConcurrent::blockingMap(indices, [this](int& i) + std::function get_scaled = [this](const int& i) { - ResizeGameIcon(i); - }); + return GetResizedGameIcon(i); + }; + + QList scaled = QtConcurrent::blockingMapped>(indices, get_scaled); + + for (int i = 0; i < m_game_table->rowCount() && i < scaled.count(); ++i) + { + QTableWidgetItem* icon_item = m_game_table->item(i, TrophyColumns::Icon); + if (icon_item) + icon_item->setData(Qt::DecorationRole, scaled[i]); + } ReadjustGameTable(); } @@ -533,13 +541,13 @@ void trophy_manager_dialog::ResizeTrophyIcons() for (int i = 0; i < m_trophy_table->rowCount(); ++i) indices.append(i); - QtConcurrent::blockingMap(indices, [this, db_pos, dpr, new_height](int& i) + std::function get_scaled = [this, db_pos, dpr, new_height](const int& i) { QTableWidgetItem* item = m_trophy_table->item(i, TrophyColumns::Id); QTableWidgetItem* icon_item = m_trophy_table->item(i, TrophyColumns::Icon); if (!item || !icon_item) { - return; + return QPixmap(); } const int trophy_id = item->text().toInt(); const QPixmap icon = m_trophies_db[db_pos]->trophy_images[trophy_id]; @@ -555,9 +563,17 @@ void trophy_manager_dialog::ResizeTrophyIcons() painter.end(); } - const QPixmap scaled = new_icon.scaledToHeight(new_height, Qt::SmoothTransformation); - icon_item->setData(Qt::DecorationRole, scaled); - }); + return new_icon.scaledToHeight(new_height, Qt::SmoothTransformation); + }; + + QList scaled = QtConcurrent::blockingMapped>(indices, get_scaled); + + for (int i = 0; i < m_trophy_table->rowCount() && i < scaled.count(); ++i) + { + QTableWidgetItem* icon_item = m_trophy_table->item(i, TrophyColumns::Icon); + if (icon_item) + icon_item->setData(Qt::DecorationRole, scaled[i]); + } ReadjustTrophyTable(); } @@ -706,41 +722,44 @@ void trophy_manager_dialog::PopulateGameTable() m_game_combo->clear(); - QList names; QList indices; for (size_t i = 0; i < m_trophies_db.size(); ++i) - { - const int index = static_cast(i); - const QString name = qstr(m_trophies_db[i]->game_name).simplified(); - m_game_combo->addItem(name, index); - names.append(name); - indices.append(index); - } + indices.append(static_cast(i)); - QtConcurrent::blockingMap(indices, [this, &names](int& i) + std::function get_icon = [this](const int& i) { - const int all_trophies = m_trophies_db[i]->trop_usr->GetTrophiesCount(); - const int unlocked_trophies = m_trophies_db[i]->trop_usr->GetUnlockedTrophiesCount(); - const int percentage = 100 * unlocked_trophies / all_trophies; - const std::string icon_path = m_trophies_db[i]->path + "/ICON0.PNG"; - const QString progress = QString("%0% (%1/%2)").arg(percentage).arg(unlocked_trophies).arg(all_trophies); - // Load game icon QPixmap icon; + const std::string icon_path = m_trophies_db[i]->path + "ICON0.PNG"; if (!icon.load(qstr(icon_path))) { LOG_WARNING(GENERAL, "Could not load trophy game icon from path %s", icon_path); } + return icon; + }; + + QList icons = QtConcurrent::blockingMapped>(indices, get_icon); + + for (int i = 0; i < indices.count(); ++i) + { + const int all_trophies = m_trophies_db[i]->trop_usr->GetTrophiesCount(); + const int unlocked_trophies = m_trophies_db[i]->trop_usr->GetUnlockedTrophiesCount(); + const int percentage = 100 * unlocked_trophies / all_trophies; + const QString progress = QString("%0% (%1/%2)").arg(percentage).arg(unlocked_trophies).arg(all_trophies); + const QString name = qstr(m_trophies_db[i]->game_name).simplified(); custom_table_widget_item* icon_item = new custom_table_widget_item; - icon_item->setData(Qt::UserRole, icon); + if (icons.count() > i) + icon_item->setData(Qt::UserRole, icons[i]); m_game_table->setItem(i, GameColumns::GameIcon, icon_item); - m_game_table->setItem(i, GameColumns::GameName, new custom_table_widget_item(names[i])); + m_game_table->setItem(i, GameColumns::GameName, new custom_table_widget_item(name)); m_game_table->setItem(i, GameColumns::GameProgress, new custom_table_widget_item(progress, Qt::UserRole, percentage)); - ResizeGameIcon(i); - }); + m_game_combo->addItem(name, i); + } + + ResizeGameIcons(); m_game_table->setSortingEnabled(true); // Enable sorting only after using setItem calls diff --git a/rpcs3/rpcs3qt/trophy_manager_dialog.h b/rpcs3/rpcs3qt/trophy_manager_dialog.h index dce1df1b0a..657d49e155 100644 --- a/rpcs3/rpcs3qt/trophy_manager_dialog.h +++ b/rpcs3/rpcs3qt/trophy_manager_dialog.h @@ -63,7 +63,7 @@ public Q_SLOTS: void HandleRepaintUiRequest(); private Q_SLOTS: - void ResizeGameIcon(int index); + QPixmap GetResizedGameIcon(int index); void ResizeGameIcons(); void ResizeTrophyIcons(); void ApplyFilter();