]> git.mxchange.org Git - simgear.git/commitdiff
Update package classes ownership model.
authorJames Turner <zakalawe@mac.com>
Sat, 31 May 2014 15:46:49 +0000 (16:46 +0100)
committerJames Turner <zakalawe@mac.com>
Sat, 31 May 2014 15:47:12 +0000 (16:47 +0100)
Use SGReferences as the base for package classes, so they can be
exposed directly to Nasal by cppbind.

simgear/package/Catalog.cxx
simgear/package/Catalog.hxx
simgear/package/Install.cxx
simgear/package/Install.hxx
simgear/package/Package.cxx
simgear/package/Package.hxx
simgear/package/Root.cxx
simgear/package/Root.hxx
simgear/package/pkgutil.cxx

index 160d2fbf7cc45e917853c4289c93c04c02fa07d4..bc3df27bd93bf6330a2db6def36a3e0f7b11a6e7 100644 (file)
@@ -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
index 3ea3d846519e26b0ce45c125fb77d0b1dad15663..236bed894ea6201c5af3e46a0860922c949e47cc 100644 (file)
@@ -24,6 +24,9 @@
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/props/props.hxx>
 
+#include <simgear/structure/SGReferenced.hxx>
+#include <simgear/structure/SGSharedPtr.hxx>
+
 #include <simgear/package/Delegate.hxx>
 
 namespace simgear
@@ -39,17 +42,21 @@ class Package;
 class Catalog;
 class Root;
 
-typedef std::vector<Package*> PackageList;
-typedef std::vector<Catalog*> CatalogList;
+typedef SGSharedPtr<Package> PackageRef;
+typedef SGSharedPtr<Catalog> CatalogRef;
+typedef SGSharedPtr<Install> InstallRef;
+  
+typedef std::vector<PackageRef> PackageList;
+typedef std::vector<CatalogRef> 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;
 };  
index 3a15981637c4de2b5424c4d54b8e3632affd1062..ba612d6a0efe93ba4c731590dccedd4e97ad4e5c 100644 (file)
@@ -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);
     
index 3ad0ecd1655348f4e57cb7c8e0fdeb7bc2b322c3..dd676b88e2c204422d7efa7fd8bf52879b73ad10 100644 (file)
@@ -23,6 +23,9 @@
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/package/Delegate.hxx>
 
+#include <simgear/structure/SGReferenced.hxx>
+#include <simgear/structure/SGSharedPtr.hxx>
+
 namespace simgear
 {
     
@@ -32,22 +35,27 @@ namespace pkg
 // forward decls
 class Package;
 class Catalog;
-    
+class Install;
+  
+typedef SGSharedPtr<Package> PackageRef;
+typedef SGSharedPtr<Catalog> CatalogRef;  
+typedef SGSharedPtr<Install> 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
     
index 7e0b1853ba8abf4714966b042a1d791cab0a5e54..7ad13f02383bfd993c057b2688427b7e8202d0d6 100644 (file)
@@ -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);
index 19a69434ac392e8d28e6516d1d2e4e47ac64def4..7346500e72b58f811e682423a2c1a276c2b7e0fe 100644 (file)
@@ -24,6 +24,9 @@
 #include <simgear/props/props.hxx>
 #include <simgear/misc/strutils.hxx>
 
+#include <simgear/structure/SGReferenced.hxx>
+#include <simgear/structure/SGSharedPtr.hxx>
+
 typedef std::set<std::string> string_set;
 
 namespace simgear
@@ -36,16 +39,20 @@ namespace pkg
 class Install;
 class Catalog;
 class Package;
+  
+typedef SGSharedPtr<Package> PackageRef;
+typedef SGSharedPtr<Catalog> CatalogRef;
+typedef SGSharedPtr<Install> InstallRef;
 
-typedef std::vector<Package*> PackageList;
+typedef std::vector<PackageRef> 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;
 };
 
 
index ad5c49b69baf0da0a3fa367bdc14002085d8e39e..adc7b25723f3ee20252c42d9a22538a7fd98e62e 100644 (file)
@@ -37,7 +37,7 @@ namespace simgear {
     
 namespace pkg {
 
-typedef std::map<std::string, Catalog*> CatalogDict;
+typedef std::map<std::string, CatalogRef> CatalogDict;
     
 class Root::RootPrivate
 {
@@ -58,8 +58,8 @@ public:
     Delegate* delegate;
     std::string version;
     
-    std::set<Catalog*> refreshing;
-    std::deque<Install*> updateDeque;
+    std::set<CatalogRef> refreshing;
+    std::deque<InstallRef> updateDeque;
     std::deque<HTTP::Request_ptr> 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
index 176651091e98429e44f5777b886f16266653539c..c0a53a446605da31ac9403ee86b2176a61a42d8d 100644 (file)
@@ -24,6 +24,9 @@
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/package/Delegate.hxx>
 
+#include <simgear/structure/SGReferenced.hxx>
+#include <simgear/structure/SGSharedPtr.hxx>
+
 class SGPropertyNode;
 
 namespace simgear
@@ -41,11 +44,15 @@ namespace pkg
 class Package;
 class Catalog;
 class Install;
+  
+typedef SGSharedPtr<Package> PackageRef;
+typedef SGSharedPtr<Catalog> CatalogRef;
+typedef SGSharedPtr<Install> InstallRef;
+  
+typedef std::vector<PackageRef> PackageList;
+typedef std::vector<CatalogRef> CatalogList;
 
-typedef std::vector<Package*> PackageList;
-typedef std::vector<Catalog*> 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<RootPrivate> d;
 };
-    
+  
+typedef SGSharedPtr<Root> RootRef;
+  
 } // of namespace pkg
 
 } // of namespace simgear
index 837f0d71d9b1a7a5e4fbb9472a8ddd40449e1506..9794c169f7d4f3d596b63bead881e7ca13d5ec50 100644 (file)
@@ -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;