Qt: Allow cancelling icon downloads

This commit is contained in:
Stenzek
2025-12-06 15:09:29 +10:00
parent 1541200903
commit 3867c848b0
4 changed files with 51 additions and 3 deletions

View File

@@ -2135,7 +2135,8 @@ bool Achievements::DownloadGameIcons(ProgressCallback* progress, Error* error)
rc_error_str(parse_result));
titles_response.reset();
}
});
},
progress);
rc_api_destroy_request(&request);
WaitForHTTPRequestsWithYield(lock);

View File

@@ -3294,8 +3294,8 @@ void MainWindow::onToolsCoverDownloaderTriggered()
void MainWindow::onToolsDownloadAchievementGameIconsTriggered()
{
QtAsyncTaskWithProgressDialog::create(
this, TRANSLATE_STR("GameListWidget", "Download Game Badges"),
TRANSLATE_STR("GameListWidget", "Downloading game badges..."), true, 0, 0, 0.0f, [](ProgressCallback* progress) {
this, TRANSLATE_STR("GameListWidget", "Download Game Icons"),
TRANSLATE_STR("GameListWidget", "Downloading game icons..."), true, 0, 0, 0.0f, [](ProgressCallback* progress) {
Error error;
const bool result = Achievements::DownloadGameIcons(progress, &error);
return [error = std::move(error), result]() {

View File

@@ -262,6 +262,52 @@ bool HTTPDownloader::HasAnyRequests()
return !m_pending_http_requests.empty();
}
void HTTPDownloader::CancelAllRequests()
{
std::unique_lock lock(m_pending_http_request_lock);
bool has_pending_requests = false;
do
{
has_pending_requests = false;
LockedPollRequests(lock);
for (size_t index = 0; index < m_pending_http_requests.size();)
{
Request* req = m_pending_http_requests[index];
const Request::State req_state = req->state.load(std::memory_order_acquire);
// can't cancel a request in pending stage
if (req_state == Request::State::Pending)
{
has_pending_requests = true;
index++;
continue;
}
else if (req_state == Request::State::Started || req_state == Request::State::Receiving)
{
// request timed out
ERROR_LOG("Request for '{}' cancelled", req->url);
req->state.store(Request::State::Cancelled, std::memory_order_release);
m_pending_http_requests.erase(m_pending_http_requests.begin() + index);
lock.unlock();
req->error.SetStringView("Request was cancelled.");
req->callback(HTTP_STATUS_CANCELLED, req->error, std::string(), Request::Data());
CloseRequest(req);
lock.lock();
continue;
}
index++;
}
} while (has_pending_requests);
}
std::string HTTPDownloader::GetExtensionForContentType(const std::string& content_type)
{
// Based on https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types

View File

@@ -80,6 +80,7 @@ public:
void WaitForAllRequests();
void WaitForAllRequestsWithYield(std::function<void()> before_sleep_cb, std::function<void()> after_sleep_cb);
bool HasAnyRequests();
void CancelAllRequests();
protected:
virtual Request* InternalCreateRequest() = 0;