]> git.mxchange.org Git - flightgear.git/commitdiff
Add --fg-aircraft option, and aircraft dir path list. Partial support in places that...
authorJames Turner <zakalawe@mac.com>
Sun, 18 Jul 2010 12:21:30 +0000 (13:21 +0100)
committerJames Turner <zakalawe@mac.com>
Wed, 28 Jul 2010 21:03:10 +0000 (22:03 +0100)
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.

src/Autopilot/autopilotgroup.cxx
src/Cockpit/panel_io.cxx
src/Instrumentation/instrument_mgr.cxx
src/Main/fg_init.cxx
src/Main/globals.cxx
src/Main/globals.hxx
src/Main/options.cxx
src/Main/splash.cxx
src/Scripting/NasalSys.cxx
src/Sound/fg_fx.cxx
src/Systems/system_mgr.cxx

index 81b4d81018e86bdc81b081bc5b2b2dabb0e3ccfc..e5bb6d03cd0b421ea8333c32b445a4bc87a5d49c 100644 (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() );
 
index 7ef58b6e1522ed393a9e1d2e0a34abeef30b4f41..ecd6efd89a02c674463529642c5899e92bbb6ef2 100644 (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) {
index 6bfecbb270968d540253735f1fd426cddf07c9ca..27f5e39485624dffd3caa9860ed9db301112242d 100644 (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 {
index 4c2404dba786e19bed89b634bdf70989c3cb96a7..179b46e0e53dcb0209ed468817e11a802b7a9cd9 100644 (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;
+    }
+    
+    if (fgFindAircraftInDir(*p, obj, pred)) {
+      return true;
     }
-  } // of recursive case
+  } // 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()) {
index ad38089194f6af50d08de6be8c83532d445c3048..a7023045d22d409d35adbc945ac8712b3ddfbc6a 100644 (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
index 06490eaf38f9a60af0012464e557306d49929b20..3828a9326482f4e87271cb131d03f7965b3970f3 100644 (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; }
 
index e3dd7ab38b5880a0feaec139eca7b16b63f89cc6..e572ebf84c660b2c1e1a7913506270e7bb052655 100644 (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];
index 403617891f2027276978b7110de7146a8bcfc845..19b12348849d43277aaeebbb1979aa3ff6cffd34 100644 (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()));
 
index a210d03569c50bbafbc35ba4bda2f4720e1f9f03..055ad879d78ae707323374a6cb6fbf0098bb317f 100644 (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++;
         }
index f1c11f775f176a4b923a35a3dff8db10c94a1856..950e0bdd071467a6bd9e4e954788e96429ec0913 100644 (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());
 
index 4936ea63818fec9a43fe5ceaac56d9fb75ff18ed..0ca9efb7a1b0eca305ab0b23372ddb56762231d9 100644 (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() );