]> git.mxchange.org Git - simgear.git/commitdiff
pkg: Support for install callbacks and fix memory corruption.
authorThomas Geymayer <tomgey@gmail.com>
Tue, 10 Jun 2014 21:46:14 +0000 (23:46 +0200)
committerThomas Geymayer <tomgey@gmail.com>
Tue, 10 Jun 2014 22:19:11 +0000 (00:19 +0200)
simgear/package/Delegate.hxx
simgear/package/Install.cxx
simgear/package/Install.hxx

index a1b0f147741a59e97049df22c75c7dd3547ef6a9..8bb23a3348be83217e049fa812fd07da4658c1e3 100644 (file)
@@ -37,6 +37,7 @@ public:
     typedef enum {
         FAIL_SUCCESS = 0, ///< not a failure :)
         FAIL_UNKNOWN = 1,
+        FAIL_IN_PROGRESS, ///< downloading/installation in progress (not a failure :P)
         FAIL_CHECKSUM,  ///< package MD5 verificstion failed
         FAIL_DOWNLOAD,  ///< network issue
         FAIL_EXTRACT,   ///< package archive failed to extract cleanly
index ba612d6a0efe93ba4c731590dccedd4e97ad4e5c..3d51629930d38440390b77b950d01e509666ad50 100644 (file)
@@ -255,11 +255,11 @@ private:
 };
 
 ////////////////////////////////////////////////////////////////////
-    
 Install::Install(PackageRef aPkg, const SGPath& aPath) :
     m_package(aPkg),
     m_path(aPath),
-    m_download(NULL)
+    m_download(NULL),
+    _status(Delegate::FAIL_IN_PROGRESS)
 {
     parseRevision();
 }
@@ -315,24 +315,75 @@ void Install::uninstall()
 {
     Dir d(m_path);
     d.remove(true);
-    delete this;
 }
 
+//------------------------------------------------------------------------------
+Install* Install::done(const Callback& cb)
+{
+  if( _status == Delegate::FAIL_SUCCESS )
+    cb(this);
+  else
+    _cb_done = cb;
+
+  return this;
+}
+
+//------------------------------------------------------------------------------
+Install* Install::fail(const Callback& cb)
+{
+  if(    _status != Delegate::FAIL_SUCCESS
+      && _status != Delegate::FAIL_IN_PROGRESS )
+    cb(this);
+  else
+    _cb_fail = cb;
+
+  return this;
+}
+
+//------------------------------------------------------------------------------
+Install* Install::always(const Callback& cb)
+{
+  if( _status != Delegate::FAIL_IN_PROGRESS )
+    cb(this);
+  else
+    _cb_always = cb;
+
+  return this;
+}
+
+//------------------------------------------------------------------------------
+Install* Install::progress(const ProgressCallback& cb)
+{
+  _cb_progress = cb;
+  return this;
+}
+
+//------------------------------------------------------------------------------
 void Install::installResult(Delegate::FailureCode aReason)
 {
     if (aReason == Delegate::FAIL_SUCCESS) {
         m_package->catalog()->root()->finishInstall(this);
+        if( _cb_done )
+          _cb_done(this);
     } else {
         m_package->catalog()->root()->failedInstall(this, aReason);
+        if( _cb_fail )
+          _cb_fail(this);
     }
+
+    if( _cb_always )
+      _cb_always(this);
 }
-    
+
+//------------------------------------------------------------------------------
 void Install::installProgress(unsigned int aBytes, unsigned int aTotal)
 {
     m_package->catalog()->root()->installProgress(this, aBytes, aTotal);
+    if( _cb_progress )
+      _cb_progress(this, aBytes, aTotal);
 }
 
-    
+
 } // of namespace pkg
 
 } // of namespace simgear
index dd676b88e2c204422d7efa7fd8bf52879b73ad10..f5458d69eb4c6fba749fceefa39142d8c3aadc1d 100644 (file)
@@ -26,6 +26,9 @@
 #include <simgear/structure/SGReferenced.hxx>
 #include <simgear/structure/SGSharedPtr.hxx>
 
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+
 namespace simgear
 {
     
@@ -47,6 +50,10 @@ typedef SGSharedPtr<Install> InstallRef;
 class Install : public SGReferenced
 {
 public:
+    typedef boost::function<void(Install*)> Callback;
+    typedef boost::function<void(Install*, unsigned int, unsigned int)>
+                                            ProgressCallback;
+
     /**
      * create from a directory on disk, or fail.
      */
@@ -66,12 +73,65 @@ public:
     void startUpdate();
     
     void uninstall();
+
+    /**
+     * Set the handler to be called when the installation successfully
+     * completes.
+     *
+     * @note If the installation is already complete, the handler is called
+     *       immediately.
+     */
+    Install* done(const Callback& cb);
+
+    template<class C>
+    Install* done(C* instance, void (C::*mem_func)(Install*))
+    {
+      return done(boost::bind(mem_func, instance, _1));
+    }
+
+    /**
+     * Set the handler to be called when the installation fails or is aborted.
+     *
+     * @note If the installation has already failed, the handler is called
+     *       immediately.
+     */
+    Install* fail(const Callback& cb);
+
+    template<class C>
+    Install* fail(C* instance, void (C::*mem_func)(Install*))
+    {
+      return fail(boost::bind(mem_func, instance, _1));
+    }
+
+    /**
+     * Set the handler to be called when the installation either successfully
+     * completes or fails.
+     *
+     * @note If the installation is already complete or has already failed, the
+     *       handler is called immediately.
+     */
+    Install* always(const Callback& cb);
+
+    template<class C>
+    Install* always(C* instance, void (C::*mem_func)(Install*))
+    {
+      return always(boost::bind(mem_func, instance, _1));
+    }
     
-// boost signals time?
-    // failure
-    // progress
-    // completed
-    
+    /**
+     * Set the handler to be called during downloading the installation file
+     * indicating the progress of the download.
+     *
+     */
+    Install* progress(const ProgressCallback& cb);
+
+    template<class C>
+    Install* progress(C* instance,
+                      void (C::*mem_func)(Install*, unsigned int, unsigned int))
+    {
+      return progress(boost::bind(mem_func, instance, _1, _2, _3));
+    }
+
 private:
     friend class Package;
     
@@ -91,6 +151,14 @@ private:
     SGPath m_path; ///< installation point on disk
     
     PackageArchiveDownloader* m_download;
+
+    Delegate::FailureCode _status;
+
+    Callback          _cb_done,
+                      _cb_fail,
+                      _cb_always;
+    ProgressCallback  _cb_progress;
+
 };