From: James Turner Date: Sat, 31 May 2014 15:46:49 +0000 (+0100) Subject: Update package classes ownership model. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=e3ddcbe2dd84e8f9f9d2c921e38d29c597adf3ed;p=simgear.git Update package classes ownership model. Use SGReferences as the base for package classes, so they can be exposed directly to Nasal by cppbind. --- diff --git a/simgear/package/Catalog.cxx b/simgear/package/Catalog.cxx index 160d2fbf..bc3df27b 100644 --- a/simgear/package/Catalog.cxx +++ b/simgear/package/Catalog.cxx @@ -43,7 +43,7 @@ CatalogList static_catalogs; class Catalog::Downloader : public HTTP::Request { public: - Downloader(Catalog* aOwner, const std::string& aUrl) : + Downloader(CatalogRef aOwner, const std::string& aUrl) : HTTP::Request(aUrl), m_owner(aOwner) { @@ -106,7 +106,7 @@ private: return false; } - Catalog* m_owner; + CatalogRef m_owner; std::string m_buffer; }; @@ -130,16 +130,17 @@ Catalog::~Catalog() static_catalogs.erase(it); } -Catalog* Catalog::createFromUrl(Root* aRoot, const std::string& aUrl) +CatalogRef Catalog::createFromUrl(Root* aRoot, const std::string& aUrl) { - Catalog* c = new Catalog(aRoot); + CatalogRef c = new Catalog(aRoot); + c->m_url = aUrl; Downloader* dl = new Downloader(c, aUrl); aRoot->makeHTTPRequest(dl); return c; } -Catalog* Catalog::createFromPath(Root* aRoot, const SGPath& aPath) +CatalogRef Catalog::createFromPath(Root* aRoot, const SGPath& aPath) { SGPath xml = aPath; xml.append("catalog.xml"); @@ -161,7 +162,7 @@ Catalog* Catalog::createFromPath(Root* aRoot, const SGPath& aPath) return NULL; } - Catalog* c = new Catalog(aRoot); + CatalogRef c = new Catalog(aRoot); c->m_installRoot = aPath; c->parseProps(props); c->parseTimestamp(); @@ -173,7 +174,7 @@ PackageList Catalog::packagesMatching(const SGPropertyNode* aFilter) const { PackageList r; - BOOST_FOREACH(Package* p, m_packages) { + BOOST_FOREACH(PackageRef p, m_packages) { if (p->matches(aFilter)) { r.push_back(p); } @@ -185,7 +186,7 @@ PackageList Catalog::packagesNeedingUpdate() const { PackageList r; - BOOST_FOREACH(Package* p, m_packages) { + BOOST_FOREACH(PackageRef p, m_packages) { if (!p->isInstalled()) { continue; } @@ -213,14 +214,26 @@ void Catalog::parseProps(const SGPropertyNode* aProps) for (int i = 0; i < nChildren; i++) { const SGPropertyNode* pkgProps = aProps->getChild(i); if (strcmp(pkgProps->getName(), "package") == 0) { - Package* p = new Package(pkgProps, this); + PackageRef p = new Package(pkgProps, this); m_packages.push_back(p); } else { SGPropertyNode* c = m_props->getChild(pkgProps->getName(), pkgProps->getIndex(), true); copyProperties(pkgProps, c); } } // of children iteration - + + if (!m_url.empty()) { + if (m_url != m_props->getStringValue("url")) { + // this effectively allows packages to migrate to new locations, + // although if we're going to rely on that feature we should + // maybe formalise it! + SG_LOG(SG_GENERAL, SG_WARN, "package downloaded from:" << m_url + << " is now at: " << m_props->getStringValue("url")); + } + } + + m_url = m_props->getStringValue("url"); + if (m_installRoot.isNull()) { m_installRoot = m_root->path(); m_installRoot.append(id()); @@ -230,9 +243,9 @@ void Catalog::parseProps(const SGPropertyNode* aProps) } } -Package* Catalog::getPackageById(const std::string& aId) const +PackageRef Catalog::getPackageById(const std::string& aId) const { - BOOST_FOREACH(Package* p, m_packages) { + BOOST_FOREACH(PackageRef p, m_packages) { if (p->id() == aId) { return p; } @@ -248,7 +261,7 @@ std::string Catalog::id() const std::string Catalog::url() const { - return m_props->getStringValue("url"); + return m_url; } std::string Catalog::description() const diff --git a/simgear/package/Catalog.hxx b/simgear/package/Catalog.hxx index 3ea3d846..236bed89 100644 --- a/simgear/package/Catalog.hxx +++ b/simgear/package/Catalog.hxx @@ -24,6 +24,9 @@ #include #include +#include +#include + #include namespace simgear @@ -39,17 +42,21 @@ class Package; class Catalog; class Root; -typedef std::vector PackageList; -typedef std::vector CatalogList; +typedef SGSharedPtr PackageRef; +typedef SGSharedPtr CatalogRef; +typedef SGSharedPtr InstallRef; + +typedef std::vector PackageList; +typedef std::vector CatalogList; -class Catalog + class Catalog : public SGReferenced { public: virtual ~Catalog(); - static Catalog* createFromUrl(Root* aRoot, const std::string& aUrl); + static CatalogRef createFromUrl(Root* aRoot, const std::string& aUrl); - static Catalog* createFromPath(Root* aRoot, const SGPath& aPath); + static CatalogRef createFromPath(Root* aRoot, const SGPath& aPath); static CatalogList allCatalogs(); @@ -81,7 +88,7 @@ public: std::string description() const; - Package* getPackageById(const std::string& aId) const; + PackageRef getPackageById(const std::string& aId) const; /** * test if the catalog data was retrieved longer ago than the @@ -113,7 +120,8 @@ private: Root* m_root; SGPropertyNode_ptr m_props; SGPath m_installRoot; - + std::string m_url; + PackageList m_packages; time_t m_retrievedTime; }; diff --git a/simgear/package/Install.cxx b/simgear/package/Install.cxx index 3a159816..ba612d6a 100644 --- a/simgear/package/Install.cxx +++ b/simgear/package/Install.cxx @@ -42,7 +42,7 @@ namespace pkg { class Install::PackageArchiveDownloader : public HTTP::Request { public: - PackageArchiveDownloader(Install* aOwner) : + PackageArchiveDownloader(InstallRef aOwner) : HTTP::Request("" /* dummy URL */), m_owner(aOwner) { @@ -247,7 +247,7 @@ private: m_urls.erase(m_urls.begin()); // pop first URL } - Install* m_owner; + InstallRef m_owner; string_list m_urls; SG_MD5_CTX m_md5; std::string m_buffer; @@ -256,7 +256,7 @@ private: //////////////////////////////////////////////////////////////////// -Install::Install(Package* aPkg, const SGPath& aPath) : +Install::Install(PackageRef aPkg, const SGPath& aPath) : m_package(aPkg), m_path(aPath), m_download(NULL) @@ -264,10 +264,10 @@ Install::Install(Package* aPkg, const SGPath& aPath) : parseRevision(); } -Install* Install::createFromPath(const SGPath& aPath, Catalog* aCat) +InstallRef Install::createFromPath(const SGPath& aPath, CatalogRef aCat) { std::string id = aPath.file(); - Package* pkg = aCat->getPackageById(id); + PackageRef pkg = aCat->getPackageById(id); if (!pkg) throw sg_exception("no package with id:" + id); diff --git a/simgear/package/Install.hxx b/simgear/package/Install.hxx index 3ad0ecd1..dd676b88 100644 --- a/simgear/package/Install.hxx +++ b/simgear/package/Install.hxx @@ -23,6 +23,9 @@ #include #include +#include +#include + namespace simgear { @@ -32,22 +35,27 @@ namespace pkg // forward decls class Package; class Catalog; - +class Install; + +typedef SGSharedPtr PackageRef; +typedef SGSharedPtr CatalogRef; +typedef SGSharedPtr InstallRef; + /** * */ -class Install +class Install : public SGReferenced { public: /** * create from a directory on disk, or fail. */ - static Install* createFromPath(const SGPath& aPath, Catalog* aCat); + static InstallRef createFromPath(const SGPath& aPath, CatalogRef aCat); unsigned int revsion() const { return m_revision; } - Package* package() const + PackageRef package() const { return m_package; } SGPath path() const @@ -70,7 +78,7 @@ private: class PackageArchiveDownloader; friend class PackageArchiveDownloader; - Install(Package* aPkg, const SGPath& aPath); + Install(PackageRef aPkg, const SGPath& aPath); void parseRevision(); void writeRevisionFile(); @@ -78,7 +86,7 @@ private: void installResult(Delegate::FailureCode aReason); void installProgress(unsigned int aBytes, unsigned int aTotal); - Package* m_package; + PackageRef m_package; unsigned int m_revision; ///< revision on disk SGPath m_path; ///< installation point on disk diff --git a/simgear/package/Package.cxx b/simgear/package/Package.cxx index 7e0b1853..7ad13f02 100644 --- a/simgear/package/Package.cxx +++ b/simgear/package/Package.cxx @@ -31,7 +31,7 @@ namespace simgear { namespace pkg { -Package::Package(const SGPropertyNode* aProps, Catalog* aCatalog) : +Package::Package(const SGPropertyNode* aProps, CatalogRef aCatalog) : m_catalog(aCatalog) { initWithProps(aProps); @@ -83,7 +83,7 @@ bool Package::isInstalled() const return p.exists(); } -Install* Package::install() +InstallRef Package::install() { SGPath p(m_catalog->installRoot()); p.append("Aircraft"); @@ -92,7 +92,7 @@ Install* Package::install() return Install::createFromPath(p, m_catalog); } - Install* ins = new Install(this, p); + InstallRef ins(new Install(this, p)); m_catalog->root()->scheduleToUpdate(ins); return ins; } @@ -174,7 +174,7 @@ PackageList Package::dependencies() const // 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); + PackageRef depPkg = m_catalog->getPackageById(depName); if (!depPkg) { Root* rt = m_catalog->root(); depPkg = rt->getPackageById(depName); diff --git a/simgear/package/Package.hxx b/simgear/package/Package.hxx index 19a69434..7346500e 100644 --- a/simgear/package/Package.hxx +++ b/simgear/package/Package.hxx @@ -24,6 +24,9 @@ #include #include +#include +#include + typedef std::set string_set; namespace simgear @@ -36,16 +39,20 @@ namespace pkg class Install; class Catalog; class Package; + +typedef SGSharedPtr PackageRef; +typedef SGSharedPtr CatalogRef; +typedef SGSharedPtr InstallRef; -typedef std::vector PackageList; +typedef std::vector PackageList; -class Package + class Package : public SGReferenced { public: /** * get or create an install for the package */ - Install* install(); + InstallRef install(); bool isInstalled() const; @@ -76,7 +83,7 @@ public: unsigned int revision() const; - Catalog* catalog() const + CatalogRef catalog() const { return m_catalog; } bool matches(const SGPropertyNode* aFilter) const; @@ -97,7 +104,7 @@ public: private: friend class Catalog; - Package(const SGPropertyNode* aProps, Catalog* aCatalog); + Package(const SGPropertyNode* aProps, CatalogRef aCatalog); void initWithProps(const SGPropertyNode* aProps); @@ -105,7 +112,7 @@ private: SGPropertyNode_ptr m_props; string_set m_tags; - Catalog* m_catalog; + CatalogRef m_catalog; }; diff --git a/simgear/package/Root.cxx b/simgear/package/Root.cxx index ad5c49b6..adc7b257 100644 --- a/simgear/package/Root.cxx +++ b/simgear/package/Root.cxx @@ -37,7 +37,7 @@ namespace simgear { namespace pkg { -typedef std::map CatalogDict; +typedef std::map CatalogDict; class Root::RootPrivate { @@ -58,8 +58,8 @@ public: Delegate* delegate; std::string version; - std::set refreshing; - std::deque updateDeque; + std::set refreshing; + std::deque updateDeque; std::deque httpPendingRequests; }; @@ -114,7 +114,7 @@ Root::Root(const SGPath& aPath, const std::string& aVersion) : } BOOST_FOREACH(SGPath c, dir.children(Dir::TYPE_DIR)) { - Catalog* cat = Catalog::createFromPath(this, c); + CatalogRef cat = Catalog::createFromPath(this, c); if (cat) { d->catalogs[cat->id()] = cat; } @@ -131,7 +131,7 @@ std::string Root::catalogVersion() const return d->version; } -Catalog* Root::getCatalogById(const std::string& aId) const +CatalogRef Root::getCatalogById(const std::string& aId) const { CatalogDict::const_iterator it = d->catalogs.find(aId); if (it == d->catalogs.end()) { @@ -141,11 +141,11 @@ Catalog* Root::getCatalogById(const std::string& aId) const return it->second; } -Package* Root::getPackageById(const std::string& aName) const +PackageRef Root::getPackageById(const std::string& aName) const { size_t lastDot = aName.rfind('.'); - Package* pkg = NULL; + PackageRef pkg = NULL; if (lastDot == std::string::npos) { // naked package ID CatalogDict::const_iterator it = d->catalogs.begin(); @@ -161,7 +161,7 @@ Package* Root::getPackageById(const std::string& aName) const std::string catalogId = aName.substr(0, lastDot); std::string id = aName.substr(lastDot + 1); - Catalog* catalog = getCatalogById(catalogId); + CatalogRef catalog = getCatalogById(catalogId); if (!catalog) { return NULL; } @@ -233,7 +233,7 @@ std::string Root::getLocale() const return d->locale; } -void Root::scheduleToUpdate(Install* aInstall) +void Root::scheduleToUpdate(InstallRef aInstall) { if (!aInstall) { throw sg_exception("missing argument to scheduleToUpdate"); @@ -254,21 +254,21 @@ void Root::scheduleToUpdate(Install* aInstall) } } -void Root::startInstall(Install* aInstall) +void Root::startInstall(InstallRef aInstall) { if (d->delegate) { - d->delegate->startInstall(aInstall); + d->delegate->startInstall(aInstall.ptr()); } } -void Root::installProgress(Install* aInstall, unsigned int aBytes, unsigned int aTotal) +void Root::installProgress(InstallRef aInstall, unsigned int aBytes, unsigned int aTotal) { if (d->delegate) { - d->delegate->installProgress(aInstall, aBytes, aTotal); + d->delegate->installProgress(aInstall.ptr(), aBytes, aTotal); } } -void Root::startNext(Install* aCurrent) +void Root::startNext(InstallRef aCurrent) { if (d->updateDeque.front() != aCurrent) { SG_LOG(SG_GENERAL, SG_ALERT, "current install of package not head of the deque"); @@ -281,32 +281,32 @@ void Root::startNext(Install* aCurrent) } } -void Root::finishInstall(Install* aInstall) +void Root::finishInstall(InstallRef aInstall) { if (d->delegate) { - d->delegate->finishInstall(aInstall); + d->delegate->finishInstall(aInstall.ptr()); } startNext(aInstall); } -void Root::failedInstall(Install* aInstall, Delegate::FailureCode aReason) +void Root::failedInstall(InstallRef aInstall, Delegate::FailureCode aReason) { SG_LOG(SG_GENERAL, SG_ALERT, "failed to install package:" << aInstall->package()->id() << ":" << aReason); if (d->delegate) { - d->delegate->failedInstall(aInstall, aReason); + d->delegate->failedInstall(aInstall.ptr(), aReason); } startNext(aInstall); } -void Root::catalogRefreshBegin(Catalog* aCat) +void Root::catalogRefreshBegin(CatalogRef aCat) { d->refreshing.insert(aCat); } -void Root::catalogRefreshComplete(Catalog* aCat, Delegate::FailureCode aReason) +void Root::catalogRefreshComplete(CatalogRef aCat, Delegate::FailureCode aReason) { CatalogDict::iterator catIt = d->catalogs.find(aCat->id()); if (aReason != Delegate::FAIL_SUCCESS) { @@ -319,7 +319,9 @@ void Root::catalogRefreshComplete(Catalog* aCat, Delegate::FailureCode aReason) bool isPermanentFailure = (aReason == Delegate::FAIL_VERSION); if (isPermanentFailure) { SG_LOG(SG_GENERAL, SG_WARN, "permanent failure for catalog:" << aCat->id()); - d->catalogs.erase(catIt); + if (catIt != d->catalogs.end()) { + d->catalogs.erase(catIt); + } } } else if (catIt == d->catalogs.end()) { // first fresh, add to our storage now diff --git a/simgear/package/Root.hxx b/simgear/package/Root.hxx index 17665109..c0a53a44 100644 --- a/simgear/package/Root.hxx +++ b/simgear/package/Root.hxx @@ -24,6 +24,9 @@ #include #include +#include +#include + class SGPropertyNode; namespace simgear @@ -41,11 +44,15 @@ namespace pkg class Package; class Catalog; class Install; + +typedef SGSharedPtr PackageRef; +typedef SGSharedPtr CatalogRef; +typedef SGSharedPtr InstallRef; + +typedef std::vector PackageList; +typedef std::vector CatalogList; -typedef std::vector PackageList; -typedef std::vector CatalogList; - -class Root +class Root : public SGReferenced { public: Root(const SGPath& aPath, const std::string& aVersion); @@ -97,30 +104,32 @@ public: */ PackageList packagesNeedingUpdate() const; - Package* getPackageById(const std::string& aId) const; + PackageRef getPackageById(const std::string& aId) const; - Catalog* getCatalogById(const std::string& aId) const; + CatalogRef getCatalogById(const std::string& aId) const; - void scheduleToUpdate(Install* aInstall); + void scheduleToUpdate(InstallRef aInstall); private: friend class Install; friend class Catalog; - void catalogRefreshBegin(Catalog* aCat); - void catalogRefreshComplete(Catalog* aCat, Delegate::FailureCode aReason); + void catalogRefreshBegin(CatalogRef aCat); + void catalogRefreshComplete(CatalogRef aCat, Delegate::FailureCode aReason); - void startNext(Install* aCurrent); + void startNext(InstallRef aCurrent); - void startInstall(Install* aInstall); - void installProgress(Install* aInstall, unsigned int aBytes, unsigned int aTotal); - void finishInstall(Install* aInstall); - void failedInstall(Install* aInstall, Delegate::FailureCode aReason); + void startInstall(InstallRef aInstall); + void installProgress(InstallRef aInstall, unsigned int aBytes, unsigned int aTotal); + void finishInstall(InstallRef aInstall); + void failedInstall(InstallRef aInstall, Delegate::FailureCode aReason); class RootPrivate; std::auto_ptr d; }; - + +typedef SGSharedPtr RootRef; + } // of namespace pkg } // of namespace simgear diff --git a/simgear/package/pkgutil.cxx b/simgear/package/pkgutil.cxx index 837f0d71..9794c169 100644 --- a/simgear/package/pkgutil.cxx +++ b/simgear/package/pkgutil.cxx @@ -132,7 +132,7 @@ int main(int argc, char** argv) } else if (!strcmp(argv[1], "refresh")) { root->refresh(true); } else if (!strcmp(argv[1], "install")) { - pkg::Package* pkg = root->getPackageById(argv[2]); + pkg::PackageRef pkg = root->getPackageById(argv[2]); if (!pkg) { cerr << "unknown package:" << argv[2] << endl; return EXIT_FAILURE; @@ -143,12 +143,12 @@ int main(int argc, char** argv) return EXIT_SUCCESS; } - pkg::Catalog* catalog = pkg->catalog(); + pkg::CatalogRef catalog = pkg->catalog(); cout << "Will install:" << pkg->id() << " from " << catalog->id() << "(" << catalog->description() << ")" << endl; pkg->install(); } else if (!strcmp(argv[1], "uninstall") || !strcmp(argv[1], "remove")) { - pkg::Package* pkg = root->getPackageById(argv[2]); + pkg::PackageRef pkg = root->getPackageById(argv[2]); if (!pkg) { cerr << "unknown package:" << argv[2] << endl; return EXIT_FAILURE; @@ -178,7 +178,7 @@ int main(int argc, char** argv) cout << "\t" << p->id() << " " << p->getLocalisedProp("name") << endl; } } else if (!strcmp(argv[1], "info")) { - pkg::Package* pkg = root->getPackageById(argv[2]); + pkg::PackageRef pkg = root->getPackageById(argv[2]); if (!pkg) { cerr << "unknown package:" << argv[2] << endl; return EXIT_FAILURE;