Qt: Remove QtAsyncProgressThread

Merged into CoverDownloaderThread.
This commit is contained in:
Stenzek
2025-11-27 01:31:22 +10:00
parent 2b26690565
commit 676165282b
4 changed files with 102 additions and 154 deletions

View File

@@ -63,14 +63,15 @@ void CoverDownloadWindow::onDownloadComplete()
QString error;
if (m_thread)
{
m_thread->join();
m_thread->wait();
if (!m_thread->getResult())
{
if (const std::string& err_str = m_thread->getError().GetDescription(); !err_str.empty())
m_ui.status->setText(QString::fromStdString(err_str));
}
m_thread.reset();
delete m_thread;
m_thread = nullptr;
}
updateEnabled();
@@ -103,12 +104,12 @@ void CoverDownloadWindow::updateEnabled()
void CoverDownloadWindow::startThread()
{
m_thread =
std::make_unique<CoverDownloadThread>(this, m_ui.urls->toPlainText(), m_ui.useSerialFileNames->isChecked());
m_thread = new CoverDownloadThread(m_ui.urls->toPlainText(), m_ui.useSerialFileNames->isChecked());
m_last_refresh_time.Reset();
connect(m_thread.get(), &CoverDownloadThread::statusUpdated, this, &CoverDownloadWindow::onDownloadStatus);
connect(m_thread.get(), &CoverDownloadThread::progressUpdated, this, &CoverDownloadWindow::onDownloadProgress);
connect(m_thread.get(), &CoverDownloadThread::threadFinished, this, &CoverDownloadWindow::onDownloadComplete);
m_thread->moveToThread(m_thread);
connect(m_thread, &CoverDownloadThread::statusUpdated, this, &CoverDownloadWindow::onDownloadStatus);
connect(m_thread, &CoverDownloadThread::progressUpdated, this, &CoverDownloadWindow::onDownloadProgress);
connect(m_thread, &CoverDownloadThread::threadFinished, this, &CoverDownloadWindow::onDownloadComplete);
m_thread->start();
updateEnabled();
}
@@ -119,20 +120,49 @@ void CoverDownloadWindow::cancelThread()
return;
m_thread->requestInterruption();
m_thread->join();
m_thread.reset();
m_thread->wait();
delete m_thread;
m_thread = nullptr;
}
CoverDownloadWindow::CoverDownloadThread::CoverDownloadThread(QWidget* parent, const QString& urls, bool use_serials)
: QtAsyncProgressThread(parent), m_use_serials(use_serials)
CoverDownloadThread::CoverDownloadThread(const QString& urls, bool use_serials) : QThread(), m_use_serials(use_serials)
{
for (const QString& str : urls.split(QChar('\n')))
m_urls.push_back(str.toStdString());
}
CoverDownloadWindow::CoverDownloadThread::~CoverDownloadThread() = default;
CoverDownloadThread::~CoverDownloadThread() = default;
void CoverDownloadWindow::CoverDownloadThread::runAsync()
bool CoverDownloadThread::IsCancelled() const
{
m_result = GameList::DownloadCovers(m_urls, m_use_serials, this, &m_error);
return isInterruptionRequested();
}
void CoverDownloadThread::SetTitle(const std::string_view title)
{
emit titleUpdated(QtUtils::StringViewToQString(title));
}
void CoverDownloadThread::SetStatusText(const std::string_view text)
{
ProgressCallback::SetStatusText(text);
emit statusUpdated(QtUtils::StringViewToQString(text));
}
void CoverDownloadThread::SetProgressRange(u32 range)
{
ProgressCallback::SetProgressRange(range);
emit progressUpdated(static_cast<int>(m_progress_value), static_cast<int>(m_progress_range));
}
void CoverDownloadThread::SetProgressValue(u32 value)
{
ProgressCallback::SetProgressValue(value);
emit progressUpdated(static_cast<int>(m_progress_value), static_cast<int>(m_progress_range));
}
void CoverDownloadThread::run()
{
m_result = GameList::DownloadCovers(m_urls, m_use_serials, static_cast<ProgressCallback*>(this), &m_error);
emit threadFinished();
}

View File

@@ -3,10 +3,10 @@
#pragma once
#include "qtprogresscallback.h"
#include "ui_coverdownloadwindow.h"
#include "common/error.h"
#include "common/progress_callback.h"
#include "common/timer.h"
#include "common/types.h"
@@ -16,6 +16,8 @@
#include <memory>
#include <string>
class CoverDownloadThread;
class CoverDownloadWindow final : public QWidget
{
Q_OBJECT
@@ -32,25 +34,6 @@ protected:
void closeEvent(QCloseEvent* ev) override;
private:
class CoverDownloadThread : public QtAsyncProgressThread
{
public:
CoverDownloadThread(QWidget* parent, const QString& urls, bool use_serials);
~CoverDownloadThread();
ALWAYS_INLINE const Error& getError() const { return m_error; }
ALWAYS_INLINE bool getResult() const { return m_result; }
protected:
void runAsync() override;
private:
std::vector<std::string> m_urls;
Error m_error;
bool m_use_serials = false;
bool m_result = false;
};
void startThread();
void cancelThread();
@@ -62,6 +45,39 @@ private:
void updateEnabled();
Ui::CoverDownloadWindow m_ui;
std::unique_ptr<CoverDownloadThread> m_thread;
CoverDownloadThread* m_thread = nullptr;
Timer m_last_refresh_time;
};
class CoverDownloadThread final : public QThread, private ProgressCallback
{
Q_OBJECT
public:
CoverDownloadThread(const QString& urls, bool use_serials);
~CoverDownloadThread();
ALWAYS_INLINE const Error& getError() const { return m_error; }
ALWAYS_INLINE bool getResult() const { return m_result; }
Q_SIGNALS:
void titleUpdated(const QString& title);
void statusUpdated(const QString& status);
void progressUpdated(int value, int range);
void threadFinished();
protected:
void run() override;
bool IsCancelled() const override;
void SetTitle(const std::string_view title) override;
void SetStatusText(const std::string_view text) override;
void SetProgressRange(u32 range) override;
void SetProgressValue(u32 value) override;
private:
std::vector<std::string> m_urls;
Error m_error;
bool m_use_serials = false;
bool m_result = false;
};

View File

@@ -96,6 +96,7 @@ void QtModalProgressCallback::checkForDelayedShow()
if (m_show_timer.GetTimeSeconds() >= m_show_delay)
MakeVisible();
}
void QtModalProgressCallback::MakeVisible()
{
m_dialog.setRange(0, m_progress_range);
@@ -106,79 +107,6 @@ void QtModalProgressCallback::MakeVisible()
m_dialog.show();
}
// NOTE: We deliberately don't set the thread parent, because otherwise we can't move it.
QtAsyncProgressThread::QtAsyncProgressThread(QWidget* parent) : QThread()
{
}
QtAsyncProgressThread::~QtAsyncProgressThread() = default;
bool QtAsyncProgressThread::IsCancelled() const
{
return isInterruptionRequested();
}
void QtAsyncProgressThread::SetCancellable(bool cancellable)
{
if (m_cancellable == cancellable)
return;
ProgressCallback::SetCancellable(cancellable);
}
void QtAsyncProgressThread::SetTitle(const std::string_view title)
{
emit titleUpdated(QtUtils::StringViewToQString(title));
}
void QtAsyncProgressThread::SetStatusText(const std::string_view text)
{
ProgressCallback::SetStatusText(text);
emit statusUpdated(QtUtils::StringViewToQString(text));
}
void QtAsyncProgressThread::SetProgressRange(u32 range)
{
ProgressCallback::SetProgressRange(range);
emit progressUpdated(static_cast<int>(m_progress_value), static_cast<int>(m_progress_range));
}
void QtAsyncProgressThread::SetProgressValue(u32 value)
{
ProgressCallback::SetProgressValue(value);
emit progressUpdated(static_cast<int>(m_progress_value), static_cast<int>(m_progress_range));
}
void QtAsyncProgressThread::start()
{
Assert(!isRunning());
QThread::start();
moveToThread(this);
m_starting_thread = QThread::currentThread();
m_start_semaphore.release();
}
void QtAsyncProgressThread::join()
{
if (isRunning())
QThread::wait();
}
void QtAsyncProgressThread::run()
{
m_start_semaphore.acquire();
emit threadStarting();
runAsync();
emit threadFinished();
moveToThread(m_starting_thread);
}
QWidget* QtAsyncProgressThread::parentWidget() const
{
return qobject_cast<QWidget*>(parent());
}
QtAsyncTaskWithProgress::QtAsyncTaskWithProgress(const QString& initial_title, const QString& initial_status_text,
bool cancellable, int range, int value, float show_delay,
QWidget* dialog_parent, WorkCallback callback)
@@ -266,9 +194,9 @@ void QtAsyncTaskWithProgress::ProgressDialog::cancelled()
m_task.m_ts_cancelled.store(true, std::memory_order_release);
}
void QtAsyncTaskWithProgress::create(QWidget* parent, std::string_view initial_title,
std::string_view initial_status_text, bool cancellable, int range, int value,
float show_delay, WorkCallback callback)
QtAsyncTaskWithProgress* QtAsyncTaskWithProgress::create(QWidget* parent, std::string_view initial_title,
std::string_view initial_status_text, bool cancellable,
int range, int value, float show_delay, WorkCallback callback)
{
DebugAssert(parent);
@@ -286,11 +214,18 @@ void QtAsyncTaskWithProgress::create(QWidget* parent, std::string_view initial_t
delete task;
});
});
return task;
}
void QtAsyncTaskWithProgress::create(QWidget* parent, float show_delay, WorkCallback callback)
QtAsyncTaskWithProgress* QtAsyncTaskWithProgress::create(QWidget* parent, float show_delay, WorkCallback callback)
{
create(parent, {}, {}, false, 0, 1, show_delay, std::move(callback));
return create(parent, {}, {}, false, 0, 1, show_delay, std::move(callback));
}
void QtAsyncTaskWithProgress::cancel()
{
m_ts_cancelled.store(true, std::memory_order_release);
}
bool QtAsyncTaskWithProgress::IsCancelled() const

View File

@@ -50,43 +50,6 @@ private:
float m_show_delay;
};
class QtAsyncProgressThread : public QThread, public ProgressCallback
{
Q_OBJECT
public:
explicit QtAsyncProgressThread(QWidget* parent);
~QtAsyncProgressThread();
bool IsCancelled() const override;
void SetCancellable(bool cancellable) override;
void SetTitle(const std::string_view title) override;
void SetStatusText(const std::string_view text) override;
void SetProgressRange(u32 range) override;
void SetProgressValue(u32 value) override;
void start();
void join();
Q_SIGNALS:
void titleUpdated(const QString& title);
void statusUpdated(const QString& status);
void progressUpdated(int value, int range);
void threadStarting();
void threadFinished();
protected:
virtual void runAsync() = 0;
void run() final;
private:
QWidget* parentWidget() const;
QSemaphore m_start_semaphore;
QThread* m_starting_thread = nullptr;
};
class QtAsyncTaskWithProgress final : public QObject, private ProgressCallback
{
Q_OBJECT
@@ -95,11 +58,14 @@ public:
using CompletionCallback = std::function<void()>;
using WorkCallback = std::function<CompletionCallback(ProgressCallback*)>;
~QtAsyncTaskWithProgress();
static QtAsyncTaskWithProgress* create(QWidget* parent, std::string_view initial_title,
std::string_view initial_status_text, bool cancellable, int range, int value,
float show_delay, WorkCallback callback);
static QtAsyncTaskWithProgress* create(QWidget* parent, float show_delay, WorkCallback callback);
static void create(QWidget* parent, std::string_view initial_title, std::string_view initial_status_text,
bool cancellable, int range, int value, float show_delay, WorkCallback callback);
static void create(QWidget* parent, float show_delay, WorkCallback callback);
/// Asynchronously cancel the task. Should only be called from the UI thread.
/// There is no guarantee when the cancel will go through.
void cancel();
Q_SIGNALS:
void completed(QtAsyncTaskWithProgress* self);
@@ -138,6 +104,7 @@ private:
// constructor hidden, clients should not be creating this directly
QtAsyncTaskWithProgress(const QString& initial_title, const QString& initial_status_text, bool cancellable, int range,
int value, float show_delay, QWidget* dialog_parent, WorkCallback callback);
~QtAsyncTaskWithProgress();
// progress callback overrides
bool IsCancelled() const override;