DownloadController.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <DownloadController.h>
  9. #include <DownloadWorker.h>
  10. #include <PythonBindings.h>
  11. #include <AzCore/std/ranges/ranges_algorithm.h>
  12. #include <QMessageBox>
  13. namespace O3DE::ProjectManager
  14. {
  15. DownloadController::DownloadController(QWidget* parent)
  16. : QObject(parent)
  17. {
  18. m_worker = new DownloadWorker();
  19. m_worker->moveToThread(&m_workerThread);
  20. connect(&m_workerThread, &QThread::started, m_worker, &DownloadWorker::StartDownload);
  21. connect(m_worker, &DownloadWorker::Done, this, &DownloadController::HandleResults);
  22. connect(m_worker, &DownloadWorker::UpdateProgress, this, &DownloadController::UpdateUIProgress);
  23. connect(this, &DownloadController::StartObjectDownload, m_worker, &DownloadWorker::SetObjectToDownload);
  24. }
  25. DownloadController::~DownloadController()
  26. {
  27. connect(&m_workerThread, &QThread::finished, m_worker, &DownloadController::deleteLater);
  28. m_workerThread.requestInterruption();
  29. m_workerThread.quit();
  30. m_workerThread.wait();
  31. }
  32. void DownloadController::AddObjectDownload(const QString& objectName, const QString& destinationPath, DownloadObjectType objectType)
  33. {
  34. m_objects.push_back({ objectName, destinationPath, objectType });
  35. emit ObjectDownloadAdded(objectName, objectType);
  36. if (m_objects.size() == 1)
  37. {
  38. m_worker->SetObjectToDownload(m_objects.front().m_objectName, destinationPath, objectType, false);
  39. m_workerThread.start();
  40. }
  41. }
  42. bool DownloadController::IsDownloadingObject(const QString& objectName, DownloadObjectType objectType)
  43. {
  44. auto findResult = AZStd::ranges::find_if(m_objects,
  45. [objectName, objectType](const DownloadableObject& object)
  46. {
  47. return (object.m_objectType == objectType && object.m_objectName == objectName);
  48. });
  49. return findResult != m_objects.end();
  50. }
  51. void DownloadController::CancelObjectDownload(const QString& objectName, DownloadObjectType objectType)
  52. {
  53. auto findResult = AZStd::ranges::find_if(m_objects,
  54. [objectName, objectType](const DownloadableObject& object)
  55. {
  56. return (object.m_objectType == objectType && object.m_objectName == objectName);
  57. });
  58. if (findResult != m_objects.end())
  59. {
  60. if (findResult == m_objects.begin())
  61. {
  62. // HandleResults will remove the object upon cancelling
  63. PythonBindingsInterface::Get()->CancelDownload();
  64. }
  65. else
  66. {
  67. m_objects.erase(findResult);
  68. emit ObjectDownloadRemoved(objectName, objectType);
  69. }
  70. }
  71. }
  72. void DownloadController::UpdateUIProgress(int bytesDownloaded, int totalBytes)
  73. {
  74. if (!m_objects.empty())
  75. {
  76. const DownloadableObject& downloadableObject = m_objects.front();
  77. emit ObjectDownloadProgress(downloadableObject.m_objectName, downloadableObject.m_objectType, bytesDownloaded, totalBytes);
  78. }
  79. }
  80. void DownloadController::HandleResults(const QString& result, const QString& detailedError)
  81. {
  82. bool succeeded = true;
  83. if (!result.isEmpty())
  84. {
  85. if (!detailedError.isEmpty())
  86. {
  87. QMessageBox downloadError;
  88. downloadError.setIcon(QMessageBox::Critical);
  89. downloadError.setWindowTitle(tr("Download failed"));
  90. downloadError.setText(result);
  91. downloadError.setDetailedText(detailedError);
  92. downloadError.exec();
  93. }
  94. else
  95. {
  96. QMessageBox::critical(nullptr, tr("Download failed"), result);
  97. }
  98. succeeded = false;
  99. }
  100. if (!m_objects.empty())
  101. {
  102. DownloadableObject downloadableObject = m_objects.front();
  103. m_objects.erase(m_objects.begin());
  104. emit Done(downloadableObject.m_objectName, succeeded);
  105. emit ObjectDownloadRemoved(downloadableObject.m_objectName, downloadableObject.m_objectType);
  106. }
  107. if (!m_objects.empty())
  108. {
  109. const DownloadableObject& nextObject = m_objects.front();
  110. emit StartObjectDownload(nextObject.m_objectName, nextObject.m_destinationPath, nextObject.m_objectType, true);
  111. }
  112. else
  113. {
  114. m_workerThread.quit();
  115. m_workerThread.wait();
  116. }
  117. }
  118. } // namespace O3DE::ProjectManager