From 13dc800e964567dbe87501574a2cb61c4db0f15c Mon Sep 17 00:00:00 2001 From: Ankush Dutt Date: Wed, 2 Aug 2023 15:15:46 +0530 Subject: [PATCH] BACKENDS: Implement interrupt/cancel pending DLC downloads --- backends/dlc/dlcmanager.cpp | 5 ++++- backends/dlc/dlcmanager.h | 2 ++ backends/dlc/scummvmcloud.cpp | 14 ++++++++++++++ gui/downloaddlcsdialog.cpp | 7 +++++-- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/backends/dlc/dlcmanager.cpp b/backends/dlc/dlcmanager.cpp index 8f09298cf8a..a331a5dc891 100644 --- a/backends/dlc/dlcmanager.cpp +++ b/backends/dlc/dlcmanager.cpp @@ -58,6 +58,7 @@ void DLCManager::refreshLauncherGameList() { void DLCManager::addDownload(uint32 idx) { _dlcs[idx]->state = DLCDesc::kInProgress; _queuedDownloadTasks.push(_dlcs[idx]); + _dlcsInProgress.push_back(_dlcs[idx]); if (!_isDLCDownloading) { // if queue is not already processing DLCManager::processDownloadQueue(); @@ -74,6 +75,7 @@ void DLCManager::processDownloadQueue() { } else { // state is already cancelled/downloaded -> skip download _queuedDownloadTasks.pop(); + _dlcsInProgress.remove_at(0); // process next download in the queue processDownloadQueue(); } @@ -89,8 +91,9 @@ void DLCManager::startDownloadAsync(const Common::String &id, const Common::Stri } bool DLCManager::cancelDownload(uint32 idx) { - if (_currentDownloadingDLC == _dlcs[idx]->id) { + if (_queuedDownloadTasks.front()->idx == idx) { // if already downloading, interrupt startDownloadAsync + _interruptCurrentDownload = true; } else { // if not started, skip it in processDownload() _dlcs[idx]->state = DLCDesc::kCancelled; diff --git a/backends/dlc/dlcmanager.h b/backends/dlc/dlcmanager.h index b5448b49214..20493cfc590 100644 --- a/backends/dlc/dlcmanager.h +++ b/backends/dlc/dlcmanager.h @@ -42,8 +42,10 @@ class DLCManager : public Common::Singleton, public GUI::CommandSend public: bool _fetchDLCs = false; + bool _interruptCurrentDownload = false; uint32 _currentDownloadedSize; Common::Array _dlcs; + Common::Array _dlcsInProgress; Common::Queue _queuedDownloadTasks; DLCManager(); diff --git a/backends/dlc/scummvmcloud.cpp b/backends/dlc/scummvmcloud.cpp index 1df9d3ad204..77da3d71347 100644 --- a/backends/dlc/scummvmcloud.cpp +++ b/backends/dlc/scummvmcloud.cpp @@ -91,6 +91,18 @@ void ScummVMCloud::getAllDLCs() { void ScummVMCloud::downloadFileCallback(Networking::DataResponse r) { Networking::SessionFileResponse *response = static_cast(r.value); DLCMan._currentDownloadedSize += response->len; + if (DLCMan._interruptCurrentDownload) { + _rq->close(); + DLCMan._interruptCurrentDownload = false; + // delete the download cache (the incomplete .zip) + Common::Path relativeFilePath = Common::Path(DLCMan._queuedDownloadTasks.front()->id); + removeCacheFile(relativeFilePath); + // handle next download + DLCMan._queuedDownloadTasks.front()->state = DLCDesc::kDownloaded; + DLCMan._queuedDownloadTasks.pop(); + DLCMan._dlcsInProgress.remove_at(0); + DLCMan.processDownloadQueue(); + } if (response->eos) { warning("downloaded"); _rq->close(); // delete request @@ -106,6 +118,7 @@ void ScummVMCloud::downloadFileCallback(Networking::DataResponse r) { // handle next download DLCMan._queuedDownloadTasks.front()->state = DLCDesc::kDownloaded; DLCMan._queuedDownloadTasks.pop(); + DLCMan._dlcsInProgress.remove_at(0); DLCMan.processDownloadQueue(); } } @@ -114,6 +127,7 @@ void ScummVMCloud::errorCallback(Networking::ErrorResponse error) { // error downloading - start next download in queue DLCMan._queuedDownloadTasks.front()->state = DLCDesc::kErrorDownloading; DLCMan._queuedDownloadTasks.pop(); + DLCMan._dlcsInProgress.remove_at(0); DLCMan.processDownloadQueue(); } diff --git a/gui/downloaddlcsdialog.cpp b/gui/downloaddlcsdialog.cpp index 0c980980f4b..51f34e8d0b2 100644 --- a/gui/downloaddlcsdialog.cpp +++ b/gui/downloaddlcsdialog.cpp @@ -84,9 +84,11 @@ void DownloadDLCsDialog::refreshWidgets() { _currentDownloadLabel->setLabel(DLCMan._queuedDownloadTasks.front()->name); _downloadedSizeLabel->setLabel(getSizeLabelText()); - for (auto it : DLCMan._dlcs) { + for (auto it : DLCMan._dlcsInProgress) { if (it->state == DLC::DLCDesc::kInProgress) { pendingList.push_back(it->name); + } else { + pendingList.push_back("[Cancelled] " + it->name); } } _pendingDownloadsList->setList(pendingList); @@ -127,7 +129,8 @@ void DownloadDLCsDialog::handleTickle() { void DownloadDLCsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { switch (cmd) { case kCancelSelectedCmd: { - // set state of selected DLC to kCancelled + uint32 idx = DLCMan._dlcsInProgress[_pendingDownloadsList->getSelected()]->idx; + DLCMan.cancelDownload(idx); } break; default: