pkg: Support for install callbacks and fix memory corruption.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user