mirror of
https://github.com/stenzek/duckstation.git
synced 2026-02-16 11:24:36 +00:00
Qt: Remove QtAsyncProgressThread
Merged into CoverDownloaderThread.
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user