1
0
Fork 0

Add --fg-aircraft option, and aircraft dir path list. Partial support in places that load files, for respecting the setting.

Add helper to look for an aircraft branch path in multiple candidate locations.
Update the main subsystems to use the helper, and hence load from any aircraft dir.
This commit is contained in:
James Turner 2010-07-18 13:21:30 +01:00
parent d1852430bf
commit ab495d1370
11 changed files with 181 additions and 40 deletions

View file

@ -194,8 +194,7 @@ void FGXMLAutopilotGroup::init()
continue;
}
SGPath config( globals->get_fg_root() );
config.append( pathNode->getStringValue() );
SGPath config = globals->resolve_aircraft_path(pathNode->getStringValue());
SG_LOG( SG_ALL, SG_INFO, "Reading autopilot configuration from " << config.str() );

View file

@ -839,10 +839,9 @@ fgReadPanel (istream &input)
FGPanel *
fgReadPanel (const string &relative_path)
{
SGPath path(globals->get_fg_root());
path.append(relative_path);
SGPath path = globals->resolve_aircraft_path(relative_path);
SGPropertyNode root;
try {
readProperties(path.str(), &root);
} catch (const sg_exception &e) {

View file

@ -62,9 +62,8 @@ FGInstrumentMgr::FGInstrumentMgr () :
SGPropertyNode *path_n = fgGetNode("/sim/instrumentation/path");
if (path_n) {
SGPath config( globals->get_fg_root() );
config.append( path_n->getStringValue() );
SGPath config = globals->resolve_aircraft_path(path_n->getStringValue());
SG_LOG( SG_ALL, SG_INFO, "Reading instruments from "
<< config.str() );
try {

View file

@ -240,7 +240,9 @@ static string fgScanForOption( const string& option ) {
// Read in configuration (files and command line options) but only set
// fg_root
// fg_root and aircraft_paths, which are needed *before* do_options() is called
// in fgInitConfig
bool fgInitFGRoot ( int argc, char **argv ) {
string root;
@ -291,7 +293,7 @@ bool fgInitFGRoot ( int argc, char **argv ) {
SG_LOG(SG_INPUT, SG_INFO, "fg_root = " << root );
globals->set_fg_root(root);
return true;
}
@ -299,6 +301,21 @@ bool fgInitFGRoot ( int argc, char **argv ) {
// Read in configuration (files and command line options) but only set
// aircraft
bool fgInitFGAircraft ( int argc, char **argv ) {
string aircraftDir = fgScanForOption("--fg-aircraft=", argc, argv);
if (aircraftDir.empty()) {
aircraftDir = fgScanForOption("--fg-aircraft=");
}
const char* envp = ::getenv("FG_AIRCRAFT");
if (aircraftDir.empty() && envp) {
globals->append_aircraft_paths(envp);
}
if (!aircraftDir.empty()) {
globals->append_aircraft_paths(aircraftDir);
}
string aircraft;
// First parse command line options looking for --aircraft=, this
@ -501,13 +518,13 @@ do_options (int argc, char ** argv)
}
template <class T>
void fgFindAircraftInDir(const SGPath& dirPath, T* obj, bool (T::*pred)(const SGPath& p))
bool fgFindAircraftInDir(const SGPath& dirPath, T* obj, bool (T::*pred)(const SGPath& p))
{
if (!dirPath.exists()) {
SG_LOG(SG_GENERAL, SG_WARN, "fgFindAircraftInDir: no such path:" << dirPath.str());
return;
return false;
}
bool recurse = true;
simgear::Dir dir(dirPath);
simgear::PathList setFiles(dir.children(simgear::Dir::TYPE_FILE, "-set.xml"));
@ -520,20 +537,44 @@ void fgFindAircraftInDir(const SGPath& dirPath, T* obj, bool (T::*pred)(const SG
bool done = (obj->*pred)(*p);
if (done) {
return;
return true;
}
} // of -set.xml iteration
if (recurse) {
simgear::PathList subdirs(dir.children(simgear::Dir::TYPE_DIR | simgear::Dir::NO_DOT_OR_DOTDOT));
for (p = subdirs.begin(); p != subdirs.end(); ++p) {
if (p->file() == "CVS") {
continue;
}
fgFindAircraftInDir(*p, obj, pred);
if (!recurse) {
return false;
}
simgear::PathList subdirs(dir.children(simgear::Dir::TYPE_DIR | simgear::Dir::NO_DOT_OR_DOTDOT));
for (p = subdirs.begin(); p != subdirs.end(); ++p) {
if (p->file() == "CVS") {
continue;
}
} // of recursive case
if (fgFindAircraftInDir(*p, obj, pred)) {
return true;
}
} // of subdirs iteration
return false;
}
template <class T>
void fgFindAircraft(T* obj, bool (T::*pred)(const SGPath& p))
{
const string_list& paths(globals->get_aircraft_paths());
string_list::const_iterator it = paths.begin();
for (; it != paths.end(); ++it) {
bool done = fgFindAircraftInDir(SGPath(*it), obj, pred);
if (done) {
return;
}
} // of aircraft paths iteration
// if we reach this point, search the default location (always last)
SGPath rootAircraft(globals->get_fg_root());
rootAircraft.append("Aircraft");
fgFindAircraftInDir(rootAircraft, obj, pred);
}
class FindAndCacheAircraft
@ -559,11 +600,8 @@ public:
n->setStringValue(globals->get_fg_root().c_str());
n->setAttribute(SGPropertyNode::USERARCHIVE, true);
_cache->removeChildren("aircraft");
SGPath aircraftDir(globals->get_fg_root());
aircraftDir.append("Aircraft");
fgFindAircraftInDir(aircraftDir, this, &FindAndCacheAircraft::checkAircraft);
fgFindAircraft(this, &FindAndCacheAircraft::checkAircraft);
}
if (_foundPath.str().empty()) {

View file

@ -234,6 +234,82 @@ void FGGlobals::set_fg_scenery (const string &scenery)
} // of path list iteration
}
void FGGlobals::append_aircraft_path(const std::string& path)
{
SGPath dirPath(path);
if (!dirPath.exists()) {
SG_LOG(SG_GENERAL, SG_WARN, "aircraft path not found:" << path);
return;
}
fg_aircraft_dirs.push_back(path);
}
void FGGlobals::append_aircraft_paths(const std::string& path)
{
string_list paths = sgPathSplit(path);
for (unsigned int p = 0; p<paths.size(); ++p) {
append_aircraft_path(paths[p]);
}
}
SGPath FGGlobals::resolve_aircraft_path(const std::string& branch) const
{
string_list pieces(sgPathBranchSplit(branch));
if ((pieces.size() < 3) || (pieces.front() != "Aircraft")) {
SG_LOG(SG_AIRCRAFT, SG_ALERT, "resolve_aircraft_path: bad path:" << branch);
return SGPath();
}
// check current aircraft dir first (takes precedence, allows Generics to be
// over-riden
const char* aircraftDir = fgGetString("/sim/aircraft-dir");
string_list aircraftDirPieces(sgPathBranchSplit(aircraftDir));
if (!aircraftDirPieces.empty() && (aircraftDirPieces.back() == pieces[1])) {
SGPath r(aircraftDir);
for (unsigned int i=2; i<pieces.size(); ++i) {
r.append(pieces[i]);
}
if (r.exists()) {
std::cout << "using aircraft-dir for:" << r.str() << std::endl;
return r;
}
} // of using aircraft-dir case
// try each fg_aircraft_dirs in turn
for (unsigned int p=0; p<fg_aircraft_dirs.size(); ++p) {
SGPath r(fg_aircraft_dirs[p]);
r.append(branch);
if (r.exists()) {
std::cout << "using aircraft directory for:" << r.str() << std::endl;
return r;
}
} // of fg_aircraft_dirs iteration
// finally, try fg_root
SGPath r(fg_root);
r.append(branch);
if (r.exists()) {
std::cout << "using FG_ROOT for:" << r.str() << std::endl;
return r;
}
SG_LOG(SG_AIRCRAFT, SG_ALERT, "resolve_aircraft_path: failed to resolve:" << branch);
return SGPath();
}
SGPath FGGlobals::resolve_maybe_aircraft_path(const std::string& branch) const
{
if (branch.find("Aircraft/") == 0) {
return resolve_aircraft_path(branch);
} else {
SGPath r(fg_root);
r.append(branch);
return r;
}
}
FGRenderer *
FGGlobals::get_renderer () const

View file

@ -27,6 +27,7 @@
#include <simgear/compiler.h>
#include <simgear/props/props.hxx>
#include <simgear/structure/subsystem_mgr.hxx>
#include <simgear/misc/sg_path.hxx>
#include <vector>
#include <string>
@ -181,6 +182,8 @@ private:
//Mulitplayer managers
FGMultiplayMgr *multiplayer_mgr;
/// roots of Aircraft trees
string_list fg_aircraft_dirs;
public:
FGGlobals();
@ -212,6 +215,26 @@ public:
inline const string_list &get_fg_scenery () const { return fg_scenery; }
void set_fg_scenery (const std::string &scenery);
const string_list& get_aircraft_paths() const { return fg_aircraft_dirs; }
void append_aircraft_path(const std::string& path);
void append_aircraft_paths(const std::string& path);
/**
* Given a path to an aircraft-related resource file, resolve it
* against the appropriate root. This means looking at the location
* defined by /sim/aircraft-dir, and then aircraft_path in turn,
* finishing with fg_root/Aircraft.
*
* if the path could not be resolved, an empty path is returned.
*/
SGPath resolve_aircraft_path(const std::string& branch) const;
/**
* Same as above, but test for non 'Aircraft/' branch paths, and
* always resolve them against fg_root.
*/
SGPath resolve_maybe_aircraft_path(const std::string& branch) const;
inline const std::string &get_browser () const { return browser; }
void set_browser (const std::string &b) { browser = b; }

View file

@ -114,6 +114,7 @@ fgSetDefaults ()
// Otherwise, default to Scenery being in $FG_ROOT/Scenery
globals->set_fg_scenery("");
}
// Position (deliberately out of range)
fgSetDouble("/position/longitude-deg", 9999.0);
fgSetDouble("/position/latitude-deg", 9999.0);
@ -772,7 +773,7 @@ fgOptRoc( const char *arg )
static int
fgOptFgRoot( const char *arg )
{
globals->set_fg_root(arg);
// this option is dealt with by fgInitFGRoot
return FG_OPTIONS_OK;
}
@ -783,6 +784,13 @@ fgOptFgScenery( const char *arg )
return FG_OPTIONS_OK;
}
static int
fgOptFgAircraft(const char* arg)
{
// this option is dealt with by fgInitFGAircraft
return FG_OPTIONS_OK;
}
static int
fgOptFov( const char *arg )
{
@ -1339,6 +1347,7 @@ struct OptionDesc {
{"roc", true, OPTION_FUNC, "", false, "", fgOptRoc },
{"fg-root", true, OPTION_FUNC, "", false, "", fgOptFgRoot },
{"fg-scenery", true, OPTION_FUNC, "", false, "", fgOptFgScenery },
{"fg-aircraft", true, OPTION_FUNC, "", false, "", fgOptFgAircraft },
{"fdm", true, OPTION_STRING, "/sim/flight-model", false, "", 0 },
{"aero", true, OPTION_STRING, "/sim/aero", false, "", 0 },
{"aircraft-dir", true, OPTION_STRING, "/sim/aircraft-dir", false, "", 0 },
@ -1622,7 +1631,7 @@ fgParseArgs (int argc, char **argv)
bool verbose = false;
bool help = false;
SG_LOG(SG_GENERAL, SG_INFO, "Processing command line arguments");
SG_LOG(SG_GENERAL, SG_ALERT, "Processing command line arguments");
for (int i = 1; i < argc; i++) {
string arg = argv[i];

View file

@ -197,9 +197,10 @@ static osg::Node* fgCreateSplashCamera()
tpath.append( "Textures/Splash" );
tpath.concat( num_str );
tpath.concat( ".png" );
} else
tpath.append( splash_texture );
} else {
tpath = globals->resolve_maybe_aircraft_path(splash_texture);
}
osg::Texture2D* splashTexture = new osg::Texture2D;
splashTexture->setImage(osgDB::readImageFile(tpath.c_str()));

View file

@ -750,8 +750,7 @@ void FGNasalSys::loadPropertyScripts()
while((fn = n->getChild("file", j)) != NULL) {
file_specified = true;
const char* file = fn->getStringValue();
SGPath p(globals->get_fg_root());
p.append(file);
SGPath p = globals->resolve_maybe_aircraft_path(file);
loadModule(p, module);
j++;
}

View file

@ -69,13 +69,12 @@ FGFX::init()
SGPropertyNode *node = fgGetNode("/sim/sound", true);
string path_str = node->getStringValue("path");
SGPath path( globals->get_fg_root() );
if (path_str.empty()) {
SG_LOG(SG_GENERAL, SG_ALERT, "No path in /sim/sound/path");
return;
}
path.append(path_str.c_str());
SGPath path = globals->resolve_aircraft_path(path_str);
SG_LOG(SG_GENERAL, SG_INFO, "Reading sound " << node->getName()
<< " from " << path.str());

View file

@ -34,8 +34,7 @@ FGSystemMgr::FGSystemMgr ()
SGPropertyNode *path_n = fgGetNode("/sim/systems/path");
if (path_n) {
SGPath config( globals->get_fg_root() );
config.append( path_n->getStringValue() );
SGPath config = globals->resolve_aircraft_path(path_n->getStringValue());
SG_LOG( SG_ALL, SG_INFO, "Reading systems from "
<< config.str() );