reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

commit 7134b4e33e66ff7bed16e0cabacd9b2494b25331
parent 1870ab34a3c2ffad463dc8cd754a4d9a69aec059
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Mon, 14 Mar 2016 17:14:37 -0400

implement multiple index downloading

Diffstat:
Msrc/reapack.cpp | 135+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Msrc/reapack.hpp | 13+++++++++++--
2 files changed, 106 insertions(+), 42 deletions(-)

diff --git a/src/reapack.cpp b/src/reapack.cpp @@ -289,7 +289,7 @@ void ReaPack::about(const Remote &remote, HWND parent) if(remote.isNull()) return; - loadIndex(remote, [=] (IndexPtr index) { + fetchIndex(remote, [=] (IndexPtr index) { const auto ret = Dialog::Show<About>(m_instance, parent, index); if(ret == About::InstallResult) { @@ -300,75 +300,130 @@ void ReaPack::about(const Remote &remote, HWND parent) }, parent); } -void ReaPack::loadIndex(const Remote &remote, +void ReaPack::cleanupPackages() +{ + const vector<Remote> &remotes = m_config->remotes()->getEnabled(); + + fetchIndexes(remotes, [=] (const vector<IndexPtr> &indexes) { + printf("%zu indexes loaded\n", indexes.size()); + }); +} + +void ReaPack::fetchIndex(const Remote &remote, const IndexCallback &callback, HWND parent) { + fetchIndexes({remote}, [=] (const vector<IndexPtr> &indexes) { + callback(indexes.front()); + }, parent); +} + +void ReaPack::fetchIndexes(const vector<Remote> &remotes, + const IndexesCallback &callback, HWND parent) +{ if(!parent) parent = m_mainWindow; - const auto load = [=] { - try { - // callback is responsible of deleting the index after use - callback(Index::load(remote.name())); - } - catch(const reapack_error &e) { - const auto_string &desc = make_autostring(e.what()); + DownloadQueue *queue = new DownloadQueue; + Dialog *progress = Dialog::Create<Progress>(m_instance, m_mainWindow, queue); - auto_char msg[512] = {}; - auto_snprintf(msg, sizeof(msg), - AUTO_STR("ReaPack could not read %s's index.\n\n") + auto load = [=] { + Dialog::Destroy(progress); + delete queue; - AUTO_STR("Synchronize your packages and try again.\n") - AUTO_STR("If the problem persist, contact the repository maintainer.\n\n") + vector<IndexPtr> indexes; - AUTO_STR("[Error description: %s]"), - make_autostring(remote.name()).c_str(), desc.c_str() - ); + for(const Remote &remote : remotes) { + if(!FS::exists(Index::pathFor(remote.name()))) + continue; - MessageBox(parent, msg, AUTO_STR("ReaPack"), MB_OK); + IndexPtr index = loadIndex(remote, parent); + + if(index) + indexes.push_back(index); } + + callback(indexes); }; - Download *dl = Index::fetch(remote); + queue->onDone(load); + + // I don't know why, but at least on OSX giving the manager window handle + // (in `parent`) to the progress dialog prevents it from being shown at all + // while still taking the focus away from the manager dialog. - if(!dl) { + for(const Remote &remote : remotes) + fetchIndex(remote, queue, parent); + + if(queue->idle()) { load(); - return; } +} - DownloadQueue *queue = new DownloadQueue; - Dialog *progress = Dialog::Create<Progress>(m_instance, m_mainWindow, queue); +void ReaPack::fetchIndex(const Remote &remote, DownloadQueue *queue, HWND parent) +{ + Download *dl = Index::fetch(remote); - // I don't know why, but at least on OSX giving the manager window handle - // (in `parent`) to the progress dialog prevents it from being shown at all - // while still taking the focus away from the manager dialog. + if(!dl) + return; - queue->push(dl); - queue->onDone([=] { delete queue; }); + const auto warn = [=] (const string &desc, const auto_char *title) { + auto_char msg[512] = {}; + auto_snprintf(msg, sizeof(msg), + AUTO_STR("ReaPack could not download %s's index.\n\n") + + AUTO_STR("Try again later. ") + AUTO_STR("If the problem persist, contact the repository maintainer.\n\n") + + AUTO_STR("[Error description: %s]"), + make_autostring(remote.name()).c_str(), make_autostring(desc).c_str() + ); + + MessageBox(parent, msg, title, MB_OK); + }; dl->onFinish([=] { - Dialog::Destroy(progress); - SetFocus(parent); + const Path &path = Index::pathFor(remote.name()); switch(dl->state()) { case Download::Success: - if(FS::write(Index::pathFor(remote.name()), dl->contents())) - load(); - else - MessageBox(parent, make_autostring(FS::lastError()).c_str(), - AUTO_STR("Write Failed"), MB_OK); + if(!FS::write(path, dl->contents())) + warn(FS::lastError(), AUTO_STR("Write Failed")); break; case Download::Failure: - if(FS::exists(Index::pathFor(remote.name()))) - load(); - else - MessageBox(parent, make_autostring(dl->contents()).c_str(), - AUTO_STR("Download Failed"), MB_OK); + if(!FS::exists(path)) + warn(dl->contents(), AUTO_STR("Download Failed")); break; default: break; } }); + + queue->push(dl); +} + +IndexPtr ReaPack::loadIndex(const Remote &remote, HWND parent) +{ + try { + return Index::load(remote.name()); + } + catch(const reapack_error &e) { + const auto_string &desc = make_autostring(e.what()); + + auto_char msg[512] = {}; + auto_snprintf(msg, sizeof(msg), + AUTO_STR("ReaPack could not read %s's index.\n\n") + + AUTO_STR("Synchronize your packages and try again later.\n") + AUTO_STR("If the problem persist, contact the repository maintainer.\n\n") + + AUTO_STR("[Error description: %s]"), + make_autostring(remote.name()).c_str(), desc.c_str() + ); + + MessageBox(parent, msg, AUTO_STR("ReaPack"), MB_OK); + } + + return nullptr; } Transaction *ReaPack::createTransaction() diff --git a/src/reapack.hpp b/src/reapack.hpp @@ -23,10 +23,12 @@ #include <functional> #include <map> #include <memory> +#include <vector> #include <reaper_plugin.h> class Config; +class DownloadQueue; class Import; class Index; class Manager; @@ -34,10 +36,13 @@ class Progress; class Remote; class Transaction; +typedef std::shared_ptr<const Index> IndexPtr; + class ReaPack { public: typedef std::function<void ()> ActionCallback; - typedef std::function<void (std::shared_ptr<const Index>)> IndexCallback; + typedef std::function<void (IndexPtr)> IndexCallback; + typedef std::function<void (const std::vector<IndexPtr> &)> IndexesCallback; static const std::string VERSION; static const std::string BUILDTIME; @@ -64,7 +69,8 @@ public: void manageRemotes(); void aboutSelf(); void about(const Remote &, HWND parent); - void loadIndex(const Remote &, const IndexCallback &, HWND = nullptr); + void fetchIndexes(const std::vector<Remote> &, + const IndexesCallback &, HWND = nullptr); void runTasks(); @@ -74,6 +80,9 @@ private: Transaction *createTransaction(); bool hitchhikeTransaction(); void registerSelf(); + void fetchIndex(const Remote &remote, const IndexCallback &, HWND); + void fetchIndex(const Remote &remote, DownloadQueue *, HWND); + IndexPtr loadIndex(const Remote &remote, HWND); std::map<int, ActionCallback> m_actions;