diff --git a/apps/Launcher/syncwidget.cpp b/apps/Launcher/syncwidget.cpp index 1947dacd03..f02363257b 100644 --- a/apps/Launcher/syncwidget.cpp +++ b/apps/Launcher/syncwidget.cpp @@ -131,6 +131,8 @@ SyncWidget::SyncWidget(QWidget* parent, Qt::WindowFlags f) QTimer* timer = new QTimer(this); QObject::connect(timer, SIGNAL(timeout()), this, SLOT(handleTimer())); timer->start(100); + + _mutex.clear(); } SyncWidget::~SyncWidget() { @@ -205,23 +207,30 @@ void SyncWidget::handleFileRequest() { std::string identifier = f.identifier.toStdString(); std::string path = absPath("${SCENE}/" + f.module.toStdString() + "/" + f.destination.toStdString()); int version = f.version; - std::vector futures = - DlManager.downloadRequestFiles( + + DlManager.downloadRequestFilesAsync( identifier, path, version, - OverwriteFiles - ); + OverwriteFiles, + std::bind(&SyncWidget::handleFileFutureAddition, this, std::placeholders::_1) + ); - _futures.insert(_futures.end(), futures.begin(), futures.end()); - for (openspace::DownloadManager::FileFuture* f : futures) { - InfoWidget* w = new InfoWidget(QString::fromStdString(f->filePath), -1); - _downloadLayout->addWidget(w); + //std::vector futures = + // DlManager.downloadRequestFiles( + // identifier, + // path, + // version, + // OverwriteFiles + // ); - _futureInfoWidgetMap[f] = w; - } + //_futures.insert(_futures.end(), futures.begin(), futures.end()); + //for (openspace::DownloadManager::FileFuture* f : futures) { + // InfoWidget* w = new InfoWidget(QString::fromStdString(f->filePath), -1); + // _downloadLayout->addWidget(w); - qApp->processEvents(); + // _futureInfoWidgetMap[f] = w; + //} } } @@ -271,7 +280,6 @@ void SyncWidget::handleTorrentFiles() { _torrentInfoWidgetMap[h] = w; FileSys.setCurrentDirectory(d); - qApp->processEvents(); } } @@ -494,6 +502,18 @@ void SyncWidget::handleTimer() { delete f; } + while (_mutex.test_and_set()) {} + for (openspace::DownloadManager::FileFuture* f : _futuresToAdd) { + InfoWidget* w = new InfoWidget(QString::fromStdString(f->filePath), -1); + _downloadLayout->addWidget(w); + + _futureInfoWidgetMap[f] = w; + _futures.push_back(f); + } + _futuresToAdd.clear(); + _mutex.clear(); + + std::vector handles = _session->get_torrents(); for (torrent_handle h : handles) { torrent_status s = h.status(); @@ -570,3 +590,19 @@ void SyncWidget::handleTimer() { // qDebug() << ""; } + +void SyncWidget::handleFileFutureAddition( + const std::vector& futures) +{ + while (_mutex.test_and_set()) {} + _futuresToAdd.insert(_futuresToAdd.end(), futures.begin(), futures.end()); + _mutex.clear(); + //_futures.insert(_futures.end(), futures.begin(), futures.end()); + //for (openspace::DownloadManager::FileFuture* f : futures) { + // InfoWidget* w = new InfoWidget(QString::fromStdString(f->filePath), -1); + // _downloadLayout->addWidget(w); + + // _futureInfoWidgetMap[f] = w; + //} + +} diff --git a/apps/Launcher/syncwidget.h b/apps/Launcher/syncwidget.h index c8c856c04b..e1e560b021 100644 --- a/apps/Launcher/syncwidget.h +++ b/apps/Launcher/syncwidget.h @@ -33,6 +33,7 @@ #include +#include //#include class QBoxLayout; @@ -80,6 +81,8 @@ private: void clear(); QStringList selectedScenes() const; + void handleFileFutureAddition(const std::vector& futures); + void handleDirectFiles(); void handleFileRequest(); void handleTorrentFiles(); @@ -98,6 +101,9 @@ private: std::vector _futures; std::map _futureInfoWidgetMap; + + std::vector _futuresToAdd; + std::atomic_flag _mutex; }; #endif // __SYNCWIDGET_H__ diff --git a/include/openspace/engine/downloadmanager.h b/include/openspace/engine/downloadmanager.h index b17fc2ede5..4e61136bd9 100644 --- a/include/openspace/engine/downloadmanager.h +++ b/include/openspace/engine/downloadmanager.h @@ -58,10 +58,12 @@ public: typedef std::function DownloadProgressCallback; typedef std::function DownloadFinishedCallback; + typedef std::function&)> AsyncDownloadFinishedCallback; DownloadManager(std::string requestURL, int applicationVersion); // callers responsibility to delete + // callbacks happen on a different thread FileFuture* downloadFile( const std::string& url, const ghoul::filesystem::File& file, @@ -82,6 +84,14 @@ public: // TODO: Add async version of downloadRequestFiles that returns a filefuture // that can be used to call an additional function + void downloadRequestFilesAsync( + const std::string& identifier, + const ghoul::filesystem::Directory& destination, + int version, + bool overrideFiles, + AsyncDownloadFinishedCallback callback + ); + private: std::string _requestURL; int _applicationVersion; diff --git a/src/engine/downloadmanager.cpp b/src/engine/downloadmanager.cpp index 5e6e06584a..edddf7a027 100644 --- a/src/engine/downloadmanager.cpp +++ b/src/engine/downloadmanager.cpp @@ -226,4 +226,24 @@ std::vector DownloadManager::downloadRequestFiles( return futures; } +void DownloadManager::downloadRequestFilesAsync( + const std::string& identifier, + const ghoul::filesystem::Directory& destination, + int version, + bool overrideFiles, + AsyncDownloadFinishedCallback callback) +{ + std::thread([this, identifier, destination, version, overrideFiles, callback](){ + std::vector f = downloadRequestFiles( + identifier, + destination, + version, + overrideFiles + ); + + callback(f); + }).detach(); + +} + } // namespace openspace