Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #8714 from JosJuice/progress-dialog-thread
DolphinQt: Run tasks that use progress dialogs on separate threads
  • Loading branch information
JMC47 committed Apr 22, 2020
2 parents c335652 + 55f787b commit a5bd263
Show file tree
Hide file tree
Showing 17 changed files with 230 additions and 137 deletions.
4 changes: 0 additions & 4 deletions Source/Android/jni/MainAndroid.cpp
Expand Up @@ -140,10 +140,6 @@ void Host_YieldToUI()
{
}

void Host_UpdateProgressDialog(const char* caption, int position, int total)
{
}

void Host_TitleChanged()
{
}
Expand Down
1 change: 0 additions & 1 deletion Source/Core/Core/Host.h
Expand Up @@ -43,5 +43,4 @@ void Host_UpdateDisasmDialog();
void Host_UpdateMainFrame();
void Host_UpdateTitle(const std::string& title);
void Host_YieldToUI();
void Host_UpdateProgressDialog(const char* caption, int position, int total);
void Host_TitleChanged();
4 changes: 0 additions & 4 deletions Source/Core/DolphinNoGUI/MainNoGUI.cpp
Expand Up @@ -99,10 +99,6 @@ void Host_YieldToUI()
{
}

void Host_UpdateProgressDialog(const char* caption, int position, int total)
{
}

void Host_TitleChanged()
{
#ifdef USE_DISCORD_PRESENCE
Expand Down
1 change: 1 addition & 0 deletions Source/Core/DolphinQt/CMakeLists.txt
Expand Up @@ -224,6 +224,7 @@ add_executable(dolphin-emu
QtUtils/FlowLayout.h
QtUtils/ModalMessageBox.cpp
QtUtils/ModalMessageBox.h
QtUtils/ParallelProgressDialog.h
QtUtils/ImageConverter.cpp
QtUtils/ImageConverter.h
QtUtils/WindowActivationEventFilter.cpp
Expand Down
44 changes: 25 additions & 19 deletions Source/Core/DolphinQt/Config/FilesystemWidget.cpp
Expand Up @@ -10,7 +10,6 @@
#include <QFileInfo>
#include <QHeaderView>
#include <QMenu>
#include <QProgressDialog>
#include <QStandardItemModel>
#include <QStyleFactory>
#include <QTreeView>
Expand All @@ -23,6 +22,7 @@
#include "DiscIO/Volume.h"

#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/ParallelProgressDialog.h"
#include "DolphinQt/Resources.h"

#include "UICommon/UICommon.h"
Expand Down Expand Up @@ -282,28 +282,34 @@ void FilesystemWidget::ExtractDirectory(const DiscIO::Partition& partition, cons
std::unique_ptr<DiscIO::FileInfo> info = filesystem->FindFileInfo(path.toStdString());
u32 size = info->GetTotalChildren();

QProgressDialog* dialog = new QProgressDialog(this);
dialog->setWindowFlags(dialog->windowFlags() & ~Qt::WindowContextHelpButtonHint);
dialog->setMinimum(0);
dialog->setMaximum(size);
dialog->show();
dialog->setWindowTitle(tr("Progress"));
ParallelProgressDialog dialog(this);
dialog.GetRaw()->setMinimum(0);
dialog.GetRaw()->setMaximum(size);
dialog.GetRaw()->setWindowTitle(tr("Progress"));

bool all = path.isEmpty();
const bool all = path.isEmpty();

DiscIO::ExportDirectory(
*m_volume, partition, *info, true, path.toStdString(), out.toStdString(),
[all, dialog](const std::string& current) {
dialog->setLabelText(
(all ? QObject::tr("Extracting All Files...") : QObject::tr("Extracting Directory..."))
.append(QStringLiteral(" %1").arg(QString::fromStdString(current))));
dialog->setValue(dialog->value() + 1);
std::future<void> future = std::async(std::launch::async, [&] {
int progress = 0;

QCoreApplication::processEvents();
return dialog->wasCanceled();
});
DiscIO::ExportDirectory(
*m_volume, partition, *info, true, path.toStdString(), out.toStdString(),
[all, &dialog, &progress](const std::string& current) {
dialog.SetLabelText(
(all ? QObject::tr("Extracting All Files...") :
QObject::tr("Extracting Directory..."))
.append(QStringLiteral(" %1").arg(QString::fromStdString(current))));
dialog.SetValue(++progress);

dialog->close();
QCoreApplication::processEvents();
return dialog.WasCanceled();
});

dialog.Reset();
});

dialog.GetRaw()->exec();
future.get();
}

void FilesystemWidget::ExtractFile(const DiscIO::Partition& partition, const QString& path,
Expand Down
1 change: 0 additions & 1 deletion Source/Core/DolphinQt/Config/InfoWidget.cpp
Expand Up @@ -10,7 +10,6 @@
#include <QGroupBox>
#include <QLabel>
#include <QLineEdit>
#include <QProgressDialog>
#include <QPushButton>
#include <QTextEdit>

Expand Down
73 changes: 43 additions & 30 deletions Source/Core/DolphinQt/Config/VerifyWidget.cpp
Expand Up @@ -4,20 +4,22 @@

#include "DolphinQt/Config/VerifyWidget.h"

#include <future>
#include <memory>
#include <optional>
#include <tuple>
#include <vector>

#include <QByteArray>
#include <QHBoxLayout>
#include <QHeaderView>
#include <QLabel>
#include <QProgressDialog>
#include <QVBoxLayout>

#include "Common/CommonTypes.h"
#include "DiscIO/Volume.h"
#include "DiscIO/VolumeVerifier.h"
#include "DolphinQt/QtUtils/ParallelProgressDialog.h"

VerifyWidget::VerifyWidget(std::shared_ptr<DiscIO::Volume> volume) : m_volume(std::move(volume))
{
Expand Down Expand Up @@ -131,33 +133,44 @@ void VerifyWidget::Verify()
// We have to divide the number of processed bytes with something so it won't make ints overflow
constexpr int DIVISOR = 0x100;

QProgressDialog progress(tr("Verifying"), tr("Cancel"), 0, verifier.GetTotalBytes() / DIVISOR,
this);
progress.setWindowTitle(tr("Verifying"));
progress.setWindowFlags(progress.windowFlags() & ~Qt::WindowContextHelpButtonHint);
progress.setMinimumDuration(500);
progress.setWindowModality(Qt::WindowModal);

verifier.Start();
while (verifier.GetBytesProcessed() != verifier.GetTotalBytes())
{
progress.setValue(verifier.GetBytesProcessed() / DIVISOR);
if (progress.wasCanceled())
return;

verifier.Process();
}
verifier.Finish();

DiscIO::VolumeVerifier::Result result = verifier.GetResult();
progress.setValue(verifier.GetBytesProcessed() / DIVISOR);

m_summary_text->setText(QString::fromStdString(result.summary_text));

m_problems->setRowCount(static_cast<int>(result.problems.size()));
ParallelProgressDialog progress(tr("Verifying"), tr("Cancel"), 0,
static_cast<int>(verifier.GetTotalBytes() / DIVISOR), this);
progress.GetRaw()->setWindowTitle(tr("Verifying"));
progress.GetRaw()->setMinimumDuration(500);
progress.GetRaw()->setWindowModality(Qt::WindowModal);

auto future =
std::async(std::launch::async,
[&verifier, &progress]() -> std::optional<DiscIO::VolumeVerifier::Result> {
progress.SetValue(0);
verifier.Start();
while (verifier.GetBytesProcessed() != verifier.GetTotalBytes())
{
progress.SetValue(static_cast<int>(verifier.GetBytesProcessed() / DIVISOR));
if (progress.WasCanceled())
return std::nullopt;

verifier.Process();
}
verifier.Finish();

const DiscIO::VolumeVerifier::Result result = verifier.GetResult();
progress.Reset();

return result;
});
progress.GetRaw()->exec();

std::optional<DiscIO::VolumeVerifier::Result> result = future.get();
if (!result)
return;

m_summary_text->setText(QString::fromStdString(result->summary_text));

m_problems->setRowCount(static_cast<int>(result->problems.size()));
for (int i = 0; i < m_problems->rowCount(); ++i)
{
const DiscIO::VolumeVerifier::Problem problem = result.problems[i];
const DiscIO::VolumeVerifier::Problem problem = result->problems[i];

QString severity;
switch (problem.severity)
Expand All @@ -179,12 +192,12 @@ void VerifyWidget::Verify()
SetProblemCellText(i, 1, severity);
}

SetHash(m_crc32_line_edit, result.hashes.crc32);
SetHash(m_md5_line_edit, result.hashes.md5);
SetHash(m_sha1_line_edit, result.hashes.sha1);
SetHash(m_crc32_line_edit, result->hashes.crc32);
SetHash(m_md5_line_edit, result->hashes.md5);
SetHash(m_sha1_line_edit, result->hashes.sha1);

if (m_redump_line_edit)
m_redump_line_edit->setText(QString::fromStdString(result.redump.message));
m_redump_line_edit->setText(QString::fromStdString(result->redump.message));
}

void VerifyWidget::SetProblemCellText(int row, int column, QString text)
Expand Down
4 changes: 3 additions & 1 deletion Source/Core/DolphinQt/DolphinQt.vcxproj
Expand Up @@ -181,6 +181,7 @@
<QtMoc Include="QtUtils\FileOpenEventFilter.h" />
<QtMoc Include="QtUtils\FlowLayout.h" />
<QtMoc Include="QtUtils\ModalMessageBox.h" />
<QtMoc Include="QtUtils\ParallelProgressDialog.h" />
<QtMoc Include="QtUtils\WindowActivationEventFilter.h" />
<QtMoc Include="QtUtils\WrapInScrollArea.h" />
<QtMoc Include="RenderWidget.h" />
Expand Down Expand Up @@ -282,6 +283,7 @@
<ClCompile Include="$(QtMocOutPrefix)NewBreakpointDialog.cpp" />
<ClCompile Include="$(QtMocOutPrefix)NewPatchDialog.cpp" />
<ClCompile Include="$(QtMocOutPrefix)PadMappingDialog.cpp" />
<ClCompile Include="$(QtMocOutPrefix)ParallelProgressDialog.cpp" />
<ClCompile Include="$(QtMocOutPrefix)PatchesWidget.cpp" />
<ClCompile Include="$(QtMocOutPrefix)PatchInstructionDialog.cpp" />
<ClCompile Include="$(QtMocOutPrefix)PathPane.cpp" />
Expand Down Expand Up @@ -541,4 +543,4 @@
<Message Text="Copy: @(BinaryFiles) -&gt; $(BinaryOutputDir)" Importance="High" />
<Copy SourceFiles="@(BinaryFiles)" DestinationFolder="$(BinaryOutputDir)" />
</Target>
</Project>
</Project>
59 changes: 38 additions & 21 deletions Source/Core/DolphinQt/GameList/GameList.cpp
Expand Up @@ -6,6 +6,7 @@

#include <algorithm>
#include <cmath>
#include <future>

#include <QDesktopServices>
#include <QDir>
Expand All @@ -20,7 +21,6 @@
#include <QListView>
#include <QMap>
#include <QMenu>
#include <QProgressDialog>
#include <QShortcut>
#include <QSortFilterProxyModel>
#include <QTableView>
Expand All @@ -46,6 +46,7 @@
#include "DolphinQt/MenuBar.h"
#include "DolphinQt/QtUtils/DoubleClickEventFilter.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/ParallelProgressDialog.h"
#include "DolphinQt/Resources.h"
#include "DolphinQt/Settings.h"
#include "DolphinQt/WiiUpdate.h"
Expand Down Expand Up @@ -577,34 +578,50 @@ void GameList::CompressISO(bool decompress)
}
}

QProgressDialog progress_dialog(decompress ? tr("Decompressing...") : tr("Compressing..."),
tr("Abort"), 0, 100, this);
progress_dialog.setWindowModality(Qt::WindowModal);
progress_dialog.setWindowFlags(progress_dialog.windowFlags() &
~Qt::WindowContextHelpButtonHint);
progress_dialog.setWindowTitle(tr("Progress"));
ParallelProgressDialog progress_dialog(
decompress ? tr("Decompressing...") : tr("Compressing..."), tr("Abort"), 0, 100, this);
progress_dialog.GetRaw()->setWindowModality(Qt::WindowModal);
progress_dialog.GetRaw()->setWindowTitle(tr("Progress"));

bool good;
std::future<bool> good;

if (decompress)
{
if (files.size() > 1)
progress_dialog.setLabelText(tr("Decompressing...") + QLatin1Char{'\n'} +
QFileInfo(QString::fromStdString(original_path)).fileName());
good = DiscIO::DecompressBlobToFile(original_path, dst_path.toStdString(), &CompressCB,
&progress_dialog);
{
progress_dialog.GetRaw()->setLabelText(
tr("Decompressing...") + QLatin1Char{'\n'} +
QFileInfo(QString::fromStdString(original_path)).fileName());
}

good = std::async(std::launch::async, [&] {
const bool good = DiscIO::DecompressBlobToFile(original_path, dst_path.toStdString(),
&CompressCB, &progress_dialog);
progress_dialog.Reset();
return good;
});
}
else
{
if (files.size() > 1)
progress_dialog.setLabelText(tr("Compressing...") + QLatin1Char{'\n'} +
QFileInfo(QString::fromStdString(original_path)).fileName());
good = DiscIO::CompressFileToBlob(original_path, dst_path.toStdString(),
file->GetPlatform() == DiscIO::Platform::WiiDisc ? 1 : 0,
16384, &CompressCB, &progress_dialog);
{
progress_dialog.GetRaw()->setLabelText(
tr("Compressing...") + QLatin1Char{'\n'} +
QFileInfo(QString::fromStdString(original_path)).fileName());
}

good = std::async(std::launch::async, [&] {
const bool good =
DiscIO::CompressFileToBlob(original_path, dst_path.toStdString(),
file->GetPlatform() == DiscIO::Platform::WiiDisc ? 1 : 0,
16384, &CompressCB, &progress_dialog);
progress_dialog.Reset();
return good;
});
}

if (!good)
progress_dialog.GetRaw()->exec();
if (!good.get())
{
QErrorMessage(this).showMessage(tr("Dolphin failed to complete the requested action."));
return;
Expand Down Expand Up @@ -937,10 +954,10 @@ static bool CompressCB(const std::string& text, float percent, void* ptr)
if (ptr == nullptr)
return false;

auto* progress_dialog = static_cast<QProgressDialog*>(ptr);
auto* progress_dialog = static_cast<ParallelProgressDialog*>(ptr);

progress_dialog->setValue(percent * 100);
return !progress_dialog->wasCanceled();
progress_dialog->SetValue(percent * 100);
return !progress_dialog->WasCanceled();
}

void GameList::OnSectionResized(int index, int, int)
Expand Down
6 changes: 0 additions & 6 deletions Source/Core/DolphinQt/Host.cpp
Expand Up @@ -6,7 +6,6 @@

#include <QAbstractEventDispatcher>
#include <QApplication>
#include <QProgressDialog>

#include <imgui.h>

Expand Down Expand Up @@ -126,11 +125,6 @@ void Host_UpdateDisasmDialog()
QueueOnObject(QApplication::instance(), [] { emit Host::GetInstance()->UpdateDisasmDialog(); });
}

void Host_UpdateProgressDialog(const char* caption, int position, int total)
{
emit Host::GetInstance()->UpdateProgressDialog(QString::fromUtf8(caption), position, total);
}

void Host::RequestNotifyMapLoaded()
{
QueueOnObject(QApplication::instance(), [this] { emit NotifyMapLoaded(); });
Expand Down
1 change: 0 additions & 1 deletion Source/Core/DolphinQt/Host.h
Expand Up @@ -33,7 +33,6 @@ class Host final : public QObject
void RequestTitle(const QString& title);
void RequestStop();
void RequestRenderSize(int w, int h);
void UpdateProgressDialog(QString label, int position, int maximum);
void UpdateDisasmDialog();
void NotifyMapLoaded();

Expand Down

0 comments on commit a5bd263

Please sign in to comment.