diff options
| author | JMC47 <JMC4789@gmail.com> | 2020-04-21 23:59:37 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-21 23:59:37 -0400 |
| commit | a5bd263dfba780de6a6fc88ccc996d42d350d416 (patch) | |
| tree | 0337aa4a34d5c405926dc0ca49c761cc44522bf2 /Source | |
| parent | c33565295dd913991a543147f81be8687f3be737 (diff) | |
| parent | 55f787b89898d28bd6245ec6768247659dd85b88 (diff) | |
Merge pull request #8714 from JosJuice/progress-dialog-thread
DolphinQt: Run tasks that use progress dialogs on separate threads
Diffstat (limited to 'Source')
| -rw-r--r-- | Source/Android/jni/MainAndroid.cpp | 4 | ||||
| -rw-r--r-- | Source/Core/Core/Host.h | 1 | ||||
| -rw-r--r-- | Source/Core/DolphinNoGUI/MainNoGUI.cpp | 4 | ||||
| -rw-r--r-- | Source/Core/DolphinQt/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | Source/Core/DolphinQt/Config/FilesystemWidget.cpp | 44 | ||||
| -rw-r--r-- | Source/Core/DolphinQt/Config/InfoWidget.cpp | 1 | ||||
| -rw-r--r-- | Source/Core/DolphinQt/Config/VerifyWidget.cpp | 73 | ||||
| -rw-r--r-- | Source/Core/DolphinQt/DolphinQt.vcxproj | 4 | ||||
| -rw-r--r-- | Source/Core/DolphinQt/GameList/GameList.cpp | 59 | ||||
| -rw-r--r-- | Source/Core/DolphinQt/Host.cpp | 6 | ||||
| -rw-r--r-- | Source/Core/DolphinQt/Host.h | 1 | ||||
| -rw-r--r-- | Source/Core/DolphinQt/MainWindow.cpp | 50 | ||||
| -rw-r--r-- | Source/Core/DolphinQt/MainWindow.h | 4 | ||||
| -rw-r--r-- | Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp | 1 | ||||
| -rw-r--r-- | Source/Core/DolphinQt/QtUtils/ParallelProgressDialog.h | 108 | ||||
| -rw-r--r-- | Source/DSPTool/StubHost.cpp | 3 | ||||
| -rw-r--r-- | Source/UnitTests/StubHost.cpp | 3 |
17 files changed, 230 insertions, 137 deletions
diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp index 2bebbc4e8d..122f3fd6d9 100644 --- a/Source/Android/jni/MainAndroid.cpp +++ b/Source/Android/jni/MainAndroid.cpp @@ -140,10 +140,6 @@ void Host_YieldToUI() { } -void Host_UpdateProgressDialog(const char* caption, int position, int total) -{ -} - void Host_TitleChanged() { } diff --git a/Source/Core/Core/Host.h b/Source/Core/Core/Host.h index d3f5ee4b61..cf65c22eb0 100644 --- a/Source/Core/Core/Host.h +++ b/Source/Core/Core/Host.h @@ -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(); diff --git a/Source/Core/DolphinNoGUI/MainNoGUI.cpp b/Source/Core/DolphinNoGUI/MainNoGUI.cpp index 14fac966c9..1278d46c40 100644 --- a/Source/Core/DolphinNoGUI/MainNoGUI.cpp +++ b/Source/Core/DolphinNoGUI/MainNoGUI.cpp @@ -99,10 +99,6 @@ void Host_YieldToUI() { } -void Host_UpdateProgressDialog(const char* caption, int position, int total) -{ -} - void Host_TitleChanged() { #ifdef USE_DISCORD_PRESENCE diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index f0951cb3b5..6a124cd03b 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -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 diff --git a/Source/Core/DolphinQt/Config/FilesystemWidget.cpp b/Source/Core/DolphinQt/Config/FilesystemWidget.cpp index 461a83ccc6..ddffe76963 100644 --- a/Source/Core/DolphinQt/Config/FilesystemWidget.cpp +++ b/Source/Core/DolphinQt/Config/FilesystemWidget.cpp @@ -10,7 +10,6 @@ #include <QFileInfo> #include <QHeaderView> #include <QMenu> -#include <QProgressDialog> #include <QStandardItemModel> #include <QStyleFactory> #include <QTreeView> @@ -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" @@ -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, diff --git a/Source/Core/DolphinQt/Config/InfoWidget.cpp b/Source/Core/DolphinQt/Config/InfoWidget.cpp index 416c1a8866..c382c7dc1b 100644 --- a/Source/Core/DolphinQt/Config/InfoWidget.cpp +++ b/Source/Core/DolphinQt/Config/InfoWidget.cpp @@ -10,7 +10,6 @@ #include <QGroupBox> #include <QLabel> #include <QLineEdit> -#include <QProgressDialog> #include <QPushButton> #include <QTextEdit> diff --git a/Source/Core/DolphinQt/Config/VerifyWidget.cpp b/Source/Core/DolphinQt/Config/VerifyWidget.cpp index 925409a81c..ce221bce8f 100644 --- a/Source/Core/DolphinQt/Config/VerifyWidget.cpp +++ b/Source/Core/DolphinQt/Config/VerifyWidget.cpp @@ -4,7 +4,9 @@ #include "DolphinQt/Config/VerifyWidget.h" +#include <future> #include <memory> +#include <optional> #include <tuple> #include <vector> @@ -12,12 +14,12 @@ #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)) { @@ -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) @@ -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) diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj index de228eba5f..1763c06300 100644 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj +++ b/Source/Core/DolphinQt/DolphinQt.vcxproj @@ -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" /> @@ -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" /> @@ -541,4 +543,4 @@ <Message Text="Copy: @(BinaryFiles) -> $(BinaryOutputDir)" Importance="High" /> <Copy SourceFiles="@(BinaryFiles)" DestinationFolder="$(BinaryOutputDir)" /> </Target> -</Project> +</Project>
\ No newline at end of file diff --git a/Source/Core/DolphinQt/GameList/GameList.cpp b/Source/Core/DolphinQt/GameList/GameList.cpp index f15b20664f..a635bee291 100644 --- a/Source/Core/DolphinQt/GameList/GameList.cpp +++ b/Source/Core/DolphinQt/GameList/GameList.cpp @@ -6,6 +6,7 @@ #include <algorithm> #include <cmath> +#include <future> #include <QDesktopServices> #include <QDir> @@ -20,7 +21,6 @@ #include <QListView> #include <QMap> #include <QMenu> -#include <QProgressDialog> #include <QShortcut> #include <QSortFilterProxyModel> #include <QTableView> @@ -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" @@ -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; @@ -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) diff --git a/Source/Core/DolphinQt/Host.cpp b/Source/Core/DolphinQt/Host.cpp index fc53954195..cb910854d1 100644 --- a/Source/Core/DolphinQt/Host.cpp +++ b/Source/Core/DolphinQt/Host.cpp @@ -6,7 +6,6 @@ #include <QAbstractEventDispatcher> #include <QApplication> -#include <QProgressDialog> #include <imgui.h> @@ -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(); }); diff --git a/Source/Core/DolphinQt/Host.h b/Source/Core/DolphinQt/Host.h index 9a25d217a9..e1c44b91a2 100644 --- a/Source/Core/DolphinQt/Host.h +++ b/Source/Core/DolphinQt/Host.h @@ -33,7 +33,6 @@ signals: 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(); diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index 6080457c5a..89a19b42ba 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -12,7 +12,6 @@ #include <QFileInfo> #include <QIcon> #include <QMimeData> -#include <QProgressDialog> #include <QStackedWidget> #include <QVBoxLayout> #include <QWindow> @@ -87,6 +86,7 @@ #include "DolphinQt/NetPlay/NetPlaySetupDialog.h" #include "DolphinQt/QtUtils/FileOpenEventFilter.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" +#include "DolphinQt/QtUtils/ParallelProgressDialog.h" #include "DolphinQt/QtUtils/QueueOnObject.h" #include "DolphinQt/QtUtils/RunOnObject.h" #include "DolphinQt/QtUtils/WindowActivationEventFilter.h" @@ -615,8 +615,6 @@ void MainWindow::ConnectRenderWidget() void MainWindow::ConnectHost() { - connect(Host::GetInstance(), &Host::UpdateProgressDialog, this, - &MainWindow::OnUpdateProgressDialog); connect(Host::GetInstance(), &Host::RequestStop, this, &MainWindow::RequestStop); } @@ -1510,23 +1508,21 @@ void MainWindow::OnImportNANDBackup() if (file.isEmpty()) return; - QProgressDialog* dialog = new QProgressDialog(this); - dialog->setMinimum(0); - dialog->setMaximum(0); - dialog->setLabelText(tr("Importing NAND backup")); - dialog->setCancelButton(nullptr); + ParallelProgressDialog dialog(this); + dialog.GetRaw()->setMinimum(0); + dialog.GetRaw()->setMaximum(0); + dialog.GetRaw()->setLabelText(tr("Importing NAND backup")); + dialog.GetRaw()->setCancelButton(nullptr); auto beginning = QDateTime::currentDateTime().toMSecsSinceEpoch(); - auto result = std::async(std::launch::async, [&] { + std::future<void> result = std::async(std::launch::async, [&] { DiscIO::NANDImporter().ImportNANDBin( file.toStdString(), [&dialog, beginning] { - QueueOnObject(dialog, [&dialog, beginning] { - dialog->setLabelText( - tr("Importing NAND backup\n Time elapsed: %1s") - .arg((QDateTime::currentDateTime().toMSecsSinceEpoch() - beginning) / 1000)); - }); + dialog.SetLabelText( + tr("Importing NAND backup\n Time elapsed: %1s") + .arg((QDateTime::currentDateTime().toMSecsSinceEpoch() - beginning) / 1000)); }, [this] { std::optional<std::string> keys_file = RunOnObject(this, [this] { @@ -1540,10 +1536,10 @@ void MainWindow::OnImportNANDBackup() return *keys_file; return std::string(""); }); - QueueOnObject(dialog, &QProgressDialog::close); + dialog.Reset(); }); - dialog->exec(); + dialog.GetRaw()->exec(); result.wait(); @@ -1703,28 +1699,6 @@ void MainWindow::ShowCheatsManager() m_cheats_manager->show(); } -void MainWindow::OnUpdateProgressDialog(QString title, int progress, int total) -{ - if (!m_progress_dialog) - { - m_progress_dialog = new QProgressDialog(m_render_widget, Qt::WindowTitleHint); - m_progress_dialog->show(); - m_progress_dialog->setCancelButton(nullptr); - m_progress_dialog->setWindowTitle(tr("Dolphin")); - } - - m_progress_dialog->setValue(progress); - m_progress_dialog->setLabelText(title); - m_progress_dialog->setMaximum(total); - - if (total < 0 || progress >= total) - { - m_progress_dialog->hide(); - m_progress_dialog->deleteLater(); - m_progress_dialog = nullptr; - } -} - void MainWindow::Show() { if (!Settings::Instance().IsBatchModeEnabled()) diff --git a/Source/Core/DolphinQt/MainWindow.h b/Source/Core/DolphinQt/MainWindow.h index acc93df540..50fea52a24 100644 --- a/Source/Core/DolphinQt/MainWindow.h +++ b/Source/Core/DolphinQt/MainWindow.h @@ -11,7 +11,6 @@ #include <optional> #include <string> -class QProgressDialog; class QStackedWidget; class QString; @@ -167,8 +166,6 @@ private: void OnSignal(); #endif - void OnUpdateProgressDialog(QString label, int progress, int total); - void OnPlayRecording(); void OnStartRecording(); void OnStopRecording(); @@ -193,7 +190,6 @@ private: std::unique_ptr<X11Utils::XRRConfiguration> m_xrr_config; #endif - QProgressDialog* m_progress_dialog = nullptr; QStackedWidget* m_stack; ToolBar* m_tool_bar; MenuBar* m_menu_bar; diff --git a/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp b/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp index 31abe2f384..230823b8b6 100644 --- a/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp +++ b/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp @@ -14,7 +14,6 @@ #include <QLabel> #include <QLineEdit> #include <QMenu> -#include <QProgressDialog> #include <QPushButton> #include <QSignalBlocker> #include <QSpinBox> diff --git a/Source/Core/DolphinQt/QtUtils/ParallelProgressDialog.h b/Source/Core/DolphinQt/QtUtils/ParallelProgressDialog.h new file mode 100644 index 0000000000..274e3d4b11 --- /dev/null +++ b/Source/Core/DolphinQt/QtUtils/ParallelProgressDialog.h @@ -0,0 +1,108 @@ +#pragma once + +#include <chrono> +#include <utility> + +#include <QObject> +#include <QProgressDialog> +#include <QString> + +#include "Common/Flag.h" + +class ParallelProgressDialog final : public QObject +{ + Q_OBJECT + +public: + // Only use this from the main thread + template <typename... Args> + ParallelProgressDialog(Args&&... args) : m_dialog{std::forward<Args>(args)...} + { + setParent(m_dialog.parent()); + m_dialog.setWindowFlags(m_dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint); + ConnectSignalsAndSlots(); + } + + // Only use this from the main thread + QProgressDialog* GetRaw() { return &m_dialog; } + + // All of the following can be called from any thread + void Cancel() { emit CancelSignal(); } + void Reset() { emit ResetSignal(); } + void SetCancelButtonText(const QString& text) { emit SetCancelButtonText(text); } + void SetLabelText(const QString& text) { emit SetLabelTextSignal(text); } + void SetMaximum(int maximum) { emit SetMaximumSignal(maximum); } + void SetMinimum(int minimum) { emit SetMinimumSignal(minimum); } + void SetMinimumDuration(int ms) { emit SetMinimumDurationSignal(ms); } + void SetRange(int minimum, int maximum) { emit SetRangeSignal(minimum, maximum); } + + // Can be called from any thread, but only from one thread at a time + void SetValue(int progress) + { + // HACK: To avoid the https://bugreports.qt.io/browse/QTBUG-10561 stack overflow, + // limit how often QProgressDialog::setValue can run + const auto current_time = std::chrono::steady_clock::now(); + if (current_time - m_last_setvalue_time >= std::chrono::milliseconds(50)) + { + m_last_setvalue_time = current_time; + emit SetValueSignal(progress); + } + } + + // Can be called from any thread + bool WasCanceled() { return m_was_cancelled.IsSet(); } + +signals: + void CancelSignal(); + void ResetSignal(); + void SetCancelButtonTextSignal(const QString& cancel_button_text); + void SetLabelTextSignal(const QString& text); + void SetMaximumSignal(int maximum); + void SetMinimumSignal(int minimum); + void SetMinimumDurationSignal(int ms); + void SetRangeSignal(int minimum, int maximum); + void SetValueSignal(int progress); + + void Canceled(); + void Finished(int result); + +private slots: + void OnCancelled() { m_was_cancelled.Set(); } + +private: + template <typename Func1, typename Func2> + void ConnectSignal(Func1 signal, Func2 slot) + { + QObject::connect(this, signal, &m_dialog, slot); + } + + template <typename Func1, typename Func2> + void ConnectSlot(Func1 signal, Func2 slot) + { + QObject::connect(&m_dialog, signal, this, slot); + } + + void ConnectSignalsAndSlots() + { + ConnectSignal(&ParallelProgressDialog::CancelSignal, &QProgressDialog::cancel); + ConnectSignal(&ParallelProgressDialog::ResetSignal, &QProgressDialog::reset); + ConnectSignal(&ParallelProgressDialog::SetCancelButtonTextSignal, + &QProgressDialog::setCancelButtonText); + ConnectSignal(&ParallelProgressDialog::SetLabelTextSignal, &QProgressDialog::setLabelText); + ConnectSignal(&ParallelProgressDialog::SetMaximumSignal, &QProgressDialog::setMaximum); + ConnectSignal(&ParallelProgressDialog::SetMinimumSignal, &QProgressDialog::setMinimum); + ConnectSignal(&ParallelProgressDialog::SetMinimumDurationSignal, + &QProgressDialog::setMinimumDuration); + ConnectSignal(&ParallelProgressDialog::SetRangeSignal, &QProgressDialog::setRange); + ConnectSignal(&ParallelProgressDialog::SetValueSignal, &QProgressDialog::setValue); + + ConnectSlot(&QProgressDialog::canceled, &ParallelProgressDialog::OnCancelled); + + ConnectSlot(&QProgressDialog::canceled, &ParallelProgressDialog::Canceled); + ConnectSlot(&QProgressDialog::finished, &ParallelProgressDialog::Finished); + } + + QProgressDialog m_dialog; + Common::Flag m_was_cancelled; + std::chrono::time_point<std::chrono::steady_clock> m_last_setvalue_time; +}; diff --git a/Source/DSPTool/StubHost.cpp b/Source/DSPTool/StubHost.cpp index 75dd66296d..488a49d2cd 100644 --- a/Source/DSPTool/StubHost.cpp +++ b/Source/DSPTool/StubHost.cpp @@ -45,9 +45,6 @@ bool Host_RendererIsFullscreen() void Host_YieldToUI() { } -void Host_UpdateProgressDialog(const char* caption, int position, int total) -{ -} void Host_TitleChanged() { } diff --git a/Source/UnitTests/StubHost.cpp b/Source/UnitTests/StubHost.cpp index 4fa45ef1c2..211ee8bfba 100644 --- a/Source/UnitTests/StubHost.cpp +++ b/Source/UnitTests/StubHost.cpp @@ -46,9 +46,6 @@ bool Host_RendererIsFullscreen() void Host_YieldToUI() { } -void Host_UpdateProgressDialog(const char* caption, int position, int total) -{ -} void Host_TitleChanged() { } |
