X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fpackage%2FRoot.cxx;h=adc7b25723f3ee20252c42d9a22538a7fd98e62e;hb=edbfbd769eeee589773bdfda882223fb62cf2e6e;hp=197f96c9b42f09af8422bb7015da70098f655b44;hpb=fc64abea5cf304def36c81f8a95f1da82b2cf078;p=simgear.git diff --git a/simgear/package/Root.cxx b/simgear/package/Root.cxx index 197f96c9..adc7b257 100644 --- a/simgear/package/Root.cxx +++ b/simgear/package/Root.cxx @@ -19,6 +19,9 @@ #include #include +#include +#include +#include #include #include @@ -34,41 +37,86 @@ namespace simgear { namespace pkg { -void Root::setMaxAgeSeconds(int seconds) +typedef std::map CatalogDict; + +class Root::RootPrivate +{ +public: + RootPrivate() : + http(NULL), + maxAgeSeconds(60 * 60 * 24), + delegate(NULL) + { + + } + + SGPath path; + std::string locale; + HTTP::Client* http; + CatalogDict catalogs; + unsigned int maxAgeSeconds; + Delegate* delegate; + std::string version; + + std::set refreshing; + std::deque updateDeque; + std::deque httpPendingRequests; +}; + +SGPath Root::path() const +{ + return d->path; +} + +void Root::setMaxAgeSeconds(unsigned int seconds) { - m_maxAgeSeconds = seconds; + d->maxAgeSeconds = seconds; +} + +unsigned int Root::maxAgeSeconds() const +{ + return d->maxAgeSeconds; } void Root::setHTTPClient(HTTP::Client* aHTTP) { - m_http = aHTTP; + d->http = aHTTP; + BOOST_FOREACH(HTTP::Request_ptr req, d->httpPendingRequests) { + d->http->makeRequest(req); + } + + d->httpPendingRequests.clear(); } -HTTP::Client* Root::getHTTPClient() const +void Root::makeHTTPRequest(HTTP::Request *req) { - return m_http; + if (d->http) { + d->http->makeRequest(req); + return; + } + + d->httpPendingRequests.push_back(req); } - -Root::Root(const SGPath& aPath) : - m_path(aPath), - m_http(NULL), - m_maxAgeSeconds(60 * 60 * 24), - m_delegate(NULL) + +Root::Root(const SGPath& aPath, const std::string& aVersion) : + d(new RootPrivate) { + d->path = aPath; + d->version = aVersion; if (getenv("LOCALE")) { - m_locale = getenv("LOCALE"); + d->locale = getenv("LOCALE"); } - Dir d(aPath); - if (!d.exists()) { - d.create(0755); + Dir dir(aPath); + if (!dir.exists()) { + dir.create(0755); return; } - BOOST_FOREACH(SGPath c, d.children(Dir::TYPE_DIR)) { - Catalog* cat = Catalog::createFromPath(this, c); + BOOST_FOREACH(SGPath c, dir.children(Dir::TYPE_DIR)) { + CatalogRef cat = Catalog::createFromPath(this, c); if (cat) { - m_catalogs[cat->id()] = cat; + d->catalogs[cat->id()] = cat; } } // of child directories iteration } @@ -77,26 +125,31 @@ Root::~Root() { } - -Catalog* Root::getCatalogById(const std::string& aId) const + +std::string Root::catalogVersion() const { - CatalogDict::const_iterator it = m_catalogs.find(aId); - if (it == m_catalogs.end()) { + return d->version; +} + +CatalogRef Root::getCatalogById(const std::string& aId) const +{ + CatalogDict::const_iterator it = d->catalogs.find(aId); + if (it == d->catalogs.end()) { return NULL; } return it->second; } -Package* Root::getPackageById(const std::string& aName) const +PackageRef Root::getPackageById(const std::string& aName) const { size_t lastDot = aName.rfind('.'); - Package* pkg = NULL; + PackageRef pkg = NULL; if (lastDot == std::string::npos) { // naked package ID - CatalogDict::const_iterator it = m_catalogs.begin(); - for (; it != m_catalogs.end(); ++it) { + CatalogDict::const_iterator it = d->catalogs.begin(); + for (; it != d->catalogs.end(); ++it) { pkg = it->second->getPackageById(aName); if (pkg) { return pkg; @@ -108,7 +161,7 @@ Package* Root::getPackageById(const std::string& aName) const std::string catalogId = aName.substr(0, lastDot); std::string id = aName.substr(lastDot + 1); - Catalog* catalog = getCatalogById(catalogId); + CatalogRef catalog = getCatalogById(catalogId); if (!catalog) { return NULL; } @@ -119,8 +172,8 @@ Package* Root::getPackageById(const std::string& aName) const CatalogList Root::catalogs() const { CatalogList r; - CatalogDict::const_iterator it = m_catalogs.begin(); - for (; it != m_catalogs.end(); ++it) { + CatalogDict::const_iterator it = d->catalogs.begin(); + for (; it != d->catalogs.end(); ++it) { r.push_back(it->second); } @@ -132,8 +185,8 @@ Root::packagesMatching(const SGPropertyNode* aFilter) const { PackageList r; - CatalogDict::const_iterator it = m_catalogs.begin(); - for (; it != m_catalogs.end(); ++it) { + CatalogDict::const_iterator it = d->catalogs.begin(); + for (; it != d->catalogs.end(); ++it) { PackageList r2(it->second->packagesMatching(aFilter)); r.insert(r.end(), r2.begin(), r2.end()); } @@ -146,8 +199,8 @@ Root::packagesNeedingUpdate() const { PackageList r; - CatalogDict::const_iterator it = m_catalogs.begin(); - for (; it != m_catalogs.end(); ++it) { + CatalogDict::const_iterator it = d->catalogs.begin(); + for (; it != d->catalogs.end(); ++it) { PackageList r2(it->second->packagesNeedingUpdate()); r.insert(r.end(), r2.begin(), r2.end()); } @@ -157,28 +210,33 @@ Root::packagesNeedingUpdate() const void Root::refresh(bool aForce) { - CatalogDict::iterator it = m_catalogs.begin(); - for (; it != m_catalogs.end(); ++it) { - if (aForce || (it->second->ageInSeconds() > m_maxAgeSeconds)) { + CatalogDict::iterator it = d->catalogs.begin(); + for (; it != d->catalogs.end(); ++it) { + if (aForce || it->second->needsRefresh()) { it->second->refresh(); } } } +void Root::setDelegate(simgear::pkg::Delegate *aDelegate) +{ + d->delegate = aDelegate; +} + void Root::setLocale(const std::string& aLocale) { - m_locale = aLocale; + d->locale = aLocale; } std::string Root::getLocale() const { - return m_locale; + return d->locale; } -void Root::scheduleToUpdate(Install* aInstall) +void Root::scheduleToUpdate(InstallRef aInstall) { if (!aInstall) { - sg_exception("missing argument to scheduleToUpdate"); + throw sg_exception("missing argument to scheduleToUpdate"); } PackageList deps = aInstall->package()->dependencies(); @@ -188,71 +246,92 @@ void Root::scheduleToUpdate(Install* aInstall) dep->install(); } - bool wasEmpty = m_updateDeque.empty(); - m_updateDeque.push_back(aInstall); + bool wasEmpty = d->updateDeque.empty(); + d->updateDeque.push_back(aInstall); + if (wasEmpty) { aInstall->startUpdate(); } } -void Root::startInstall(Install* aInstall) +void Root::startInstall(InstallRef aInstall) { - if (m_delegate) { - m_delegate->startInstall(aInstall); + if (d->delegate) { + d->delegate->startInstall(aInstall.ptr()); } } -void Root::installProgress(Install* aInstall, unsigned int aBytes, unsigned int aTotal) +void Root::installProgress(InstallRef aInstall, unsigned int aBytes, unsigned int aTotal) { - if (m_delegate) { - m_delegate->installProgress(aInstall, aBytes, aTotal); + if (d->delegate) { + d->delegate->installProgress(aInstall.ptr(), aBytes, aTotal); } } -void Root::startNext(Install* aCurrent) +void Root::startNext(InstallRef aCurrent) { - if (m_updateDeque.front() != aCurrent) { + if (d->updateDeque.front() != aCurrent) { SG_LOG(SG_GENERAL, SG_ALERT, "current install of package not head of the deque"); } else { - m_updateDeque.pop_front(); + d->updateDeque.pop_front(); } - if (!m_updateDeque.empty()) { - m_updateDeque.front()->startUpdate(); + if (!d->updateDeque.empty()) { + d->updateDeque.front()->startUpdate(); } } -void Root::finishInstall(Install* aInstall) +void Root::finishInstall(InstallRef aInstall) { - if (m_delegate) { - m_delegate->finishInstall(aInstall); + if (d->delegate) { + d->delegate->finishInstall(aInstall.ptr()); } startNext(aInstall); } -void Root::failedInstall(Install* aInstall, Delegate::FailureCode aReason) +void Root::failedInstall(InstallRef aInstall, Delegate::FailureCode aReason) { SG_LOG(SG_GENERAL, SG_ALERT, "failed to install package:" << aInstall->package()->id() << ":" << aReason); - if (m_delegate) { - m_delegate->failedInstall(aInstall, aReason); + if (d->delegate) { + d->delegate->failedInstall(aInstall.ptr(), aReason); } startNext(aInstall); } -void Root::catalogRefreshBegin(Catalog* aCat) +void Root::catalogRefreshBegin(CatalogRef aCat) { - m_refreshing.insert(aCat); + d->refreshing.insert(aCat); } -void Root::catalogRefreshComplete(Catalog* aCat, bool aSuccess) +void Root::catalogRefreshComplete(CatalogRef aCat, Delegate::FailureCode aReason) { - m_refreshing.erase(aCat); - if (m_refreshing.empty()) { - if (m_delegate) { - m_delegate->refreshComplete(); + CatalogDict::iterator catIt = d->catalogs.find(aCat->id()); + if (aReason != Delegate::FAIL_SUCCESS) { + if (d->delegate) { + d->delegate->failedRefresh(aCat, aReason); + } + + // if the failure is permanent, delete the catalog from our + // list (don't touch it on disk) + bool isPermanentFailure = (aReason == Delegate::FAIL_VERSION); + if (isPermanentFailure) { + SG_LOG(SG_GENERAL, SG_WARN, "permanent failure for catalog:" << aCat->id()); + if (catIt != d->catalogs.end()) { + d->catalogs.erase(catIt); + } + } + } else if (catIt == d->catalogs.end()) { + // first fresh, add to our storage now + d->catalogs.insert(catIt, CatalogDict::value_type(aCat->id(), aCat)); + } + + d->refreshing.erase(aCat); + if (d->refreshing.empty()) { + if (d->delegate) { + d->delegate->refreshComplete(); } } }