Forráskód Böngészése

Added progress signals and concurrent download in PatchDownloader

Ivan Arkhipov 4 éve
szülő
commit
d697ad7cb3
2 módosított fájl, 62 hozzáadás és 17 törlés
  1. 50 16
      src/Legacy/models/patchdownloader.cpp
  2. 12 1
      src/Legacy/models/patchdownloader.h

+ 50 - 16
src/Legacy/models/patchdownloader.cpp

@@ -6,7 +6,11 @@
 
 void PatchDownloader::init() {
     for (const QString& patch: patches_) {
-        patch_downloaders_[patch] = new Downloader(this);
+        Downloader* patch_downloader = new Downloader(this);
+        patch_downloaders_[patch] = patch_downloader;
+        patch_downloaders_status_[patch_downloader] = Downloader::Status();
+        QObject::connect(patch_downloader, &Downloader::progressChanged, this, &PatchDownloader::onDownloaderProgressChanged);
+        QObject::connect(patch_downloader, &Downloader::downloadFinished, this, &PatchDownloader::onDownloaderFinished);
     }
 }
 
@@ -22,12 +26,46 @@ PatchDownloader::PatchDownloader() {
 }
 
 void PatchDownloader::startPatchDownloaderChain() {
+    if (started_) {
+        qCritical() << "PatchDwnlder: Tried to start patch downloader chain while other was already running!";
+    }
+    started_ = true;
+    emit started();
     checkForUpdates();
-    download();
+    beginDownload();
+    // Finished signal will be emitted when all downloads are completed.
+    // Note, this function finishes immediately after downloads are STARTED!
+}
+
+void PatchDownloader::onDownloaderProgressChanged(Downloader* context, Downloader::Status progress) {
+    patch_downloaders_status_[context] = progress;
+
+    Downloader::Status cumulative_status;
+    for (const Downloader::Status& status: patch_downloaders_status_.values()) {
+        cumulative_status = cumulative_status + status;
+    }
+    emit progressChanged(cumulative_status);
+}
+
+void PatchDownloader::onDownloaderFinished(Downloader* context) {
+    context->targetFile->close();
+    context->targetFile->deleteLater();
+    context->targetFile = nullptr;
+    Settings::setValue("DatabaseNeedInstall/" + patch_downloaders_.key(context), true);
+
+    Downloader::Status cumulative_status;
+    for (const Downloader::Status& status: patch_downloaders_status_.values()) {
+        cumulative_status = cumulative_status + status;
+    }
+
+    if (!cumulative_status.running) {
+        started_ = false;
+        emit finished();
+    }
 }
 
 void PatchDownloader::checkForUpdates() {
-    qDebug() << "CHECKING FOR UPDATES!";
+    qDebug() << __FUNCTION__ << "Started check for updates!";
     QUrlQuery query; // query for building GET-request aka patch-version
 
     for (const QString& patch: patches_) {
@@ -46,10 +84,10 @@ void PatchDownloader::checkForUpdates() {
     downloader.waitForDownloaded();
 
     if (target_array.isEmpty()) {
-        qWarning() << "PatchDwnlder: Cannot check for updates, target_array is empty!";
+        qWarning() << __FUNCTION__ << "Cannot check for updates, target_array is empty!";
         return;
     }
-    qDebug() << "CHECK FOR UPDATES RESULT: " << target_array;
+    qDebug() << __FUNCTION__ << "Check for updates result: " << target_array;
 
     QStringList patch_info = QString(target_array).split('|');
     if (patch_info.size() != patches_.size()) {
@@ -65,7 +103,7 @@ void PatchDownloader::checkForUpdates() {
             return;
         }
 
-        QString patch_filename = Settings::getValue("General/PatchDownloadDir").toString() + "/" + patch;
+        QString patch_filename = Settings::getValue("General/PatchDownloadDir").toString() + "/" + patch + ".db";
 
         Settings::setValue("PatchDatabases/" + patch + "/url", patch_data[0]);
         Settings::setValue("PatchDatabases/" + patch + "/hashsum", patch_data[1]);
@@ -74,12 +112,11 @@ void PatchDownloader::checkForUpdates() {
     }
 }
 
-void PatchDownloader::download() {
-    qDebug() << "STARTING PATCH DOWNLOAD";
+void PatchDownloader::beginDownload() {
     for (const QString& patch: patches_) {
         QString target_filename = Settings::getValue("PatchDatabases/" + patch + "/path").toString();
 
-        qDebug() << patch << ": Checking if there's need to download patch";
+        qDebug() << __FUNCTION__ << patch << ": Checking if there's need to download patch";
         if (!needDownloadDatabase(patch)) {
             qInfo() << patch << ": file " << target_filename << " is up-to-date, no need to download";
             continue;
@@ -88,23 +125,20 @@ void PatchDownloader::download() {
         FileSystem::createFilePath(target_filename);
         QFile* target_file = new QFile(target_filename);
         if (!target_file->open(QIODevice::ReadWrite | QIODevice::Truncate)) {
-            qWarning() << "PatchDwnlder" << patch << "Cannot open file " << target_filename;
+            qWarning() << __FUNCTION__ << patch << "Cannot open file " << target_filename;
             continue;
         }
 
-        qInfo() << "PatchDwnlder" << patch << ": beginning download of file " << target_filename;
+        qInfo() << __FUNCTION__ << patch << ": beginning download of file " << target_filename;
 
         patch_downloaders_[patch]->setUrl(Settings::getValue("PatchDatabases/" + patch + "/url").toUrl());
         patch_downloaders_[patch]->targetFile = target_file;
         patch_downloaders_[patch]->start();
-        patch_downloaders_[patch]->waitForDownloaded();
-        target_file->close();
-        target_file->deleteLater();
-        Settings::setValue("DatabaseNeedInstall/" + patch, true);
     }
-    qDebug() << "FINISHED PATCH DOWNLOAD";
 }
 
+
+
 bool PatchDownloader::needDownloadDatabase(QString db_name)
 {
     QString patch_filename = Settings::getValue("PatchDatabases/" + db_name + "/path").toString();

+ 12 - 1
src/Legacy/models/patchdownloader.h

@@ -24,15 +24,26 @@ public:
 private:
     PatchDownloader();
     void checkForUpdates();  // Checks for updates. Returns true, if there are new patch updates
-    void download();         // Downloads all necessary patches.
+    void beginDownload();         // Starts downloading all necessary patches.
     static bool needDownloadDatabase(QString db_name); // Checks if database needs to be downloaded (by checksum comparing)
 
 public slots:
     void startPatchDownloaderChain();
 
+signals:
+    void started();
+    void progressChanged(Downloader::Status status);
+    void finished();
+
+private slots:
+    void onDownloaderProgressChanged(Downloader* context, Downloader::Status progress);
+    void onDownloaderFinished(Downloader* context);
+
 private:
+    bool started_ = false;
     const QList<QString> patches_ = {"text", "font", "image", "texture", "loadscreen", "sound", "video"};
     QMap<QString, Downloader*> patch_downloaders_;
+    QMap<Downloader*, Downloader::Status> patch_downloaders_status_;
 };
 
 #endif // PATCHDOWNLOADER_H