return c;
}
+PackageList const&
+Catalog::packages() const
+{
+ return m_packages;
+}
+
PackageList
Catalog::packagesMatching(const SGPropertyNode* aFilter) const
{
return r;
}
+PackageList
+Catalog::installedPackages() const
+{
+ PackageList r;
+ BOOST_FOREACH(PackageRef p, m_packages) {
+ if (p->isInstalled()) {
+ r.push_back(p);
+ }
+ }
+ return r;
+}
+
+InstallRef Catalog::installForPackage(PackageRef pkg) const
+{
+ PackageInstallDict::const_iterator it = m_installed.find(pkg);
+ if (it == m_installed.end()) {
+ // check if it exists on disk, create
+
+ SGPath p(pkg->pathOnDisk());
+ if (p.exists()) {
+ return Install::createFromPath(p, CatalogRef(const_cast<Catalog*>(this)));
+ }
+
+ return NULL;
+ }
+
+ return it->second;
+}
+
void Catalog::refresh()
{
Downloader* dl = new Downloader(this, url());
{
// copy everything except package children?
m_props = new SGPropertyNode;
-
+
+ m_variantDict.clear(); // will rebuild during parse
+ std::set<PackageRef> orphans;
+ orphans.insert(m_packages.begin(), m_packages.end());
+
int nChildren = aProps->nChildren();
for (int i = 0; i < nChildren; i++) {
const SGPropertyNode* pkgProps = aProps->getChild(i);
if (strcmp(pkgProps->getName(), "package") == 0) {
- PackageRef p = new Package(pkgProps, this);
- m_packages.push_back(p);
+ PackageRef p = getPackageById(pkgProps->getStringValue("id"));
+ if (p) {
+ // existing package
+ p->updateFromProps(pkgProps);
+ orphans.erase(p); // not an orphan
+ } else {
+ // new package
+ p = new Package(pkgProps, this);
+ m_packages.push_back(p);
+ }
+
+ string_list vars(p->variants());
+ for (string_list::iterator it = vars.begin(); it != vars.end(); ++it) {
+ m_variantDict[*it] = p.ptr();
+ }
} else {
SGPropertyNode* c = m_props->getChild(pkgProps->getName(), pkgProps->getIndex(), true);
copyProperties(pkgProps, c);
}
} // of children iteration
-
+
+ if (!orphans.empty()) {
+ SG_LOG(SG_GENERAL, SG_WARN, "have orphan packages: will become inaccesible");
+ std::set<PackageRef>::iterator it;
+ for (it = orphans.begin(); it != orphans.end(); ++it) {
+ SG_LOG(SG_GENERAL, SG_WARN, "\torphan package:" << (*it)->qualifiedId());
+ PackageList::iterator pit = std::find(m_packages.begin(), m_packages.end(), *it);
+ assert(pit != m_packages.end());
+ m_packages.erase(pit);
+ }
+ }
+
if (!m_url.empty()) {
if (m_url != m_props->getStringValue("url")) {
// this effectively allows packages to migrate to new locations,
PackageRef Catalog::getPackageById(const std::string& aId) const
{
- BOOST_FOREACH(PackageRef p, m_packages) {
- if (p->id() == aId) {
- return p;
- }
- }
-
- return NULL; // not found
+ // search the variant dict here, so looking up aircraft variants
+ // works as expected.
+ PackageWeakMap::const_iterator it = m_variantDict.find(aId);
+ if (it == m_variantDict.end())
+ return NULL;
+
+ return it->second;
}
std::string Catalog::id() const
m_root->catalogRefreshComplete(this, aReason);
}
+void Catalog::registerInstall(Install* ins)
+{
+ if (!ins || ins->package()->catalog() != this) {
+ return;
+ }
+
+ m_installed[ins->package()] = ins;
+}
+
+void Catalog::unregisterInstall(Install* ins)
+{
+ if (!ins || ins->package()->catalog() != this) {
+ return;
+ }
+
+ m_installed.erase(ins->package());
+}
} // of namespace pkg