Skip to content

Commit 6761652

Browse files
committed
Qt: Remove QtAsyncProgressThread
Merged into CoverDownloaderThread.
1 parent 2b26690 commit 6761652

File tree

4 files changed

+102
-154
lines changed

4 files changed

+102
-154
lines changed

src/duckstation-qt/coverdownloadwindow.cpp

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,15 @@ void CoverDownloadWindow::onDownloadComplete()
6363
QString error;
6464
if (m_thread)
6565
{
66-
m_thread->join();
66+
m_thread->wait();
6767
if (!m_thread->getResult())
6868
{
6969
if (const std::string& err_str = m_thread->getError().GetDescription(); !err_str.empty())
7070
m_ui.status->setText(QString::fromStdString(err_str));
7171
}
7272

73-
m_thread.reset();
73+
delete m_thread;
74+
m_thread = nullptr;
7475
}
7576

7677
updateEnabled();
@@ -103,12 +104,12 @@ void CoverDownloadWindow::updateEnabled()
103104

104105
void CoverDownloadWindow::startThread()
105106
{
106-
m_thread =
107-
std::make_unique<CoverDownloadThread>(this, m_ui.urls->toPlainText(), m_ui.useSerialFileNames->isChecked());
107+
m_thread = new CoverDownloadThread(m_ui.urls->toPlainText(), m_ui.useSerialFileNames->isChecked());
108108
m_last_refresh_time.Reset();
109-
connect(m_thread.get(), &CoverDownloadThread::statusUpdated, this, &CoverDownloadWindow::onDownloadStatus);
110-
connect(m_thread.get(), &CoverDownloadThread::progressUpdated, this, &CoverDownloadWindow::onDownloadProgress);
111-
connect(m_thread.get(), &CoverDownloadThread::threadFinished, this, &CoverDownloadWindow::onDownloadComplete);
109+
m_thread->moveToThread(m_thread);
110+
connect(m_thread, &CoverDownloadThread::statusUpdated, this, &CoverDownloadWindow::onDownloadStatus);
111+
connect(m_thread, &CoverDownloadThread::progressUpdated, this, &CoverDownloadWindow::onDownloadProgress);
112+
connect(m_thread, &CoverDownloadThread::threadFinished, this, &CoverDownloadWindow::onDownloadComplete);
112113
m_thread->start();
113114
updateEnabled();
114115
}
@@ -119,20 +120,49 @@ void CoverDownloadWindow::cancelThread()
119120
return;
120121

121122
m_thread->requestInterruption();
122-
m_thread->join();
123-
m_thread.reset();
123+
m_thread->wait();
124+
delete m_thread;
125+
m_thread = nullptr;
124126
}
125127

126-
CoverDownloadWindow::CoverDownloadThread::CoverDownloadThread(QWidget* parent, const QString& urls, bool use_serials)
127-
: QtAsyncProgressThread(parent), m_use_serials(use_serials)
128+
CoverDownloadThread::CoverDownloadThread(const QString& urls, bool use_serials) : QThread(), m_use_serials(use_serials)
128129
{
129130
for (const QString& str : urls.split(QChar('\n')))
130131
m_urls.push_back(str.toStdString());
131132
}
132133

133-
CoverDownloadWindow::CoverDownloadThread::~CoverDownloadThread() = default;
134+
CoverDownloadThread::~CoverDownloadThread() = default;
134135

135-
void CoverDownloadWindow::CoverDownloadThread::runAsync()
136+
bool CoverDownloadThread::IsCancelled() const
136137
{
137-
m_result = GameList::DownloadCovers(m_urls, m_use_serials, this, &m_error);
138+
return isInterruptionRequested();
139+
}
140+
141+
void CoverDownloadThread::SetTitle(const std::string_view title)
142+
{
143+
emit titleUpdated(QtUtils::StringViewToQString(title));
144+
}
145+
146+
void CoverDownloadThread::SetStatusText(const std::string_view text)
147+
{
148+
ProgressCallback::SetStatusText(text);
149+
emit statusUpdated(QtUtils::StringViewToQString(text));
150+
}
151+
152+
void CoverDownloadThread::SetProgressRange(u32 range)
153+
{
154+
ProgressCallback::SetProgressRange(range);
155+
emit progressUpdated(static_cast<int>(m_progress_value), static_cast<int>(m_progress_range));
156+
}
157+
158+
void CoverDownloadThread::SetProgressValue(u32 value)
159+
{
160+
ProgressCallback::SetProgressValue(value);
161+
emit progressUpdated(static_cast<int>(m_progress_value), static_cast<int>(m_progress_range));
162+
}
163+
164+
void CoverDownloadThread::run()
165+
{
166+
m_result = GameList::DownloadCovers(m_urls, m_use_serials, static_cast<ProgressCallback*>(this), &m_error);
167+
emit threadFinished();
138168
}

src/duckstation-qt/coverdownloadwindow.h

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33

44
#pragma once
55

6-
#include "qtprogresscallback.h"
76
#include "ui_coverdownloadwindow.h"
87

98
#include "common/error.h"
9+
#include "common/progress_callback.h"
1010
#include "common/timer.h"
1111
#include "common/types.h"
1212

@@ -16,6 +16,8 @@
1616
#include <memory>
1717
#include <string>
1818

19+
class CoverDownloadThread;
20+
1921
class CoverDownloadWindow final : public QWidget
2022
{
2123
Q_OBJECT
@@ -32,25 +34,6 @@ class CoverDownloadWindow final : public QWidget
3234
void closeEvent(QCloseEvent* ev) override;
3335

3436
private:
35-
class CoverDownloadThread : public QtAsyncProgressThread
36-
{
37-
public:
38-
CoverDownloadThread(QWidget* parent, const QString& urls, bool use_serials);
39-
~CoverDownloadThread();
40-
41-
ALWAYS_INLINE const Error& getError() const { return m_error; }
42-
ALWAYS_INLINE bool getResult() const { return m_result; }
43-
44-
protected:
45-
void runAsync() override;
46-
47-
private:
48-
std::vector<std::string> m_urls;
49-
Error m_error;
50-
bool m_use_serials = false;
51-
bool m_result = false;
52-
};
53-
5437
void startThread();
5538
void cancelThread();
5639

@@ -62,6 +45,39 @@ class CoverDownloadWindow final : public QWidget
6245
void updateEnabled();
6346

6447
Ui::CoverDownloadWindow m_ui;
65-
std::unique_ptr<CoverDownloadThread> m_thread;
48+
CoverDownloadThread* m_thread = nullptr;
6649
Timer m_last_refresh_time;
6750
};
51+
52+
class CoverDownloadThread final : public QThread, private ProgressCallback
53+
{
54+
Q_OBJECT
55+
56+
public:
57+
CoverDownloadThread(const QString& urls, bool use_serials);
58+
~CoverDownloadThread();
59+
60+
ALWAYS_INLINE const Error& getError() const { return m_error; }
61+
ALWAYS_INLINE bool getResult() const { return m_result; }
62+
63+
Q_SIGNALS:
64+
void titleUpdated(const QString& title);
65+
void statusUpdated(const QString& status);
66+
void progressUpdated(int value, int range);
67+
void threadFinished();
68+
69+
protected:
70+
void run() override;
71+
72+
bool IsCancelled() const override;
73+
void SetTitle(const std::string_view title) override;
74+
void SetStatusText(const std::string_view text) override;
75+
void SetProgressRange(u32 range) override;
76+
void SetProgressValue(u32 value) override;
77+
78+
private:
79+
std::vector<std::string> m_urls;
80+
Error m_error;
81+
bool m_use_serials = false;
82+
bool m_result = false;
83+
};

src/duckstation-qt/qtprogresscallback.cpp

Lines changed: 13 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ void QtModalProgressCallback::checkForDelayedShow()
9696
if (m_show_timer.GetTimeSeconds() >= m_show_delay)
9797
MakeVisible();
9898
}
99+
99100
void QtModalProgressCallback::MakeVisible()
100101
{
101102
m_dialog.setRange(0, m_progress_range);
@@ -106,79 +107,6 @@ void QtModalProgressCallback::MakeVisible()
106107
m_dialog.show();
107108
}
108109

109-
// NOTE: We deliberately don't set the thread parent, because otherwise we can't move it.
110-
QtAsyncProgressThread::QtAsyncProgressThread(QWidget* parent) : QThread()
111-
{
112-
}
113-
114-
QtAsyncProgressThread::~QtAsyncProgressThread() = default;
115-
116-
bool QtAsyncProgressThread::IsCancelled() const
117-
{
118-
return isInterruptionRequested();
119-
}
120-
121-
void QtAsyncProgressThread::SetCancellable(bool cancellable)
122-
{
123-
if (m_cancellable == cancellable)
124-
return;
125-
126-
ProgressCallback::SetCancellable(cancellable);
127-
}
128-
129-
void QtAsyncProgressThread::SetTitle(const std::string_view title)
130-
{
131-
emit titleUpdated(QtUtils::StringViewToQString(title));
132-
}
133-
134-
void QtAsyncProgressThread::SetStatusText(const std::string_view text)
135-
{
136-
ProgressCallback::SetStatusText(text);
137-
emit statusUpdated(QtUtils::StringViewToQString(text));
138-
}
139-
140-
void QtAsyncProgressThread::SetProgressRange(u32 range)
141-
{
142-
ProgressCallback::SetProgressRange(range);
143-
emit progressUpdated(static_cast<int>(m_progress_value), static_cast<int>(m_progress_range));
144-
}
145-
146-
void QtAsyncProgressThread::SetProgressValue(u32 value)
147-
{
148-
ProgressCallback::SetProgressValue(value);
149-
emit progressUpdated(static_cast<int>(m_progress_value), static_cast<int>(m_progress_range));
150-
}
151-
152-
void QtAsyncProgressThread::start()
153-
{
154-
Assert(!isRunning());
155-
156-
QThread::start();
157-
moveToThread(this);
158-
m_starting_thread = QThread::currentThread();
159-
m_start_semaphore.release();
160-
}
161-
162-
void QtAsyncProgressThread::join()
163-
{
164-
if (isRunning())
165-
QThread::wait();
166-
}
167-
168-
void QtAsyncProgressThread::run()
169-
{
170-
m_start_semaphore.acquire();
171-
emit threadStarting();
172-
runAsync();
173-
emit threadFinished();
174-
moveToThread(m_starting_thread);
175-
}
176-
177-
QWidget* QtAsyncProgressThread::parentWidget() const
178-
{
179-
return qobject_cast<QWidget*>(parent());
180-
}
181-
182110
QtAsyncTaskWithProgress::QtAsyncTaskWithProgress(const QString& initial_title, const QString& initial_status_text,
183111
bool cancellable, int range, int value, float show_delay,
184112
QWidget* dialog_parent, WorkCallback callback)
@@ -266,9 +194,9 @@ void QtAsyncTaskWithProgress::ProgressDialog::cancelled()
266194
m_task.m_ts_cancelled.store(true, std::memory_order_release);
267195
}
268196

269-
void QtAsyncTaskWithProgress::create(QWidget* parent, std::string_view initial_title,
270-
std::string_view initial_status_text, bool cancellable, int range, int value,
271-
float show_delay, WorkCallback callback)
197+
QtAsyncTaskWithProgress* QtAsyncTaskWithProgress::create(QWidget* parent, std::string_view initial_title,
198+
std::string_view initial_status_text, bool cancellable,
199+
int range, int value, float show_delay, WorkCallback callback)
272200
{
273201
DebugAssert(parent);
274202

@@ -286,11 +214,18 @@ void QtAsyncTaskWithProgress::create(QWidget* parent, std::string_view initial_t
286214
delete task;
287215
});
288216
});
217+
218+
return task;
219+
}
220+
221+
QtAsyncTaskWithProgress* QtAsyncTaskWithProgress::create(QWidget* parent, float show_delay, WorkCallback callback)
222+
{
223+
return create(parent, {}, {}, false, 0, 1, show_delay, std::move(callback));
289224
}
290225

291-
void QtAsyncTaskWithProgress::create(QWidget* parent, float show_delay, WorkCallback callback)
226+
void QtAsyncTaskWithProgress::cancel()
292227
{
293-
create(parent, {}, {}, false, 0, 1, show_delay, std::move(callback));
228+
m_ts_cancelled.store(true, std::memory_order_release);
294229
}
295230

296231
bool QtAsyncTaskWithProgress::IsCancelled() const

src/duckstation-qt/qtprogresscallback.h

Lines changed: 8 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -50,43 +50,6 @@ class QtModalProgressCallback final : public QObject, public ProgressCallback
5050
float m_show_delay;
5151
};
5252

53-
class QtAsyncProgressThread : public QThread, public ProgressCallback
54-
{
55-
Q_OBJECT
56-
57-
public:
58-
explicit QtAsyncProgressThread(QWidget* parent);
59-
~QtAsyncProgressThread();
60-
61-
bool IsCancelled() const override;
62-
63-
void SetCancellable(bool cancellable) override;
64-
void SetTitle(const std::string_view title) override;
65-
void SetStatusText(const std::string_view text) override;
66-
void SetProgressRange(u32 range) override;
67-
void SetProgressValue(u32 value) override;
68-
69-
void start();
70-
void join();
71-
72-
Q_SIGNALS:
73-
void titleUpdated(const QString& title);
74-
void statusUpdated(const QString& status);
75-
void progressUpdated(int value, int range);
76-
void threadStarting();
77-
void threadFinished();
78-
79-
protected:
80-
virtual void runAsync() = 0;
81-
void run() final;
82-
83-
private:
84-
QWidget* parentWidget() const;
85-
86-
QSemaphore m_start_semaphore;
87-
QThread* m_starting_thread = nullptr;
88-
};
89-
9053
class QtAsyncTaskWithProgress final : public QObject, private ProgressCallback
9154
{
9255
Q_OBJECT
@@ -95,11 +58,14 @@ class QtAsyncTaskWithProgress final : public QObject, private ProgressCallback
9558
using CompletionCallback = std::function<void()>;
9659
using WorkCallback = std::function<CompletionCallback(ProgressCallback*)>;
9760

98-
~QtAsyncTaskWithProgress();
61+
static QtAsyncTaskWithProgress* create(QWidget* parent, std::string_view initial_title,
62+
std::string_view initial_status_text, bool cancellable, int range, int value,
63+
float show_delay, WorkCallback callback);
64+
static QtAsyncTaskWithProgress* create(QWidget* parent, float show_delay, WorkCallback callback);
9965

100-
static void create(QWidget* parent, std::string_view initial_title, std::string_view initial_status_text,
101-
bool cancellable, int range, int value, float show_delay, WorkCallback callback);
102-
static void create(QWidget* parent, float show_delay, WorkCallback callback);
66+
/// Asynchronously cancel the task. Should only be called from the UI thread.
67+
/// There is no guarantee when the cancel will go through.
68+
void cancel();
10369

10470
Q_SIGNALS:
10571
void completed(QtAsyncTaskWithProgress* self);
@@ -138,6 +104,7 @@ class QtAsyncTaskWithProgress final : public QObject, private ProgressCallback
138104
// constructor hidden, clients should not be creating this directly
139105
QtAsyncTaskWithProgress(const QString& initial_title, const QString& initial_status_text, bool cancellable, int range,
140106
int value, float show_delay, QWidget* dialog_parent, WorkCallback callback);
107+
~QtAsyncTaskWithProgress();
141108

142109
// progress callback overrides
143110
bool IsCancelled() const override;

0 commit comments

Comments
 (0)