commit e3cf77c35d18ac90a3d2d4c4d7a1bba6d11ea1a0
parent 687f52f5e78ebe4d32b1fedb0ad8145eae7fd0d9
Author: cfillion <cfillion@users.noreply.github.com>
Date: Fri, 8 Apr 2016 18:50:22 -0400
don't lose queued actions when reloading the browser
Diffstat:
5 files changed, 87 insertions(+), 22 deletions(-)
diff --git a/src/browser.cpp b/src/browser.cpp
@@ -338,9 +338,12 @@ void Browser::refresh(const bool stale)
m_loading = true;
- m_reapack->fetchIndexes(remotes, [=] (const vector<IndexPtr> &indexes) {
+ m_reapack->fetchIndexes(remotes, [=] (vector<IndexPtr> indexes) {
m_loading = false;
- m_indexes = indexes;
+
+ // keep the old indexes around a little bit longer for use by populate
+ indexes.swap(m_indexes);
+
populate();
if(!m_loaded) {
@@ -355,33 +358,56 @@ void Browser::populate()
try {
Registry reg(Path::prefixRoot(Path::REGISTRY));
- m_currentIndex = -1;
- m_actions.clear();
- m_entries.clear();
+ std::vector<Entry> entries;
for(IndexPtr index : m_indexes) {
for(const Package *pkg : index->packages())
- m_entries.push_back(makeEntry(pkg, reg.getEntry(pkg)));
+ entries.push_back(makeEntry(pkg, reg.getEntry(pkg)));
// obsolete packages
- for(const Registry::Entry &entry : reg.getEntries(index->name())) {
- const Category *cat = index->category(entry.category);
+ for(const Registry::Entry ®Entry : reg.getEntries(index->name())) {
+ const Category *cat = index->category(regEntry.category);
- if(cat && cat->package(entry.package))
+ if(cat && cat->package(regEntry.package))
continue;
- m_entries.push_back({InstalledFlag | ObsoleteFlag, entry});
+ entries.push_back({InstalledFlag | ObsoleteFlag, regEntry});
+ }
+ }
+
+ auto actionIt = m_actions.begin();
+ while(actionIt != m_actions.end())
+ {
+ const Entry &oldEntry = *actionIt->first;
+ const Version *target = actionIt->second;
+
+ const auto &entryIt = find(entries.begin(), entries.end(), oldEntry);
+
+ actionIt = m_actions.erase(actionIt);
+
+ if(entryIt == entries.end())
+ continue;
+
+ if(target) {
+ const Package *pkg = entryIt->package;
+ if(!pkg || !(target = pkg->findVersion(*target)))
+ continue;
}
+
+ m_actions[&*entryIt] = target;
}
+ m_currentIndex = -1;
+ m_entries.swap(entries);
+
fillList();
}
catch(const reapack_error &e) {
const auto_string &desc = make_autostring(e.what());
auto_char msg[255] = {};
auto_snprintf(msg, sizeof(msg),
- AUTO_STR("ReaPack could not open its package registry.\r\n")
- AUTO_STR("Retry later when all installation task are completed.\r\n")
+ AUTO_STR("ReaPack could not read from its package registry.\r\n")
+ AUTO_STR("Retry later once all installation task are completed.\r\n")
AUTO_STR("\r\nError description: %s"),
desc.c_str());
MessageBox(handle(), msg, AUTO_STR("ReaPack"), MB_OK);
@@ -402,12 +428,7 @@ auto Browser::makeEntry(const Package *pkg, const Registry::Entry ®Entry)
if(regEntry.version < *latest)
flags |= OutOfDateFlag;
- for(const Version *ver : pkg->versions()) {
- if(*ver == regEntry.version) {
- current = ver;
- break;
- }
- }
+ current = pkg->findVersion(regEntry.version);
}
else
flags |= UninstalledFlag;
@@ -699,3 +720,13 @@ void Browser::apply()
fillList(); // update state column
}
+
+auto Browser::Entry::hash() const -> Hash
+{
+ if(package) {
+ return make_tuple(package->category()->index()->name(),
+ package->category()->name(), package->name());
+ }
+ else
+ return make_tuple(regEntry.remote, regEntry.category, regEntry.package);
+}
diff --git a/src/browser.hpp b/src/browser.hpp
@@ -56,13 +56,16 @@ private:
};
struct Entry {
+ typedef std::tuple<std::string, std::string, std::string> Hash;
int flags;
Registry::Entry regEntry;
const Package *package;
const Version *latest;
const Version *current;
+ Hash hash() const;
bool test(Flag f) const { return (flags & f) != 0; }
+ bool operator==(const Entry &o) const { return hash() == o.hash(); }
};
enum Column {
diff --git a/src/package.cpp b/src/package.cpp
@@ -52,7 +52,7 @@ string Package::displayType(const Type type)
return {}; // MSVC is stupid
}
-Package::Package(const Type type, const string &name, Category *cat)
+Package::Package(const Type type, const string &name, const Category *cat)
: m_category(cat), m_type(type), m_name(name)
{
if(m_name.empty())
@@ -104,6 +104,17 @@ const Version *Package::lastVersion() const
return *m_versions.rbegin();
}
+const Version *Package::findVersion(const Version &ver) const
+{
+ const auto &it = find_if(m_versions.begin(), m_versions.end(),
+ [=] (const Version *cur) { return *cur == ver; });
+
+ if(it == m_versions.end())
+ return nullptr;
+ else
+ return *it;
+}
+
Path Package::makeTargetPath(const string &file) const
{
Path path;
diff --git a/src/package.hpp b/src/package.hpp
@@ -38,10 +38,10 @@ public:
static Type typeFor(const char *);
static std::string displayType(Type);
- Package(const Type, const std::string &name, Category * = nullptr);
+ Package(const Type, const std::string &name, const Category * = nullptr);
~Package();
- Category *category() const { return m_category; }
+ const Category *category() const { return m_category; }
Type type() const { return m_type; }
std::string displayType() const;
const std::string &name() const { return m_name; }
@@ -51,11 +51,12 @@ public:
const VersionSet &versions() const { return m_versions; }
const Version *version(size_t index) const;
const Version *lastVersion() const;
+ const Version *findVersion(const Version &) const;
Path makeTargetPath(const std::string &file = {}) const;
private:
- Category *m_category;
+ const Category *m_category;
Type m_type;
std::string m_name;
diff --git a/test/package.cpp b/test/package.cpp
@@ -107,6 +107,25 @@ TEST_CASE("add owned version", M) {
}
}
+TEST_CASE("find matching version", M) {
+ Index ri("Remote Name");
+ Category cat("Category Name", &ri);
+
+ Package pack(Package::ScriptType, "a", &cat);
+ CHECK(pack.versions().size() == 0);
+
+ Version *ver = new Version("1", &pack);
+ ver->addSource(new Source(Source::GenericPlatform, {}, "google.com", ver));
+
+ REQUIRE(pack.findVersion(Version("1")) == nullptr);
+ REQUIRE(pack.findVersion(Version("2")) == nullptr);
+
+ pack.addVersion(ver);
+
+ REQUIRE(pack.findVersion(Version("1")) == ver);
+ REQUIRE(pack.findVersion(Version("2")) == nullptr);
+}
+
TEST_CASE("target path for unknown package type", M) {
Index ri("name");
Category cat("name", &ri);