--- /dev/null
+//
+// AircraftDirVisitorBase.hxx - helper to traverse a heirarchy containing
+// aircraft dirs
+//
+// Written by Curtis Olson, started August 1997.
+//
+// Copyright (C) 1997 Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef FG_MAIN_AIRCRAFT_DIR_VISITOR_HXX
+#define FG_MAIN_AIRCRAFT_DIR_VISITOR_HXX
+
+class AircraftDirVistorBase
+{
+public:
+
+protected:
+ enum VisitResult {
+ VISIT_CONTINUE = 0,
+ VISIT_DONE,
+ VISIT_ERROR
+ };
+
+ AircraftDirVistorBase() :
+ _maxDepth(2)
+ {
+
+ }
+
+ VisitResult visitAircraftPaths()
+ {
+ const string_list& paths(globals->get_aircraft_paths());
+ string_list::const_iterator it = paths.begin();
+ for (; it != paths.end(); ++it) {
+ VisitResult vr = visitDir(simgear::Dir(*it), 0);
+ if (vr != VISIT_CONTINUE) {
+ return vr;
+ }
+ } // of aircraft paths iteration
+
+ // if we reach this point, search the default location (always last)
+ SGPath rootAircraft(globals->get_fg_root());
+ rootAircraft.append("Aircraft");
+ return visitDir(rootAircraft, 0);
+ }
+
+ VisitResult visitPath(const SGPath& path, unsigned int depth)
+ {
+ if (!path.exists()) {
+ return VISIT_ERROR;
+ }
+
+ return visit(path);
+ }
+
+ VisitResult visitDir(const simgear::Dir& d, unsigned int depth)
+ {
+ if (!d.exists()) {
+ SG_LOG(SG_GENERAL, SG_WARN, "visitDir: no such path:" << d.path());
+ return VISIT_CONTINUE;
+ }
+
+ if (depth >= _maxDepth) {
+ return VISIT_CONTINUE;
+ }
+
+ bool recurse = true;
+ simgear::PathList setFiles(d.children(simgear::Dir::TYPE_FILE, "-set.xml"));
+ simgear::PathList::iterator p;
+ for (p = setFiles.begin(); p != setFiles.end(); ++p) {
+
+ // if we found a -set.xml at this level, don't recurse any deeper
+ recurse = false;
+ VisitResult vr = visit(*p);
+ if (vr != VISIT_CONTINUE) {
+ return vr;
+ }
+ } // of -set.xml iteration
+
+ if (!recurse) {
+ return VISIT_CONTINUE;
+ }
+
+ simgear::PathList subdirs(d.children(simgear::Dir::TYPE_DIR | simgear::Dir::NO_DOT_OR_DOTDOT));
+ for (p = subdirs.begin(); p != subdirs.end(); ++p) {
+ VisitResult vr = visitDir(*p, depth + 1);
+ if (vr != VISIT_CONTINUE) {
+ return vr;
+ }
+ }
+
+ return VISIT_CONTINUE;
+ } // of visitDir method
+
+ virtual VisitResult visit(const SGPath& path) = 0;
+
+private:
+ unsigned int _maxDepth;
+};
+
+#endif // of FG_MAIN_AIRCRAFT_DIR_VISITOR_HXX
util.hxx
positioninit.hxx
subsystemFactory.hxx
+ AircraftDirVisitorBase.hxx
)
get_property(FG_SOURCES GLOBAL PROPERTY FG_SOURCES)
#include "main.hxx"
#include "positioninit.hxx"
#include "util.hxx"
+#include "AircraftDirVisitorBase.hxx"
#if defined(SG_MAC)
#include <GUI/CocoaHelpers.h> // for Mac impl of platformDefaultDataPath()
return version;
}
-
-template <class T>
-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 false;
- }
-
- bool recurse = true;
- simgear::Dir dir(dirPath);
- simgear::PathList setFiles(dir.children(simgear::Dir::TYPE_FILE, "-set.xml"));
- simgear::PathList::iterator p;
- for (p = setFiles.begin(); p != setFiles.end(); ++p) {
- // check file name ends with -set.xml
-
- // if we found a -set.xml at this level, don't recurse any deeper
- recurse = false;
-
- bool done = (obj->*pred)(*p);
- if (done) {
- return true;
- }
- } // of -set.xml iteration
-
- 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 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
+class FindAndCacheAircraft : public AircraftDirVistorBase
{
public:
FindAndCacheAircraft(SGPropertyNode* autoSave)
n->setAttribute(SGPropertyNode::USERARCHIVE, true);
_cache->removeChildren("aircraft");
- fgFindAircraft(this, &FindAndCacheAircraft::checkAircraft);
+ visitAircraftPaths();
}
if (_foundPath.str().empty()) {
return false;
}
- bool checkAircraft(const SGPath& p)
+ virtual VisitResult visit(const SGPath& p)
{
// create cache node
int i = 0;
if ( boost::equals(fileName, _searchAircraft.c_str(), is_iequal()) ) {
_foundPath = p;
- return true;
+ return VISIT_DONE;
}
- return false;
+ return VISIT_CONTINUE;
}
std::string _searchAircraft;
}
-///////////////////////////////////////////////////////////////////////////////
-// helper object to implement the --show-aircraft command.
-// resides here so we can share the fgFindAircraftInDir template above,
-// and hence ensure this command lists exectly the same aircraft as the normal
-// loading path.
-class ShowAircraft
-{
-public:
- ShowAircraft()
- {
- _minStatus = getNumMaturity(fgGetString("/sim/aircraft-min-status", "all"));
- }
-
-
- void show(const SGPath& path)
- {
- fgFindAircraftInDir(path, this, &ShowAircraft::processAircraft);
-
- simgear::requestConsole(); // ensure console is shown on Windows
-
- std::sort(_aircraft.begin(), _aircraft.end(), ciLessLibC());
- cout << "Available aircraft:" << endl;
- for ( unsigned int i = 0; i < _aircraft.size(); i++ ) {
- cout << _aircraft[i] << endl;
- }
- }
-
-private:
- bool processAircraft(const SGPath& path)
- {
- SGPropertyNode root;
- try {
- readProperties(path.str(), &root);
- } catch (sg_exception& ) {
- return false;
- }
-
- int maturity = 0;
- string descStr(" ");
- descStr += path.file();
- // trim common suffix from file names
- int nPos = descStr.rfind("-set.xml");
- if (nPos == (int)(descStr.size() - 8)) {
- descStr.resize(nPos);
- }
-
- SGPropertyNode *node = root.getNode("sim");
- if (node) {
- SGPropertyNode* desc = node->getNode("description");
- // if a status tag is found, read it in
- if (node->hasValue("status")) {
- maturity = getNumMaturity(node->getStringValue("status"));
- }
-
- if (desc) {
- if (descStr.size() <= 27+3) {
- descStr.append(29+3-descStr.size(), ' ');
- } else {
- descStr += '\n';
- descStr.append( 32, ' ');
- }
- descStr += desc->getStringValue();
- }
- } // of have 'sim' node
-
- if (maturity < _minStatus) {
- return false;
- }
-
- _aircraft.push_back(descStr);
- return false;
- }
-
-
- int getNumMaturity(const char * str)
- {
- // changes should also be reflected in $FG_ROOT/data/options.xml &
- // $FG_ROOT/data/Translations/string-default.xml
- const char* levels[] = {"alpha","beta","early-production","production"};
-
- if (!strcmp(str, "all")) {
- return 0;
- }
-
- for (size_t i=0; i<(sizeof(levels)/sizeof(levels[0]));i++)
- if (strcmp(str,levels[i])==0)
- return i;
-
- return 0;
- }
-
- // recommended in Meyers, Effective STL when internationalization and embedded
- // NULLs aren't an issue. Much faster than the STL or Boost lex versions.
- struct ciLessLibC : public std::binary_function<string, string, bool>
- {
- bool operator()(const std::string &lhs, const std::string &rhs) const
- {
- return strcasecmp(lhs.c_str(), rhs.c_str()) < 0 ? 1 : 0;
- }
- };
-
- int _minStatus;
- string_list _aircraft;
-};
-
-void fgShowAircraft(const SGPath &path)
-{
- ShowAircraft s;
- s.show(path);
-
-#ifdef _MSC_VER
- cout << "Hit a key to continue..." << endl;
- std::cin.get();
-#endif
-}
-
-
// Reset: this is what the 'reset' command (and hence, GUI) is attached to
void fgReInitSubsystems();
-/*
- * Search in the current directory, and in on directory deeper
- * for <aircraft>-set.xml configuration files and show the aircaft name
- * and the contents of the<description> tag in a sorted manner.
- *
- * @parampath the directory to search for configuration files
- */
-void fgShowAircraft(const SGPath &path);
-
#endif // _FG_INIT_HXX
#include <Viewer/viewer.hxx>
#include <Viewer/viewmgr.hxx>
#include <Environment/presets.hxx>
+#include "AircraftDirVisitorBase.hxx"
#include <osg/Version>
fgSetupProxy( envp );
}
+///////////////////////////////////////////////////////////////////////////////
+// helper object to implement the --show-aircraft command.
+// resides here so we can share the fgFindAircraftInDir template above,
+// and hence ensure this command lists exectly the same aircraft as the normal
+// loading path.
+class ShowAircraft : public AircraftDirVistorBase
+{
+public:
+ ShowAircraft()
+ {
+ _minStatus = getNumMaturity(fgGetString("/sim/aircraft-min-status", "all"));
+ }
+
+
+ void show(const SGPath& path)
+ {
+ visitDir(path, 0);
+
+ simgear::requestConsole(); // ensure console is shown on Windows
+
+ std::sort(_aircraft.begin(), _aircraft.end(), ciLessLibC());
+ cout << "Available aircraft:" << endl;
+ for ( unsigned int i = 0; i < _aircraft.size(); i++ ) {
+ cout << _aircraft[i] << endl;
+ }
+ }
+
+private:
+ virtual VisitResult visit(const SGPath& path)
+ {
+ SGPropertyNode root;
+ try {
+ readProperties(path.str(), &root);
+ } catch (sg_exception& ) {
+ return VISIT_CONTINUE;
+ }
+
+ int maturity = 0;
+ string descStr(" ");
+ descStr += path.file();
+ // trim common suffix from file names
+ int nPos = descStr.rfind("-set.xml");
+ if (nPos == (int)(descStr.size() - 8)) {
+ descStr.resize(nPos);
+ }
+
+ SGPropertyNode *node = root.getNode("sim");
+ if (node) {
+ SGPropertyNode* desc = node->getNode("description");
+ // if a status tag is found, read it in
+ if (node->hasValue("status")) {
+ maturity = getNumMaturity(node->getStringValue("status"));
+ }
+
+ if (desc) {
+ if (descStr.size() <= 27+3) {
+ descStr.append(29+3-descStr.size(), ' ');
+ } else {
+ descStr += '\n';
+ descStr.append( 32, ' ');
+ }
+ descStr += desc->getStringValue();
+ }
+ } // of have 'sim' node
+
+ if (maturity >= _minStatus) {
+ _aircraft.push_back(descStr);
+ }
+
+ return VISIT_CONTINUE;
+ }
+
+
+ int getNumMaturity(const char * str)
+ {
+ // changes should also be reflected in $FG_ROOT/data/options.xml &
+ // $FG_ROOT/data/Translations/string-default.xml
+ const char* levels[] = {"alpha","beta","early-production","production"};
+
+ if (!strcmp(str, "all")) {
+ return 0;
+ }
+
+ for (size_t i=0; i<(sizeof(levels)/sizeof(levels[0]));i++)
+ if (strcmp(str,levels[i])==0)
+ return i;
+
+ return 0;
+ }
+
+ // recommended in Meyers, Effective STL when internationalization and embedded
+ // NULLs aren't an issue. Much faster than the STL or Boost lex versions.
+ struct ciLessLibC : public std::binary_function<string, string, bool>
+ {
+ bool operator()(const std::string &lhs, const std::string &rhs) const
+ {
+ return strcasecmp(lhs.c_str(), rhs.c_str()) < 0 ? 1 : 0;
+ }
+ };
+
+ int _minStatus;
+ string_list _aircraft;
+};
+
+/*
+ * Search in the current directory, and in on directory deeper
+ * for <aircraft>-set.xml configuration files and show the aircaft name
+ * and the contents of the<description> tag in a sorted manner.
+ *
+ * @parampath the directory to search for configuration files
+ */
+void fgShowAircraft(const SGPath &path)
+{
+ ShowAircraft s;
+ s.show(path);
+
+#ifdef _MSC_VER
+ cout << "Hit a key to continue..." << endl;
+ std::cin.get();
+#endif
+}
+
+
static bool
parse_wind (const string &wind, double * min_hdg, double * max_hdg,
double * speed, double * gust)