Initial package-system integration.
- disabled by default - incomplete, adding so Thomas can see the API
This commit is contained in:
parent
568dadc898
commit
d1fd5756f6
5 changed files with 196 additions and 3 deletions
|
@ -69,6 +69,8 @@
|
||||||
#include <simgear/scene/model/particles.hxx>
|
#include <simgear/scene/model/particles.hxx>
|
||||||
#include <simgear/scene/tsync/terrasync.hxx>
|
#include <simgear/scene/tsync/terrasync.hxx>
|
||||||
|
|
||||||
|
#include <simgear/package/Root.hxx>
|
||||||
|
|
||||||
#include <Aircraft/controls.hxx>
|
#include <Aircraft/controls.hxx>
|
||||||
#include <Aircraft/replay.hxx>
|
#include <Aircraft/replay.hxx>
|
||||||
#include <Aircraft/FlightHistory.hxx>
|
#include <Aircraft/FlightHistory.hxx>
|
||||||
|
@ -123,6 +125,7 @@
|
||||||
#include <Network/HTTPClient.hxx>
|
#include <Network/HTTPClient.hxx>
|
||||||
#include <Network/fgcom.hxx>
|
#include <Network/fgcom.hxx>
|
||||||
#include <Network/http/httpd.hxx>
|
#include <Network/http/httpd.hxx>
|
||||||
|
#include <Include/version.h>
|
||||||
|
|
||||||
#include <Viewer/CameraGroup.hxx>
|
#include <Viewer/CameraGroup.hxx>
|
||||||
|
|
||||||
|
@ -149,7 +152,9 @@ using std::string;
|
||||||
using std::endl;
|
using std::endl;
|
||||||
using std::cerr;
|
using std::cerr;
|
||||||
using std::cout;
|
using std::cout;
|
||||||
|
|
||||||
using namespace boost::algorithm;
|
using namespace boost::algorithm;
|
||||||
|
using namespace simgear::pkg;
|
||||||
|
|
||||||
extern osg::ref_ptr<osgViewer::Viewer> viewer;
|
extern osg::ref_ptr<osgViewer::Viewer> viewer;
|
||||||
|
|
||||||
|
@ -480,11 +485,19 @@ int fgInitConfig ( int argc, char **argv, bool reinit )
|
||||||
|
|
||||||
int fgInitAircraft(bool reinit)
|
int fgInitAircraft(bool reinit)
|
||||||
{
|
{
|
||||||
|
// FIXME - use Documents/FlightGear/Aircraft
|
||||||
|
SGPath userAircraftDir = globals->get_fg_home();
|
||||||
|
userAircraftDir.append("Aircraft");
|
||||||
|
|
||||||
|
SGSharedPtr<Root> pkgRoot(new Root(userAircraftDir, FLIGHTGEAR_VERSION));
|
||||||
|
// set the http client later (too early in startup right now)
|
||||||
|
globals->setPackageRoot(pkgRoot);
|
||||||
|
|
||||||
// Scan user config files and command line for a specified aircraft.
|
// Scan user config files and command line for a specified aircraft.
|
||||||
if (reinit) {
|
if (reinit) {
|
||||||
SGPropertyNode* sim = fgGetNode("/sim", true);
|
SGPropertyNode* sim = fgGetNode("/sim", true);
|
||||||
sim->removeChildren("fg-aircraft");
|
sim->removeChildren("fg-aircraft");
|
||||||
// after reset, add aircraft dirs to props, neede for Nasal IO rules
|
// after reset, add aircraft dirs to props, needed for Nasal IO rules
|
||||||
string_list::const_iterator it;
|
string_list::const_iterator it;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (it = globals->get_aircraft_paths().begin();
|
for (it = globals->get_aircraft_paths().begin();
|
||||||
|
@ -493,7 +506,6 @@ int fgInitAircraft(bool reinit)
|
||||||
SGPropertyNode* n = sim->getChild("fg-aircraft", index, true);
|
SGPropertyNode* n = sim->getChild("fg-aircraft", index, true);
|
||||||
n->setStringValue(*it);
|
n->setStringValue(*it);
|
||||||
n->setAttribute(SGPropertyNode::WRITE, false);
|
n->setAttribute(SGPropertyNode::WRITE, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SGPropertyNode* aircraftProp = fgGetNode("/sim/aircraft", true);
|
SGPropertyNode* aircraftProp = fgGetNode("/sim/aircraft", true);
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include <simgear/props/propertyObject.hxx>
|
#include <simgear/props/propertyObject.hxx>
|
||||||
#include <simgear/props/props_io.hxx>
|
#include <simgear/props/props_io.hxx>
|
||||||
#include <simgear/scene/model/modellib.hxx>
|
#include <simgear/scene/model/modellib.hxx>
|
||||||
|
#include <simgear/package/Root.hxx>
|
||||||
|
|
||||||
#include <Aircraft/controls.hxx>
|
#include <Aircraft/controls.hxx>
|
||||||
#include <Airports/runways.hxx>
|
#include <Airports/runways.hxx>
|
||||||
|
@ -740,4 +741,14 @@ void FGGlobals::cleanupListeners()
|
||||||
_listeners_to_cleanup.clear();
|
_listeners_to_cleanup.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
simgear::pkg::Root* FGGlobals::packageRoot()
|
||||||
|
{
|
||||||
|
return _packageRoot.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGGlobals::setPackageRoot(const SGSharedPtr<simgear::pkg::Root>& p)
|
||||||
|
{
|
||||||
|
_packageRoot = p;
|
||||||
|
}
|
||||||
|
|
||||||
// end of globals.cxx
|
// end of globals.cxx
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
typedef std::vector<std::string> string_list;
|
typedef std::vector<std::string> string_list;
|
||||||
typedef std::vector<SGPath> PathList;
|
typedef std::vector<SGPath> PathList;
|
||||||
|
@ -67,6 +68,10 @@ class FGRenderer;
|
||||||
class FGFontCache;
|
class FGFontCache;
|
||||||
class FGSampleQueue;
|
class FGSampleQueue;
|
||||||
|
|
||||||
|
namespace simgear { namespace pkg {
|
||||||
|
class Root;
|
||||||
|
}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bucket for subsystem pointers representing the sim's state.
|
* Bucket for subsystem pointers representing the sim's state.
|
||||||
*/
|
*/
|
||||||
|
@ -164,6 +169,7 @@ private:
|
||||||
typedef std::vector<SGPropertyChangeListener*> SGPropertyChangeListenerVec;
|
typedef std::vector<SGPropertyChangeListener*> SGPropertyChangeListenerVec;
|
||||||
SGPropertyChangeListenerVec _listeners_to_cleanup;
|
SGPropertyChangeListenerVec _listeners_to_cleanup;
|
||||||
|
|
||||||
|
SGSharedPtr<simgear::pkg::Root> _packageRoot;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FGGlobals();
|
FGGlobals();
|
||||||
|
@ -337,6 +343,9 @@ public:
|
||||||
void set_chatter_queue(FGSampleQueue* queue);
|
void set_chatter_queue(FGSampleQueue* queue);
|
||||||
|
|
||||||
void addListenerToCleanup(SGPropertyChangeListener* l);
|
void addListenerToCleanup(SGPropertyChangeListener* l);
|
||||||
|
|
||||||
|
simgear::pkg::Root* packageRoot();
|
||||||
|
void setPackageRoot(const SGSharedPtr<simgear::pkg::Root>& p);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,98 @@
|
||||||
|
|
||||||
#include "HTTPClient.hxx"
|
#include "HTTPClient.hxx"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
|
#include <Include/version.h>
|
||||||
|
|
||||||
#include <simgear/sg_inlines.h>
|
#include <simgear/sg_inlines.h>
|
||||||
|
|
||||||
|
#include <simgear/package/Root.hxx>
|
||||||
|
#include <simgear/package/Catalog.hxx>
|
||||||
|
#include <simgear/package/Delegate.hxx>
|
||||||
|
#include <simgear/package/Install.hxx>
|
||||||
|
#include <simgear/package/Package.hxx>
|
||||||
|
|
||||||
|
#include <simgear/nasal/cppbind/from_nasal.hxx>
|
||||||
|
#include <simgear/nasal/cppbind/to_nasal.hxx>
|
||||||
|
#include <simgear/nasal/cppbind/NasalHash.hxx>
|
||||||
|
#include <simgear/nasal/cppbind/Ghost.hxx>
|
||||||
|
|
||||||
|
#include <Scripting/NasalSys.hxx>
|
||||||
|
|
||||||
|
using namespace simgear;
|
||||||
|
|
||||||
|
typedef nasal::Ghost<pkg::RootRef> NasalPackageRoot;
|
||||||
|
typedef nasal::Ghost<pkg::PackageRef> NasalPackage;
|
||||||
|
typedef nasal::Ghost<pkg::CatalogRef> NasalCatalog;
|
||||||
|
typedef nasal::Ghost<pkg::InstallRef> NasalInstall;
|
||||||
|
|
||||||
|
// #define ENABLE_PACKAGE_SYSTEM 1
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class FGDelegate : public pkg::Delegate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void refreshComplete()
|
||||||
|
{
|
||||||
|
SG_LOG(SG_IO, SG_INFO, "all Catalogs refreshed");
|
||||||
|
|
||||||
|
// auto-update; make this controlled by a property
|
||||||
|
pkg::Root* r = globals->packageRoot();
|
||||||
|
|
||||||
|
pkg::PackageList toBeUpdated(r->packagesNeedingUpdate());
|
||||||
|
pkg::PackageList::const_iterator it;
|
||||||
|
for (it = toBeUpdated.begin(); it != toBeUpdated.end(); ++it) {
|
||||||
|
assert((*it)->isInstalled());
|
||||||
|
SG_LOG(SG_IO, SG_INFO, "updating:" << (*it)->id());
|
||||||
|
r->scheduleToUpdate((*it)->install());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void failedRefresh(pkg::Catalog* aCat, FailureCode aReason)
|
||||||
|
{
|
||||||
|
switch (aReason) {
|
||||||
|
case pkg::Delegate::FAIL_SUCCESS:
|
||||||
|
SG_LOG(SG_IO, SG_WARN, "refresh of Catalog done");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
SG_LOG(SG_IO, SG_WARN, "refresh of Catalog " << aCat->url() << " failed:" << aReason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void startInstall(pkg::Install* aInstall)
|
||||||
|
{
|
||||||
|
SG_LOG(SG_IO, SG_INFO, "begining install of:" << aInstall->package()->id()
|
||||||
|
<< " to local path:" << aInstall->path());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void installProgress(pkg::Install* aInstall, unsigned int aBytes, unsigned int aTotal)
|
||||||
|
{
|
||||||
|
SG_LOG(SG_IO, SG_INFO, "installing:" << aInstall->package()->id() << ":"
|
||||||
|
<< aBytes << " of " << aTotal);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void finishInstall(pkg::Install* aInstall)
|
||||||
|
{
|
||||||
|
SG_LOG(SG_IO, SG_INFO, "finished install of:" << aInstall->package()->id()
|
||||||
|
<< " to local path:" << aInstall->path());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void failedInstall(pkg::Install* aInstall, FailureCode aReason)
|
||||||
|
{
|
||||||
|
SG_LOG(SG_IO, SG_WARN, "install failed of:" << aInstall->package()->id()
|
||||||
|
<< " to local path:" << aInstall->path());
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // of anonymous namespace
|
||||||
|
|
||||||
FGHTTPClient::FGHTTPClient()
|
FGHTTPClient::FGHTTPClient()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -42,6 +131,77 @@ void FGHTTPClient::init()
|
||||||
if (!proxyHost.empty()) {
|
if (!proxyHost.empty()) {
|
||||||
_http->setProxy(proxyHost, proxyPort, proxyAuth);
|
_http->setProxy(proxyHost, proxyPort, proxyAuth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_PACKAGE_SYSTEM
|
||||||
|
pkg::Root* packageRoot = globals->packageRoot();
|
||||||
|
if (packageRoot) {
|
||||||
|
// package system needs access to the HTTP engine too
|
||||||
|
packageRoot->setHTTPClient(_http.get());
|
||||||
|
|
||||||
|
packageRoot->setDelegate(new FGDelegate);
|
||||||
|
|
||||||
|
// setup default catalog if not present
|
||||||
|
pkg::Catalog* defaultCatalog = packageRoot->getCatalogById("org.flightgear.default");
|
||||||
|
if (!defaultCatalog) {
|
||||||
|
// always show this message
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "default catalog not found, installing...");
|
||||||
|
pkg::Catalog::createFromUrl(packageRoot,
|
||||||
|
"http://fgfs.goneabitbursar.com/pkg/" FLIGHTGEAR_VERSION "/default-catalog.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
// start a refresh now
|
||||||
|
packageRoot->refresh();
|
||||||
|
}
|
||||||
|
#endif // of ENABLE_PACKAGE_SYSTEM
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGHTTPClient::postinit()
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_PACKAGE_SYSTEM
|
||||||
|
NasalPackageRoot::init("PackageRoot")
|
||||||
|
.member("path", &pkg::Root::path)
|
||||||
|
.member("version", &pkg::Root::catalogVersion)
|
||||||
|
.method("refresh", &pkg::Root::refresh)
|
||||||
|
.method("packageById", &pkg::Root::getPackageById)
|
||||||
|
.method("catalogById", &pkg::Root::getCatalogById);
|
||||||
|
|
||||||
|
NasalCatalog::init("Catalog")
|
||||||
|
.member("installRoot", &pkg::Catalog::installRoot)
|
||||||
|
.member("id", &pkg::Catalog::id)
|
||||||
|
.member("url", &pkg::Catalog::url)
|
||||||
|
.member("description", &pkg::Catalog::description)
|
||||||
|
.method("packageById", &pkg::Catalog::getPackageById)
|
||||||
|
.method("refresh", &pkg::Catalog::refresh)
|
||||||
|
.method("needingUpdate", &pkg::Catalog::packagesNeedingUpdate)
|
||||||
|
.member("installed", &pkg::Catalog::installedPackages);
|
||||||
|
|
||||||
|
NasalPackage::init("Package")
|
||||||
|
.member("id", &pkg::Package::id)
|
||||||
|
.member("name", &pkg::Package::name)
|
||||||
|
.member("description", &pkg::Package::description)
|
||||||
|
.member("installed", &pkg::Package::isInstalled)
|
||||||
|
.member("thumbnails", &pkg::Package::thumbnailUrls)
|
||||||
|
.member("revision", &pkg::Package::revision)
|
||||||
|
.member("catalog", &pkg::Package::catalog)
|
||||||
|
.method("install", &pkg::Package::install)
|
||||||
|
.method("lprop", &pkg::Package::getLocalisedProp);
|
||||||
|
|
||||||
|
NasalInstall::init("Install")
|
||||||
|
.member("revision", &pkg::Install::revsion)
|
||||||
|
.member("pkg", &pkg::Install::package)
|
||||||
|
.member("path", &pkg::Install::path)
|
||||||
|
.member("hasUpdate", &pkg::Install::hasUpdate)
|
||||||
|
.method("startUpdate", & pkg::Install::startUpdate)
|
||||||
|
.method("uninstall", &pkg::Install::uninstall);
|
||||||
|
|
||||||
|
pkg::Root* packageRoot = globals->packageRoot();
|
||||||
|
if (packageRoot) {
|
||||||
|
FGNasalSys* nasalSys = (FGNasalSys*) globals->get_subsystem("nasal");
|
||||||
|
nasal::Hash nasalGlobals = nasalSys->getGlobals();
|
||||||
|
nasal::Hash nasalPkg = nasalGlobals.createHash("pkg"); // module
|
||||||
|
nasalPkg.set("root", packageRoot);
|
||||||
|
}
|
||||||
|
#endif // of ENABLE_PACKAGE_SYSTEM
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGHTTPClient::shutdown()
|
void FGHTTPClient::shutdown()
|
||||||
|
|
|
@ -37,6 +37,7 @@ public:
|
||||||
simgear::HTTP::Client const* client() const { return _http.get(); }
|
simgear::HTTP::Client const* client() const { return _http.get(); }
|
||||||
|
|
||||||
virtual void init();
|
virtual void init();
|
||||||
|
virtual void postinit();
|
||||||
virtual void shutdown();
|
virtual void shutdown();
|
||||||
virtual void update(double);
|
virtual void update(double);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue