]> git.mxchange.org Git - simgear.git/commitdiff
Catalog install feedback.
authorJames Turner <zakalawe@mac.com>
Thu, 12 Mar 2015 14:27:29 +0000 (14:27 +0000)
committerJames Turner <zakalawe@mac.com>
Sun, 15 Mar 2015 20:55:54 +0000 (21:55 +0100)
- also support removing (uninstalling) a catalog and
all installs relating to it.

simgear/package/Catalog.cxx
simgear/package/Catalog.hxx
simgear/package/Delegate.hxx
simgear/package/Install.cxx
simgear/package/Install.hxx
simgear/package/Root.cxx
simgear/package/Root.hxx

index b1a31b567770514f5a3155c2e9e9faf1556d68d6..1150969f6a061a13148fb79d2401bc3bc2e49b41 100644 (file)
@@ -45,6 +45,8 @@ public:
         HTTP::Request(aUrl),
         m_owner(aOwner)
     {
+        // refreshing
+        m_owner->changeStatus(Delegate::FAIL_IN_PROGRESS);
     }
 
 protected:
@@ -90,7 +92,7 @@ protected:
 
         time(&m_owner->m_retrievedTime);
         m_owner->writeTimestamp();
-        m_owner->refreshComplete(Delegate::FAIL_SUCCESS);
+        m_owner->refreshComplete(Delegate::CATALOG_REFRESHED);
     }
 
 private:
@@ -112,6 +114,7 @@ private:
 
 Catalog::Catalog(Root *aRoot) :
     m_root(aRoot),
+    m_status(Delegate::FAIL_UNKNOWN),
     m_retrievedTime(0)
 {
 }
@@ -154,12 +157,39 @@ CatalogRef Catalog::createFromPath(Root* aRoot, const SGPath& aPath)
 
     CatalogRef c = new Catalog(aRoot);
     c->m_installRoot = aPath;
-    c->parseProps(props);
+    c->parseProps(props); // will set status
     c->parseTimestamp();
 
     return c;
 }
 
+bool Catalog::uninstall()
+{
+    bool ok;
+    bool atLeastOneFailure = false;
+    
+    BOOST_FOREACH(PackageRef p, installedPackages()) {
+        ok = p->existingInstall()->uninstall();
+        if (!ok) {
+            SG_LOG(SG_GENERAL, SG_WARN, "uninstall of package " <<
+                p->id() << " failed");
+            // continue trying other packages, bailing out here
+            // gains us nothing
+            atLeastOneFailure = true;
+        }
+    }
+
+    Dir d(m_installRoot);
+    ok = d.remove(true /* recursive */);
+    if (!ok) {
+        atLeastOneFailure = true;
+    }
+    
+    changeStatus(atLeastOneFailure ? Delegate::FAIL_FILESYSTEM
+                                   : Delegate::FAIL_SUCCESS);
+    return ok;
+}
+
 PackageList const&
 Catalog::packages() const
 {
@@ -226,6 +256,7 @@ InstallRef Catalog::installForPackage(PackageRef pkg) const
 void Catalog::refresh()
 {
     Downloader* dl = new Downloader(this, url());
+    // will iupdate status to IN_PROGRESS
     m_root->makeHTTPRequest(dl);
     m_root->catalogRefreshBegin(this);
 }
@@ -294,6 +325,9 @@ void Catalog::parseProps(const SGPropertyNode* aProps)
         Dir d(m_installRoot);
         d.create(0755);
     }
+    
+    // parsed XML ok, mark status as valid
+    changeStatus(Delegate::FAIL_SUCCESS);
 }
 
 PackageRef Catalog::getPackageById(const std::string& aId) const
@@ -372,6 +406,7 @@ std::string Catalog::getLocalisedString(const SGPropertyNode* aRoot, const char*
 void Catalog::refreshComplete(Delegate::FailureCode aReason)
 {
     m_root->catalogRefreshComplete(this, aReason);
+    changeStatus(aReason);
 }
 
 void Catalog::registerInstall(Install* ins)
@@ -392,6 +427,26 @@ void Catalog::unregisterInstall(Install* ins)
   m_installed.erase(ins->package());
 }
 
+void Catalog::changeStatus(Delegate::FailureCode newStatus)
+{
+    if (m_status == newStatus) {
+        return;
+    }
+    
+    m_status = newStatus;
+    m_statusCallbacks(this);
+}
+
+void Catalog::addStatusCallback(const Callback& cb)
+{
+    m_statusCallbacks.push_back(cb);
+}
+
+Delegate::FailureCode Catalog::status() const
+{
+    return m_status;
+}
+
 } // of namespace pkg
 
 } // of namespace simgear
index d3d685e9d33dbbab4cb42426476e73d4bc580100..4a21dc9df701c5646884bcce368b2b5c31c32676 100644 (file)
 #include <ctime>
 #include <map>
 
+#include <boost/bind.hpp>
+
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/props/props.hxx>
 
 #include <simgear/structure/SGReferenced.hxx>
 #include <simgear/structure/SGSharedPtr.hxx>
+#include <simgear/structure/function_list.hxx>
 
 #include <simgear/package/Delegate.hxx>
 
@@ -63,6 +66,11 @@ public:
     Root* root() const
         { return m_root;};
 
+    /**
+     * uninstall this catalog entirely, including all installed packages
+     */
+    bool uninstall();
+    
     /**
      * perform a refresh of the catalog contents
      */
@@ -115,6 +123,18 @@ public:
      * access the raw property data in the catalog
      */
     SGPropertyNode* properties() const;
+    
+    Delegate::FailureCode status() const;
+    
+    typedef boost::function<void(Catalog*)> Callback;
+    
+    void addStatusCallback(const Callback& cb);
+
+    template<class C>
+    void addStatusCallback(C* instance, void (C::*mem_func)(Catalog*))
+    {
+      return addStatusCallback(boost::bind(mem_func, instance, _1));
+    }
 private:
     Catalog(Root* aRoot);
 
@@ -134,11 +154,14 @@ private:
 
     std::string getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const;
 
+    void changeStatus(Delegate::FailureCode newStatus);
+
     Root* m_root;
     SGPropertyNode_ptr m_props;
     SGPath m_installRoot;
     std::string m_url;
-
+    Delegate::FailureCode m_status;
+    
     PackageList m_packages;
     time_t m_retrievedTime;
 
@@ -149,6 +172,8 @@ private:
   // since it is only cleaned up in the Install destructor
     typedef std::map<PackageRef, Install*> PackageInstallDict;
     PackageInstallDict m_installed;
+    
+    function_list<Callback> m_statusCallbacks;
 };
 
 } // of namespace pkg
index 8bb23a3348be83217e049fa812fd07da4658c1e3..799823fe5718048fd67124189de5ce03cb2d7d00 100644 (file)
@@ -42,7 +42,8 @@ public:
         FAIL_DOWNLOAD,  ///< network issue
         FAIL_EXTRACT,   ///< package archive failed to extract cleanly
         FAIL_FILESYSTEM,    ///< unknown filesystem error occurred
-        FAIL_VERSION ///< version check mismatch
+        FAIL_VERSION, ///< version check mismatch
+        CATALOG_REFRESHED
     } FailureCode;
     
     
index c50e31d958829c334730873e47504e78c0800d7a..2ca011222723c4d87654940c6d00246e90d391ee 100644 (file)
@@ -313,11 +313,21 @@ void Install::startUpdate()
     m_package->catalog()->root()->startInstall(this);
 }
 
-void Install::uninstall()
+bool Install::uninstall()
 {
     Dir d(m_path);
-    d.remove(true);
+    if (!d.remove(true)) {
+        SG_LOG(SG_GENERAL, SG_ALERT, "package uninstall failed: couldn't remove path " << m_path);
+        return false;
+    }
+    
     m_package->catalog()->unregisterInstall(this);
+    return true;
+}
+
+bool Install::isDownloading() const
+{
+    return (m_download != NULL);
 }
 
 //------------------------------------------------------------------------------
index e65789c4b33e0375a794b8fda399330e92505cbe..ae90353dc5cba37b1ad01b58e66ff4da1a9ef072 100644 (file)
@@ -73,9 +73,11 @@ public:
     bool hasUpdate() const;
     
     void startUpdate();
-    
-    void uninstall();
 
+    bool uninstall();
+
+    bool isDownloading() const;
+    
     /**
      * Set the handler to be called when the installation successfully
      * completes.
index adc7b25723f3ee20252c42d9a22538a7fd98e62e..a9127b1fa6ce89669423f1ea2fa6c4150b518529 100644 (file)
@@ -336,6 +336,28 @@ void Root::catalogRefreshComplete(CatalogRef aCat, Delegate::FailureCode aReason
     }
 }
 
+bool Root::removeCatalogById(const std::string& aId)
+{
+    CatalogDict::iterator catIt = d->catalogs.find(aId);
+    if (catIt == d->catalogs.end()) {
+        SG_LOG(SG_GENERAL, SG_WARN, "removeCatalogById: unknown ID:" << aId);
+        return false;
+    }
+    
+    CatalogRef cat = catIt->second;
+    
+    // drop the reference
+    d->catalogs.erase(catIt);
+    
+    bool ok = cat->uninstall();
+    if (!ok) {
+        SG_LOG(SG_GENERAL, SG_WARN, "removeCatalogById: catalog :" << aId
+            << "failed to uninstall");
+    }
+    
+    return ok;
+}
+
 } // of namespace pkg
 
 } // of namespace simgear
index c0a53a446605da31ac9403ee86b2176a61a42d8d..2a06a6b1b0b13c4233d751fd01832a905b5040cc 100644 (file)
@@ -109,6 +109,12 @@ public:
     CatalogRef getCatalogById(const std::string& aId) const;
     
     void scheduleToUpdate(InstallRef aInstall);
+    
+    /**
+     * remove a catalog. Will uninstall all packages originating
+     * from the catalog too.
+     */
+    bool removeCatalogById(const std::string& aId);
 private:
     friend class Install;
     friend class Catalog;