Catalog install feedback.
- also support removing (uninstalling) a catalog and all installs relating to it.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -22,11 +22,14 @@
|
||||
#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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user