pkg: Support for install callbacks and fix memory corruption.

This commit is contained in:
Thomas Geymayer
2014-06-10 23:46:14 +02:00
parent a8c8148068
commit 9880ba39a7
3 changed files with 130 additions and 10 deletions

View 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

View 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

View 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;
};