From 4d6663f824767248db024643fb8ce1fded6df034 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 18 Jun 2015 22:46:24 +0200 Subject: [PATCH] Add a time-remaining counter to Launcher --- apps/Launcher/infowidget.cpp | 19 +++++++++++++ apps/Launcher/infowidget.h | 4 +++ apps/Launcher/syncwidget.cpp | 29 ++++--------------- include/openspace/engine/downloadmanager.h | 4 ++- src/engine/downloadmanager.cpp | 33 ++++++++++++++-------- 5 files changed, 52 insertions(+), 37 deletions(-) diff --git a/apps/Launcher/infowidget.cpp b/apps/Launcher/infowidget.cpp index d15fc1d506..9ddc547912 100644 --- a/apps/Launcher/infowidget.cpp +++ b/apps/Launcher/infowidget.cpp @@ -24,6 +24,8 @@ #include "infowidget.h" +#include "syncwidget.h" + #include #include #include @@ -73,6 +75,23 @@ void InfoWidget::update(float progress) { _progress->setValue(static_cast(progress * 100)); } +void InfoWidget::update(openspace::DownloadManager::FileFuture* f) { + _bytes->setText( + QString("%1 / %2") + .arg(f->currentSize) + .arg(f->totalSize) + ); + _progress->setValue(static_cast(f->progress * 100)); + + if (f->errorMessage.empty()) { + QString t = "Time remaining %1 s"; + _messages->setText(t.arg(f->secondsRemaining)); + } + else { + _messages->setText(QString::fromStdString(f->errorMessage)); + } +} + void InfoWidget::error(QString message) { _messages->setText(message); } diff --git a/apps/Launcher/infowidget.h b/apps/Launcher/infowidget.h index 7f7f1d086d..ea968194df 100644 --- a/apps/Launcher/infowidget.h +++ b/apps/Launcher/infowidget.h @@ -27,6 +27,8 @@ #include +#include + class QLabel; class QProgressBar; @@ -38,6 +40,8 @@ public: void update(int currentBytes); void update(float progress); + void update(openspace::DownloadManager::FileFuture* f); + void error(QString message); private: diff --git a/apps/Launcher/syncwidget.cpp b/apps/Launcher/syncwidget.cpp index 5bae7dadae..32d126857c 100644 --- a/apps/Launcher/syncwidget.cpp +++ b/apps/Launcher/syncwidget.cpp @@ -68,9 +68,8 @@ namespace { const std::string IdentifierKey = "Identifier"; const std::string VersionKey = "Version"; - const QString DefaultSceneName = "default.scene"; - const bool OverwriteFiles = true; + const bool CleanInfoWidgets = false; } SyncWidget::SyncWidget(QWidget* parent, Qt::WindowFlags f) @@ -107,23 +106,6 @@ SyncWidget::SyncWidget(QWidget* parent, Qt::WindowFlags f) _downloadLayout = new QVBoxLayout(w); _downloadLayout->addStretch(100); - - - //QGroupBox* downloadBox = new QGroupBox; - - //QWidget* - - //_downloadLayout = new QVBoxLayout(area); - //area->setWidget(_downloadLayout) - - - - ////downloadBox->setMinimumSize(450, 1000); - //downloadBox->setLayout(_downloadLayout); - - //QScrollArea* area = new QScrollArea; - //area->setWidget(downloadBox); - layout->addWidget(area); } @@ -167,8 +149,7 @@ void SyncWidget::setSceneFiles(QMap sceneFiles) { QCheckBox* checkbox = new QCheckBox(sceneName); - if (sceneName == DefaultSceneName) - checkbox->setChecked(true); + checkbox->setChecked(true); _sceneLayout->addWidget(checkbox, i / nColumns, i % nColumns); } @@ -484,14 +465,14 @@ void SyncWidget::handleTimer() { for (FileFuture* f : _futures) { InfoWidget* w = _futureInfoWidgetMap[f]; - if (f->isFinished || f->isAborted) { + if (CleanInfoWidgets && (f->isFinished || f->isAborted)) { toRemove.push_back(f); _downloadLayout->removeWidget(w); _futureInfoWidgetMap.erase(f); delete w; } else - w->update(f->progress); + w->update(f); } for (FileFuture* f : toRemove) { @@ -519,7 +500,7 @@ void SyncWidget::handleTimer() { if (w) w->update(static_cast(s.total_wanted_done)); - if (s.state == torrent_status::finished || s.state == torrent_status::seeding) { + if (CleanInfoWidgets && (s.state == torrent_status::finished || s.state == torrent_status::seeding)) { _torrentInfoWidgetMap.remove(h); delete w; } diff --git a/include/openspace/engine/downloadmanager.h b/include/openspace/engine/downloadmanager.h index 7aeb3f32ed..1cb8a9d751 100644 --- a/include/openspace/engine/downloadmanager.h +++ b/include/openspace/engine/downloadmanager.h @@ -45,12 +45,14 @@ public: FileFuture(std::string file); // Values that are written by the DownloadManager to be consumed by others + long long currentSize; long long totalSize; float progress; // [0,1] + float secondsRemaining; bool isFinished; + bool isAborted; std::string filePath; std::string errorMessage; - bool isAborted; // Values set by others to be consumed by the DownloadManager bool abortDownload; diff --git a/src/engine/downloadmanager.cpp b/src/engine/downloadmanager.cpp index edddf7a027..0b07b72116 100644 --- a/src/engine/downloadmanager.cpp +++ b/src/engine/downloadmanager.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -45,10 +46,10 @@ namespace { struct ProgressInformation { CURL* curl; openspace::DownloadManager::FileFuture* future; + std::chrono::system_clock::time_point startTime; const openspace::DownloadManager::DownloadProgressCallback* callback; }; - size_t writeData(void* ptr, size_t size, size_t nmemb, FILE* stream) { size_t written; written = fwrite(ptr, size, nmemb, stream); @@ -75,23 +76,28 @@ namespace { return 1; } + i->future->currentSize = dlnow; i->future->totalSize = dltotal; i->future->progress = static_cast(dlnow) / static_cast(dltotal); + auto now = std::chrono::system_clock::now(); + + // Compute time spent transferring. + auto transferTime = now - i->startTime; + // Compute estimated transfer time. + auto estimatedTime = transferTime / i->future->progress; + // Compute estimated time remaining. + auto timeRemaining = estimatedTime - transferTime; + + float s = std::chrono::duration_cast(timeRemaining).count(); + + i->future->secondsRemaining = s; + if (*(i->callback)) { // The callback function is a pointer to an std::function; that is the reason // for the excessive referencing (*(i->callback))(*(i->future)); } - - - //CURL* curl = myp->curl; - //double curtime = 0; - //curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &curtime); - //fprintf(stderr, "UP: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T - // " DOWN: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T - // "\r\n", - // ulnow, ultotal, dlnow, dltotal); return 0; } @@ -100,12 +106,14 @@ namespace { namespace openspace { DownloadManager::FileFuture::FileFuture(std::string file) - : totalSize(-1) + : currentSize(-1) + , totalSize(-1) , progress(0.f) + , secondsRemaining(-1.f) , isFinished(false) + , isAborted(false) , filePath(std::move(file)) , errorMessage("") - , isAborted(false) , abortDownload(false) {} @@ -146,6 +154,7 @@ DownloadManager::FileFuture* DownloadManager::downloadFile( ProgressInformation p = { curl, future, + std::chrono::system_clock::now(), &progressCallback }; curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferinfo);