commit 0590c9fbc165e8e24e2a3a1ba25c2eca8ba6ac6b
parent 2d14d6f81fdbd123375a71462b2f1e58b34f8596
Author: cfillion <cfillion@users.noreply.github.com>
Date: Fri, 4 Mar 2016 20:53:30 -0500
fetch index files without waiting after a transaction
Diffstat:
9 files changed, 95 insertions(+), 70 deletions(-)
diff --git a/src/about.cpp b/src/about.cpp
@@ -24,7 +24,6 @@
#include "menu.hpp"
#include "reapack.hpp"
#include "registry.hpp"
-#include "remote.hpp"
#include "resource.hpp"
#include "richedit.hpp"
#include "tabbar.hpp"
@@ -37,8 +36,8 @@ using namespace std;
enum { ACTION_HISTORY = 300 };
-About::About(const Remote *remote)
- : Dialog(IDD_ABOUT_DIALOG), m_remote(remote), m_index(nullptr),
+About::About(const RemoteIndex *index)
+ : Dialog(IDD_ABOUT_DIALOG), m_index(index),
m_currentCat(-255)
{
RichEdit::Init();
@@ -51,11 +50,6 @@ About::~About()
void About::onInit()
{
- if(!load()) {
- close();
- return;
- }
-
m_about = createControl<RichEdit>(IDC_ABOUT);
m_cats = createControl<ListView>(IDC_CATEGORIES, ListView::Columns{
@@ -138,31 +132,6 @@ void About::onContextMenu(HWND target, const int x, const int y)
menu.show(x, y, handle());
}
-bool About::load()
-{
- try {
- m_index = RemoteIndex::load(m_remote->name());
- return true;
- }
- 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.\n")
- AUTO_STR("If the problem persist, contact the repository maintainer.\n\n")
-
- AUTO_STR("[Error description: %s]"),
- make_autostring(m_remote->name()).c_str(), desc.c_str()
- );
-
- MessageBox(parent(), msg, AUTO_STR("ReaPack Warning"), MB_OK);
- return false;
- }
-}
-
void About::populate()
{
auto_char title[255] = {};
@@ -244,7 +213,7 @@ void About::updateInstalledFiles()
try {
Registry reg(Path::prefixCache("registry.db"));
- for(const Registry::Entry &entry : reg.getEntries(*m_remote)) {
+ for(const Registry::Entry &entry : reg.getEntries(m_index->name())) {
const set<Path> &files = reg.getFiles(entry);
allFiles.insert(files.begin(), files.end());
}
diff --git a/src/about.hpp b/src/about.hpp
@@ -26,7 +26,6 @@
class ListView;
class Package;
-class Remote;
class RemoteIndex;
class ReportBase;
class RichEdit;
@@ -37,7 +36,7 @@ class About : public Dialog {
public:
enum { InstallResult = 100 };
- About(const Remote *);
+ About(const RemoteIndex *);
~About();
protected:
@@ -46,7 +45,6 @@ protected:
void onContextMenu(HWND, int x, int y) override;
private:
- bool load();
void populate();
void updatePackages();
void updateInstalledFiles();
@@ -54,7 +52,6 @@ private:
void openLink(const Link *);
void packageHistory();
- const Remote *m_remote;
const RemoteIndex *m_index;
int m_currentCat;
diff --git a/src/reapack.cpp b/src/reapack.cpp
@@ -20,6 +20,7 @@
#include "about.hpp"
#include "config.hpp"
#include "errors.hpp"
+#include "filesystem.hpp"
#include "import.hpp"
#include "index.hpp"
#include "manager.hpp"
@@ -186,16 +187,6 @@ void ReaPack::disable(Remote remote)
m_transaction->unregisterAll(remote);
}
-void ReaPack::requireIndex(const Remote &remote, const function<void ()> &cb)
-{
- if(file_exists(RemoteIndex::pathFor(remote.name()).join().c_str()))
- return cb();
- else if(!hitchhikeTransaction())
- return;
-
- m_transaction->fetchIndex(remote, cb);
-}
-
void ReaPack::uninstall(const Remote &remote)
{
if(remote.isProtected())
@@ -312,22 +303,89 @@ void ReaPack::about(const Remote &remote, HWND parent)
if(remote.isNull())
return;
- requireIndex(remote, [=] {
- const auto ret = Dialog::Show<About>(m_instance, parent, &remote);
+ loadIndex(remote, [=] (const RemoteIndex *index) {
+ const auto ret = Dialog::Show<About>(m_instance, parent, index);
- if(ret != About::InstallResult)
- return;
+ if(ret == About::InstallResult)
+ enable(remote);
+ }, parent);
+}
+
+void ReaPack::loadIndex(const Remote &remote,
+ const IndexCallback &callback, HWND parent)
+{
+ if(!parent)
+ parent = m_mainWindow;
+
+ const auto load = [=] {
+ try {
+ // callback is responsible of deleting the index after use
+ callback(RemoteIndex::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")
- enable(remote);
+ AUTO_STR("Synchronize your packages and try again.\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);
+ }
+ };
+
+ Download *dl = RemoteIndex::fetch(remote);
+
+ if(!dl) {
+ load();
+ return;
+ }
+
+ DownloadQueue *queue = new DownloadQueue;
+ Dialog *progress = Dialog::Create<Progress>(m_instance, m_mainWindow, queue);
+
+ // 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.
+
+ queue->push(dl);
+ queue->onDone([=] { delete queue; });
+
+ dl->onFinish([=] {
+ Dialog::Destroy(progress);
+ SetFocus(parent);
+
+ switch(dl->state()) {
+ case Download::Success:
+ if(FS::write(RemoteIndex::pathFor(remote.name()), dl->contents()))
+ load();
+ else
+ MessageBox(parent, make_autostring(FS::lastError()).c_str(),
+ AUTO_STR("Write Failed"), MB_OK);
+ break;
+ case Download::Failure:
+ MessageBox(parent, make_autostring(dl->contents()).c_str(),
+ AUTO_STR("Download Failed"), MB_OK);
+ break;
+ default:
+ break;
+ }
});
}
Transaction *ReaPack::createTransaction()
{
- if(m_transaction) {
+ if(m_progress)
m_progress->setFocus();
+
+ if(m_transaction)
return nullptr;
- }
try {
m_transaction = new Transaction;
diff --git a/src/reapack.hpp b/src/reapack.hpp
@@ -30,11 +30,13 @@ class Import;
class Manager;
class Progress;
class Remote;
+class RemoteIndex;
class Transaction;
class ReaPack {
public:
- typedef std::function<void()> ActionCallback;
+ typedef std::function<void ()> ActionCallback;
+ typedef std::function<void (const RemoteIndex *)> IndexCallback;
static const std::string VERSION;
static const std::string BUILDTIME;
@@ -54,13 +56,13 @@ public:
void synchronizeAll();
void enable(Remote);
void disable(Remote);
- void requireIndex(const Remote &, const std::function<void ()> &);
void uninstall(const Remote &);
void importRemote();
void import(const Remote &);
void manageRemotes();
void aboutSelf();
void about(const Remote &, HWND parent);
+ void loadIndex(const Remote &, const IndexCallback &, HWND = nullptr);
void runTasks();
diff --git a/src/registry.cpp b/src/registry.cpp
@@ -48,7 +48,7 @@ Registry::Registry(const Path &path)
);
m_allEntries = m_db.prepare(
- "SELECT id, remote, category, package, type, version "
+ "SELECT id, category, package, type, version "
"FROM entries WHERE remote = ?"
);
m_forgetEntry = m_db.prepare("DELETE FROM entries WHERE id = ?");
@@ -229,16 +229,15 @@ auto Registry::getEntry(const Package *pkg) const -> Entry
return {id, remote, category, package, type, version};
}
-auto Registry::getEntries(const Remote &remote) const -> vector<Entry>
+auto Registry::getEntries(const string &remoteName) const -> vector<Entry>
{
vector<Registry::Entry> list;
- m_allEntries->bind(1, remote.name());
+ m_allEntries->bind(1, remoteName);
m_allEntries->exec([&] {
int col = 0;
const int id = m_allEntries->intColumn(col++);
- const string &remote = m_allEntries->stringColumn(col++);
const string &category = m_allEntries->stringColumn(col++);
const string &package = m_allEntries->stringColumn(col++);
const Package::Type type =
@@ -246,7 +245,7 @@ auto Registry::getEntries(const Remote &remote) const -> vector<Entry>
Version::Code version = 0;
Version::parse(m_allEntries->stringColumn(col++), &version);
- list.push_back({id, remote, category, package, type, version});
+ list.push_back({id, remoteName, category, package, type, version});
return true;
});
diff --git a/src/registry.hpp b/src/registry.hpp
@@ -56,7 +56,7 @@ public:
QueryResult query(const Package *) const;
Entry getEntry(const Package *) const;
- std::vector<Entry> getEntries(const Remote &) const;
+ std::vector<Entry> getEntries(const std::string &) const;
std::set<Path> getFiles(const Entry &) const;
std::string getMainFile(const Entry &) const;
Entry push(const Version *, std::vector<Path> *conflicts = nullptr);
diff --git a/src/transaction.cpp b/src/transaction.cpp
@@ -207,7 +207,7 @@ void Transaction::installTicket(const InstallTicket &ticket)
void Transaction::registerAll(const Remote &remote)
{
- const vector<Registry::Entry> &entries = m_registry->getEntries(remote);
+ const vector<Registry::Entry> &entries = m_registry->getEntries(remote.name());
for(const auto &entry : entries)
registerInHost(true, entry);
@@ -215,7 +215,7 @@ void Transaction::registerAll(const Remote &remote)
void Transaction::unregisterAll(const Remote &remote)
{
- const vector<Registry::Entry> &entries = m_registry->getEntries(remote);
+ const vector<Registry::Entry> &entries = m_registry->getEntries(remote.name());
for(const auto &entry : entries)
registerInHost(false, entry);
@@ -228,7 +228,7 @@ void Transaction::uninstall(const Remote &remote)
inhibit(remote);
remove(RemoteIndex::pathFor(remote.name()).join().c_str());
- const vector<Registry::Entry> &entries = m_registry->getEntries(remote);
+ const vector<Registry::Entry> &entries = m_registry->getEntries(remote.name());
if(entries.empty())
return;
diff --git a/src/transaction.hpp b/src/transaction.hpp
@@ -35,8 +35,6 @@ class Task;
class Transaction {
public:
- typedef std::function<void ()> IndexCallback;
-
typedef boost::signals2::signal<void ()> Signal;
typedef Signal::slot_type Callback;
@@ -56,7 +54,6 @@ public:
void onFinish(const Callback &callback) { m_onFinish.connect(callback); }
void onDestroy(const Callback &callback) { m_onDestroy.connect(callback); }
- void fetchIndex(const Remote &, const IndexCallback &cb);
void synchronize(const Remote &, bool userAction = true);
void uninstall(const Remote &);
void registerAll(const Remote &);
@@ -80,6 +77,9 @@ public:
private:
struct HostRegistration { bool add; Registry::Entry entry; std::string file; };
+ typedef std::function<void ()> IndexCallback;
+
+ void fetchIndex(const Remote &, const IndexCallback &cb);
void installQueued();
void installTicket(const InstallTicket &);
void finish();
diff --git a/test/registry.cpp b/test/registry.cpp
@@ -89,7 +89,7 @@ TEST_CASE("get file list", M) {
TEST_CASE("query all packages", M) {
MAKE_PACKAGE
- const Remote remote("Remote Name", "irrelevent_url");
+ const string remote = "Remote Name";
Registry reg;
REQUIRE(reg.getEntries(remote).empty());