From 413e89c955c44ef67cd62bd1416ee0a8cc527c85 Mon Sep 17 00:00:00 2001 From: James Turner Date: Sat, 2 Mar 2013 15:14:09 +0000 Subject: [PATCH] Package dependencies. --- simgear/package/Catalog.cxx | 5 ++++ simgear/package/Catalog.hxx | 5 ++++ simgear/package/Package.cxx | 51 +++++++++++++++++++++++++++++++++++++ simgear/package/Package.hxx | 25 +++++++++++++++++- simgear/package/Root.cxx | 13 +++++++++- 5 files changed, 97 insertions(+), 2 deletions(-) diff --git a/simgear/package/Catalog.cxx b/simgear/package/Catalog.cxx index 92164fd1..fad31eff 100644 --- a/simgear/package/Catalog.cxx +++ b/simgear/package/Catalog.cxx @@ -221,6 +221,11 @@ std::string Catalog::description() const { return getLocalisedString(m_props, "description"); } + +SGPropertyNode* Catalog::properties() const +{ + return m_props.ptr(); +} void Catalog::parseTimestamp() { diff --git a/simgear/package/Catalog.hxx b/simgear/package/Catalog.hxx index d49f725a..bbfdc5a6 100644 --- a/simgear/package/Catalog.hxx +++ b/simgear/package/Catalog.hxx @@ -65,6 +65,11 @@ public: Package* getPackageById(const std::string& aId) const; unsigned int ageInSeconds() const; + + /** + * access the raw property data in the catalog + */ + SGPropertyNode* properties() const; private: Catalog(Root* aRoot); diff --git a/simgear/package/Package.cxx b/simgear/package/Package.cxx index 1f43d3ae..b866879e 100644 --- a/simgear/package/Package.cxx +++ b/simgear/package/Package.cxx @@ -2,9 +2,12 @@ #include +#include #include #include +#include + #include #include #include @@ -93,6 +96,20 @@ unsigned int Package::revision() const { return m_props->getIntValue("revision"); } + +SGPropertyNode* Package::properties() const +{ + return m_props.ptr(); +} + +string_list Package::thumbnailUrls() const +{ + string_list r; + BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("thumbnail")) { + r.push_back(dl->getStringValue()); + } + return r; +} string_list Package::downloadUrls() const { @@ -121,6 +138,40 @@ std::string Package::getLocalisedString(const SGPropertyNode* aRoot, const char* return aRoot->getStringValue(aName); } +PackageList Package::dependencies() const +{ + PackageList result; + + BOOST_FOREACH(SGPropertyNode* dep, m_props->getChildren("depends")) { + std::string depName = dep->getStringValue("package"); + unsigned int rev = dep->getIntValue("revision", 0); + + // prefer local hangar package if possible, in case someone does something + // silly with naming. Of course flightgear's aircraft search doesn't know + // about hanagrs, so names still need to be unique. + Package* depPkg = m_catalog->getPackageById(depName); + if (!depPkg) { + Root* rt = m_catalog->root(); + depPkg = rt->getPackageById(depName); + if (!depPkg) { + throw sg_exception("Couldn't satisfy dependency of " + id() + " : " + depName); + } + } + + if (depPkg->revision() < rev) { + throw sg_range_exception("Couldn't find suitable revision of " + depName); + } + + // forbid recursive dependency graphs, we don't need that level + // of complexity for aircraft resources + assert(depPkg->dependencies() == PackageList()); + + result.push_back(depPkg); + } + + return result; +} + } // of namespace pkg } // of namespace simgear diff --git a/simgear/package/Package.hxx b/simgear/package/Package.hxx index 416384d8..d1e79816 100644 --- a/simgear/package/Package.hxx +++ b/simgear/package/Package.hxx @@ -18,7 +18,10 @@ namespace pkg // forward decls class Install; class Catalog; +class Package; +typedef std::vector PackageList; + class Package { public: @@ -31,6 +34,14 @@ public: std::string id() const; + /** + * access the raw property data in the package + */ + SGPropertyNode* properties() const; + + /** + * hex-encoded MD5 sum of the download files + */ std::string md5() const; std::string getLocalisedProp(const std::string& aName) const; @@ -42,7 +53,19 @@ public: bool matches(const SGPropertyNode* aFilter) const; + /** + * download URLs for the package + */ string_list downloadUrls() const; + + string_list thumbnailUrls() const; + + /** + * Packages we depend upon. + * If the dependency list cannot be satisifed for some reason, + * this will raise an sg_exception. + */ + PackageList dependencies() const; private: friend class Catalog; @@ -57,7 +80,7 @@ private: Catalog* m_catalog; }; -typedef std::vector PackageList; + } // of namespace pkg diff --git a/simgear/package/Root.cxx b/simgear/package/Root.cxx index 6783b331..8f203def 100644 --- a/simgear/package/Root.cxx +++ b/simgear/package/Root.cxx @@ -162,7 +162,18 @@ std::string Root::getLocale() const void Root::scheduleToUpdate(Install* aInstall) { - bool wasEmpty = m_updateDeque.empty(); + if (!aInstall) { + sg_exception("missing argument to scheduleToUpdate"); + } + + PackageList deps = aInstall->package()->dependencies(); + BOOST_FOREACH(Package* dep, deps) { + // will internally schedule for update if required + // hence be careful, this method is re-entered in here! + dep->install(); + } + + bool wasEmpty = m_updateDeque.empty(); m_updateDeque.push_back(aInstall); if (wasEmpty) { aInstall->startUpdate(); -- 2.39.5