]> git.mxchange.org Git - flightgear.git/commitdiff
Support for multiple data dirs.
authorJames Turner <zakalawe@mac.com>
Thu, 27 Jun 2013 08:37:53 +0000 (09:37 +0100)
committerJames Turner <zakalawe@mac.com>
Tue, 17 Sep 2013 06:47:58 +0000 (07:47 +0100)
src/AIModel/AIBase.cxx
src/Main/globals.cxx
src/Main/globals.hxx
src/Scripting/NasalSys.cxx
src/Traffic/TrafficMgr.cxx
src/Traffic/TrafficMgr.hxx

index 652524378b4c6b884fa7dda46ea2c68c85e3fdbb..0f371c45478458e875f23dc22e91c2c7dad13f34 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <simgear/compiler.h>
 
+#include <boost/foreach.hpp>
 #include <string>
 
 #include <osg/ref_ptr>
@@ -350,9 +351,11 @@ bool FGAIBase::init(bool search_in_AI_path)
         osg::ref_ptr<osgDB::ReaderWriter::Options> 
           opt(osg::clone(osgDB::Registry::instance()->getOptions(), osg::CopyOp::SHALLOW_COPY));
 
-        SGPath ai_path(globals->get_fg_root(), "AI");
-        opt->setDatabasePath(ai_path.str());
-        
+        osgDB::FilePathList& paths(opt->getDatabasePathList());
+        paths.clear();
+        BOOST_FOREACH(SGPath p, globals->get_data_paths("AI")) {
+            paths.push_back(p.str());
+        }
         f = osgDB::findDataFile(model_path, opt.get());
     }
 
index 45d70af524b6c0f0dd1ee87698a7877011418632..51f202b4960d72f2785ed5498c32a2478f8a8c4f 100644 (file)
@@ -252,6 +252,54 @@ void FGGlobals::set_fg_home (const std::string &home) {
     fg_home = tmp.realpath();
 }
 
+PathList FGGlobals::get_data_paths() const
+{
+    PathList r(additional_data_paths);
+    r.push_back(SGPath(fg_root));
+    return r;
+}
+
+PathList FGGlobals::get_data_paths(const std::string& suffix) const
+{
+    PathList r;
+    BOOST_FOREACH(SGPath p, get_data_paths()) {
+        p.append(suffix);
+        if (p.exists()) {
+            r.push_back(p);
+        }
+    }
+
+    return r;
+}
+
+void FGGlobals::append_data_path(const SGPath& path)
+{
+    if (!path.exists()) {
+        SG_LOG(SG_GENERAL, SG_WARN, "adding non-existant data path:" << path);
+    }
+    
+    additional_data_paths.push_back(path);
+}
+
+SGPath FGGlobals::find_data_dir(const std::string& pathSuffix) const
+{
+    BOOST_FOREACH(SGPath p, additional_data_paths) {
+        p.append(pathSuffix);
+        if (p.exists()) {
+            return p;
+        }
+    }
+    
+    SGPath rootPath(fg_root);
+    rootPath.append(pathSuffix);
+    if (rootPath.exists()) {
+        return rootPath;
+    }
+    
+    SG_LOG(SG_GENERAL, SG_WARN, "dir not found in any data path:" << pathSuffix);
+    return SGPath();
+}
+
 void FGGlobals::append_fg_scenery (const std::string &paths)
 {
 //    fg_scenery.clear();
index 97f07307adb119231396c4679f160d5b5d9b4284..7ed60b9c3f1e7907e5f33b3f1dfdd72a846c617e 100644 (file)
@@ -33,6 +33,7 @@
 #include <string>
 
 typedef std::vector<std::string> string_list;
+typedef std::vector<SGPath> PathList;
 
 // Forward declarations
 
@@ -93,6 +94,11 @@ private:
     // Root of FlightGear data tree
     std::string fg_root;
 
+    /**
+     * locations to search for (non-scenery) data. 
+     */
+    PathList additional_data_paths;
+    
     // Users home directory for data
     std::string fg_home;
 
@@ -178,6 +184,26 @@ public:
     inline const std::string &get_fg_root () const { return fg_root; }
     void set_fg_root (const std::string &root);
 
+    /**
+     * Get list of data locations. fg_root is always the final item in the
+     * result.
+     */
+    PathList get_data_paths() const;
+    
+    /**
+     * Get data locations which contain the file path suffix. Eg pass ing
+     * 'AI/Traffic' to get all data paths which define <path>/AI/Traffic subdir
+     */
+    PathList get_data_paths(const std::string& suffix) const;
+    
+    void append_data_path(const SGPath& path);
+    
+    /**
+     * Given a path suffix (eg 'Textures' or 'AI/Traffic'), find the
+     * first data directory which defines it.
+     */
+    SGPath find_data_dir(const std::string& pathSuffix) const;
+    
     inline const std::string &get_fg_home () const { return fg_home; }
     void set_fg_home (const std::string &home);
 
index ca7dde87d5ed81a9e408f752bc117ec235dba5a9..bef2ea5c54d0abdae84bd0c4b8a160ec716885ee 100644 (file)
@@ -596,6 +596,16 @@ static naRef f_resolveDataPath(naContext c, naRef me, int argc, naRef* args)
     return naStr_fromdata(naNewString(c), const_cast<char*>(pdata), strlen(pdata));
 }
 
+static naRef f_findDataDir(naContext c, naRef me, int argc, naRef* args)
+{
+    if(argc != 1 || !naIsString(args[0]))
+        naRuntimeError(c, "bad arguments to findDataDir()");
+    
+    SGPath p = globals->find_data_dir(naStr_data(args[0]));
+    const char* pdata = p.c_str();
+    return naStr_fromdata(naNewString(c), const_cast<char*>(pdata), strlen(pdata));
+}
+
 class NasalCommand : public SGCommandMgr::Command
 {
 public:
@@ -724,6 +734,7 @@ static struct { const char* name; naCFunction func; } funcs[] = {
     { "abort", f_abort },
     { "directory", f_directory },
     { "resolvepath", f_resolveDataPath },
+    { "finddata", f_findDataDir },
     { "parsexml", f_parsexml },
     { "systime", f_systime },
     { 0, 0 }
index e21ed2c456df2de1a4c260705d55f650e162a4e6..51d7154d7dd5a7c50c53852e94fdef9acb463499 100644 (file)
@@ -76,13 +76,19 @@ using std::endl;
 /**
  * Thread encapsulating parsing the traffic schedules. 
  */
-class ScheduleParseThread : public SGThread
+class ScheduleParseThread : public SGThread, public XMLVisitor
 {
 public:
   ScheduleParseThread(FGTrafficManager* traffic) :
     _trafficManager(traffic),
     _isFinished(false),
-    _cancelThread(false)
+    _cancelThread(false),
+    cruiseAlt(0),
+    score(0),
+    acCounter(0),
+    radius(0),
+    offset(0),
+    heavy(false)
   {
     
   }
@@ -100,9 +106,9 @@ public:
     }
   }
   
-  void setTrafficDir(const SGPath& trafficDirPath)
+  void setTrafficDirs(const PathList& dirs)
   {
-    _trafficDirPath = trafficDirPath;
+    _trafficDirPaths = dirs;
   }
   
   bool isFinished() const
@@ -113,35 +119,289 @@ public:
   
   virtual void run()
   {
-    SGTimeStamp st;
-    st.stamp();
-    
-    simgear::Dir trafficDir(_trafficDirPath);
-    simgear::PathList d = trafficDir.children(simgear::Dir::TYPE_DIR | simgear::Dir::NO_DOT_OR_DOTDOT);
-    
-    BOOST_FOREACH(SGPath p, d) {
-      simgear::Dir d2(p);
-      simgear::PathList trafficFiles = d2.children(simgear::Dir::TYPE_FILE, ".xml");
-      BOOST_FOREACH(SGPath xml, trafficFiles) {
-        _trafficManager->parseSchedule(xml);
-        if (_cancelThread) {
-          return;
-        }
+      BOOST_FOREACH(SGPath p, _trafficDirPaths) {
+          parseTrafficDir(p);
+          if (_cancelThread) {
+              return;
+          }
       }
-    } // of sub-directories in AI/Traffic iteration
-    
-  //  _trafficManager->parseSchedules(schedulesToRead);
-    SG_LOG(SG_AI, SG_INFO, "parsing traffic schedules took:" << st.elapsedMSec() << "msec");
     
     SGGuard<SGMutex> g(_lock);
     _isFinished = true;
   }
+    
+    void startXML()
+    {
+        //cout << "Start XML" << endl;
+        requiredAircraft = "";
+        homePort = "";
+    }
+    
+    void endXML()
+    {
+        //cout << "End XML" << endl;
+    }
+    
+    void startElement(const char *name,
+                                        const XMLAttributes & atts)
+    {
+        const char *attval;
+        //cout << "Start element " << name << endl;
+        //FGTrafficManager temp;
+        //for (int i = 0; i < atts.size(); i++)
+        //  if (string(atts.getName(i)) == string("include"))
+        attval = atts.getValue("include");
+        if (attval != 0) {
+            //cout << "including " << attval << endl;
+            SGPath path = globals->get_fg_root();
+            path.append("/Traffic/");
+            path.append(attval);
+            readXML(path.str(), *this);
+        }
+        elementValueStack.push_back("");
+        //  cout << "  " << atts.getName(i) << '=' << atts.getValue(i) << endl;
+    }
+    
+    void endElement(const char *name)
+    {
+        //cout << "End element " << name << endl;
+        const string & value = elementValueStack.back();
+        
+        if (!strcmp(name, "model"))
+            mdl = value;
+        else if (!strcmp(name, "livery"))
+            livery = value;
+        else if (!strcmp(name, "home-port"))
+            homePort = value;
+        else if (!strcmp(name, "registration"))
+            registration = value;
+        else if (!strcmp(name, "airline"))
+            airline = value;
+        else if (!strcmp(name, "actype"))
+            acType = value;
+        else if (!strcmp(name, "required-aircraft"))
+            requiredAircraft = value;
+        else if (!strcmp(name, "flighttype"))
+            flighttype = value;
+        else if (!strcmp(name, "radius"))
+            radius = atoi(value.c_str());
+        else if (!strcmp(name, "offset"))
+            offset = atoi(value.c_str());
+        else if (!strcmp(name, "performance-class"))
+            m_class = value;
+        else if (!strcmp(name, "heavy")) {
+            if (value == string("true"))
+                heavy = true;
+            else
+                heavy = false;
+        } else if (!strcmp(name, "callsign"))
+            callsign = value;
+        else if (!strcmp(name, "fltrules"))
+            fltrules = value;
+        else if (!strcmp(name, "port"))
+            port = value;
+        else if (!strcmp(name, "time"))
+            timeString = value;
+        else if (!strcmp(name, "departure")) {
+            departurePort = port;
+            departureTime = timeString;
+        } else if (!strcmp(name, "cruise-alt"))
+            cruiseAlt = atoi(value.c_str());
+        else if (!strcmp(name, "arrival")) {
+            arrivalPort = port;
+            arrivalTime = timeString;
+        } else if (!strcmp(name, "repeat"))
+            repeat = value;
+        else if (!strcmp(name, "flight")) {
+            // We have loaded and parsed all the information belonging to this flight
+            // so we temporarily store it.
+            //cerr << "Pusing back flight " << callsign << endl;
+            //cerr << callsign  <<  " " << fltrules     << " "<< departurePort << " " <<  arrivalPort << " "
+            //   << cruiseAlt <<  " " << departureTime<< " "<< arrivalTime   << " " << repeat << endl;
+            
+            //Prioritize aircraft
+            string apt = fgGetString("/sim/presets/airport-id");
+            //cerr << "Airport information: " << apt << " " << departurePort << " " << arrivalPort << endl;
+            //if (departurePort == apt) score++;
+            //flights.push_back(new FGScheduledFlight(callsign,
+            //                                fltrules,
+            //                                departurePort,
+            //                                arrivalPort,
+            //                                cruiseAlt,
+            //                                departureTime,
+            //                                arrivalTime,
+            //                                repeat));
+            if (requiredAircraft == "") {
+                char buffer[16];
+                snprintf(buffer, 16, "%d", acCounter);
+                requiredAircraft = buffer;
+            }
+            SG_LOG(SG_AI, SG_DEBUG, "Adding flight: " << callsign << " "
+                   << fltrules << " "
+                   << departurePort << " "
+                   << arrivalPort << " "
+                   << cruiseAlt << " "
+                   << departureTime << " "
+                   << arrivalTime << " " << repeat << " " << requiredAircraft);
+            // For database maintainance purposes, it may be convenient to
+            //
+            if (fgGetBool("/sim/traffic-manager/dumpdata") == true) {
+                SG_LOG(SG_AI, SG_ALERT, "Traffic Dump FLIGHT," << callsign << ","
+                       << fltrules << ","
+                       << departurePort << ","
+                       << arrivalPort << ","
+                       << cruiseAlt << ","
+                       << departureTime << ","
+                       << arrivalTime << "," << repeat << "," << requiredAircraft);
+            }
+            
+            _trafficManager->flights[requiredAircraft].push_back(new FGScheduledFlight(callsign,
+                                                                      fltrules,
+                                                                      departurePort,
+                                                                      arrivalPort,
+                                                                      cruiseAlt,
+                                                                      departureTime,
+                                                                      arrivalTime,
+                                                                      repeat,
+                                                                      requiredAircraft));
+            requiredAircraft = "";
+        } else if (!strcmp(name, "aircraft")) {
+            endAircraft();
+        }
+        
+        elementValueStack.pop_back();
+    }
+
+    
+    void data(const char *s, int len)
+    {
+        string token = string(s, len);
+        //cout << "Character data " << string(s,len) << endl;
+        elementValueStack.back() += token;
+    }
+    
+    void pi(const char *target, const char *data)
+    {
+        //cout << "Processing instruction " << target << ' ' << data << endl;
+    }
+    
+    void warning(const char *message, int line, int column)
+    {
+        SG_LOG(SG_IO, SG_WARN,
+               "Warning: " << message << " (" << line << ',' << column << ')');
+    }
+    
+    void error(const char *message, int line, int column)
+    {
+        SG_LOG(SG_IO, SG_ALERT,
+               "Error: " << message << " (" << line << ',' << column << ')');
+    }
+    
 private:
+    void endAircraft()
+    {
+        string isHeavy = heavy ? "true" : "false";
+        
+        if (missingModels.find(mdl) != missingModels.end()) {
+            // don't stat() or warn again
+            requiredAircraft = homePort = "";
+            return;
+        }
+        
+        if (!FGAISchedule::validModelPath(mdl)) {
+            missingModels.insert(mdl);
+            SG_LOG(SG_AI, SG_WARN, "TrafficMgr: Missing model path:" << mdl);
+            requiredAircraft = homePort = "";
+            return;
+        }
+        
+        int proportion =
+        (int) (fgGetDouble("/sim/traffic-manager/proportion") * 100);
+        int randval = rand() & 100;
+        if (randval > proportion) {
+            requiredAircraft = homePort = "";
+            return;
+        }
+        
+        if (fgGetBool("/sim/traffic-manager/dumpdata") == true) {
+            SG_LOG(SG_AI, SG_ALERT, "Traffic Dump AC," << homePort << "," << registration << "," << requiredAircraft
+                   << "," << acType << "," << livery << ","
+                   << airline << ","  << m_class << "," << offset << "," << radius << "," << flighttype << "," << isHeavy << "," << mdl);
+        }
+        
+        if (requiredAircraft == "") {
+            char buffer[16];
+            snprintf(buffer, 16, "%d", acCounter);
+            requiredAircraft = buffer;
+        }
+        if (homePort == "") {
+            homePort = departurePort;
+        }
+        
+        // caution, modifying the scheduled aircraft strucutre from the
+        // 'wrong' thread. This is safe becuase FGTrafficManager won't touch
+        // the structure while we exist.
+        _trafficManager->scheduledAircraft.push_back(new FGAISchedule(mdl,
+                                                     livery,
+                                                     homePort,
+                                                     registration,
+                                                     requiredAircraft,
+                                                     heavy,
+                                                     acType,
+                                                     airline,
+                                                     m_class,
+                                                     flighttype,
+                                                     radius, offset));
+        
+        acCounter++;
+        requiredAircraft = "";
+        homePort = "";
+        score = 0;
+    }
+    
+    void parseTrafficDir(const SGPath& path)
+    {
+        SGTimeStamp st;
+        st.stamp();
+        
+        simgear::Dir trafficDir(path);
+        simgear::PathList d = trafficDir.children(simgear::Dir::TYPE_DIR | simgear::Dir::NO_DOT_OR_DOTDOT);
+        
+        BOOST_FOREACH(SGPath p, d) {
+            simgear::Dir d2(p);
+            simgear::PathList trafficFiles = d2.children(simgear::Dir::TYPE_FILE, ".xml");
+            BOOST_FOREACH(SGPath xml, trafficFiles) {                
+                readXML(xml.str(), *this);
+                if (_cancelThread) {
+                    return;
+                }
+            }
+        } // of sub-directories iteration
+        
+        SG_LOG(SG_AI, SG_INFO, "parsing traffic schedules took:" << st.elapsedMSec() << "msec");
+    }
+    
   FGTrafficManager* _trafficManager;
   mutable SGMutex _lock;
   bool _isFinished;
   bool _cancelThread;
-  SGPath _trafficDirPath;
+  PathList _trafficDirPaths;
+   
+// parser state
+    
+    string_list elementValueStack;
+    // record model paths which are missing, to avoid duplicate
+    // warnings when parsing traffic schedules.
+    std::set<std::string> missingModels;
+    
+    std::string mdl, livery, registration, callsign, fltrules,
+    port, timeString, departurePort, departureTime, arrivalPort, arrivalTime,
+    repeat, acType, airline, m_class, flighttype, requiredAircraft, homePort;
+    int cruiseAlt;
+    int score, acCounter;
+    double radius, offset;
+    bool heavy;
+
 };
 
 /******************************************************************************
@@ -151,12 +411,6 @@ FGTrafficManager::FGTrafficManager() :
   inited(false),
   doingInit(false),
   waitingMetarTime(0.0),
-  cruiseAlt(0),
-  score(0),
-  acCounter(0),
-  radius(0),
-  offset(0),
-  heavy(false),
   enabled("/sim/traffic-manager/enabled"),
   aiEnabled("/sim/ai/enabled"),
   realWxEnabled("/environment/realwx/enabled"),
@@ -224,14 +478,6 @@ void FGTrafficManager::shutdown()
     inited = false;
 }
 
-/// caution - this is run on the helper thread to improve startup
-/// responsiveness - do not access properties or global state from
-/// here, since there's no locking protection at all
-void FGTrafficManager::parseSchedule(const SGPath& path)
-{
-  readXML(path.str(), *this);
-}
-
 void FGTrafficManager::init()
 {
     if (!enabled) {
@@ -240,9 +486,15 @@ void FGTrafficManager::init()
 
     assert(!doingInit);
     doingInit = true;
-    if (string(fgGetString("/sim/traffic-manager/datafile")).empty()) {
+    if (string(fgGetString("/sim/traffic-manager/datafile")).empty()) {        
+        PathList dirs = globals->get_data_paths("AI/Traffic");
+        if (dirs.empty()) {
+            doingInit = false;
+            return;
+        }
+        
         scheduleParser.reset(new ScheduleParseThread(this));
-        scheduleParser->setTrafficDir(SGPath(globals->get_fg_root(), "AI/Traffic"));      
+        scheduleParser->setTrafficDirs(dirs);
         scheduleParser->start();
     } else {
         fgSetBool("/sim/traffic-manager/heuristics", false);
@@ -250,7 +502,10 @@ void FGTrafficManager::init()
         string ext = path.extension();
         if (path.extension() == "xml") {
             if (path.exists()) {
-                readXML(path.str(), *this);
+                // use a SchedulerParser to parse, but run it in this thread,
+                // i.e don't start it
+                ScheduleParseThread parser(this);
+                readXML(path.str(), parser);
             }
         } else if (path.extension() == "conf") {
             if (path.exists()) {
@@ -597,225 +852,3 @@ void FGTrafficManager::Tokenize(const string& str,
 }
 
 
-void FGTrafficManager::startXML()
-{
-    //cout << "Start XML" << endl;
-    requiredAircraft = "";
-    homePort = "";
-}
-
-void FGTrafficManager::endXML()
-{
-    //cout << "End XML" << endl;
-}
-
-void FGTrafficManager::startElement(const char *name,
-                                    const XMLAttributes & atts)
-{
-    const char *attval;
-    //cout << "Start element " << name << endl;
-    //FGTrafficManager temp;
-    //for (int i = 0; i < atts.size(); i++)
-    //  if (string(atts.getName(i)) == string("include"))
-    attval = atts.getValue("include");
-    if (attval != 0) {
-        //cout << "including " << attval << endl;
-        SGPath path = globals->get_fg_root();
-        path.append("/Traffic/");
-        path.append(attval);
-        readXML(path.str(), *this);
-    }
-    elementValueStack.push_back("");
-    //  cout << "  " << atts.getName(i) << '=' << atts.getValue(i) << endl; 
-}
-
-void FGTrafficManager::endElement(const char *name)
-{
-    //cout << "End element " << name << endl;
-    const string & value = elementValueStack.back();
-
-    if (!strcmp(name, "model"))
-        mdl = value;
-    else if (!strcmp(name, "livery"))
-        livery = value;
-    else if (!strcmp(name, "home-port"))
-        homePort = value;
-    else if (!strcmp(name, "registration"))
-        registration = value;
-    else if (!strcmp(name, "airline"))
-        airline = value;
-    else if (!strcmp(name, "actype"))
-        acType = value;
-    else if (!strcmp(name, "required-aircraft"))
-        requiredAircraft = value;
-    else if (!strcmp(name, "flighttype"))
-        flighttype = value;
-    else if (!strcmp(name, "radius"))
-        radius = atoi(value.c_str());
-    else if (!strcmp(name, "offset"))
-        offset = atoi(value.c_str());
-    else if (!strcmp(name, "performance-class"))
-        m_class = value;
-    else if (!strcmp(name, "heavy")) {
-        if (value == string("true"))
-            heavy = true;
-        else
-            heavy = false;
-    } else if (!strcmp(name, "callsign"))
-        callsign = value;
-    else if (!strcmp(name, "fltrules"))
-        fltrules = value;
-    else if (!strcmp(name, "port"))
-        port = value;
-    else if (!strcmp(name, "time"))
-        timeString = value;
-    else if (!strcmp(name, "departure")) {
-        departurePort = port;
-        departureTime = timeString;
-    } else if (!strcmp(name, "cruise-alt"))
-        cruiseAlt = atoi(value.c_str());
-    else if (!strcmp(name, "arrival")) {
-        arrivalPort = port;
-        arrivalTime = timeString;
-    } else if (!strcmp(name, "repeat"))
-        repeat = value;
-    else if (!strcmp(name, "flight")) {
-        // We have loaded and parsed all the information belonging to this flight
-        // so we temporarily store it. 
-        //cerr << "Pusing back flight " << callsign << endl;
-        //cerr << callsign  <<  " " << fltrules     << " "<< departurePort << " " <<  arrivalPort << " "
-        //   << cruiseAlt <<  " " << departureTime<< " "<< arrivalTime   << " " << repeat << endl;
-
-        //Prioritize aircraft 
-        string apt = fgGetString("/sim/presets/airport-id");
-        //cerr << "Airport information: " << apt << " " << departurePort << " " << arrivalPort << endl;
-        //if (departurePort == apt) score++;
-        //flights.push_back(new FGScheduledFlight(callsign,
-        //                                fltrules,
-        //                                departurePort,
-        //                                arrivalPort,
-        //                                cruiseAlt,
-        //                                departureTime,
-        //                                arrivalTime,
-        //                                repeat));
-        if (requiredAircraft == "") {
-            char buffer[16];
-            snprintf(buffer, 16, "%d", acCounter);
-            requiredAircraft = buffer;
-        }
-        SG_LOG(SG_AI, SG_DEBUG, "Adding flight: " << callsign << " "
-               << fltrules << " "
-               << departurePort << " "
-               << arrivalPort << " "
-               << cruiseAlt << " "
-               << departureTime << " "
-               << arrivalTime << " " << repeat << " " << requiredAircraft);
-        // For database maintainance purposes, it may be convenient to
-        // 
-        if (fgGetBool("/sim/traffic-manager/dumpdata") == true) {
-             SG_LOG(SG_AI, SG_ALERT, "Traffic Dump FLIGHT," << callsign << ","
-                          << fltrules << ","
-                          << departurePort << ","
-                          << arrivalPort << ","
-                          << cruiseAlt << ","
-                          << departureTime << ","
-                          << arrivalTime << "," << repeat << "," << requiredAircraft);
-        }
-        flights[requiredAircraft].push_back(new FGScheduledFlight(callsign,
-                                                                  fltrules,
-                                                                  departurePort,
-                                                                  arrivalPort,
-                                                                  cruiseAlt,
-                                                                  departureTime,
-                                                                  arrivalTime,
-                                                                  repeat,
-                                                                  requiredAircraft));
-        requiredAircraft = "";
-    } else if (!strcmp(name, "aircraft")) {
-        endAircraft();
-    }
-    
-    elementValueStack.pop_back();
-}
-
-void FGTrafficManager::endAircraft()
-{
-    string isHeavy = heavy ? "true" : "false";
-
-    if (missingModels.find(mdl) != missingModels.end()) {
-    // don't stat() or warn again
-        requiredAircraft = homePort = "";
-        return;
-    }
-    
-    if (!FGAISchedule::validModelPath(mdl)) {
-        missingModels.insert(mdl);
-        SG_LOG(SG_AI, SG_WARN, "TrafficMgr: Missing model path:" << mdl);
-        requiredAircraft = homePort = "";
-        return;
-    }
-        
-    int proportion =
-        (int) (fgGetDouble("/sim/traffic-manager/proportion") * 100);
-    int randval = rand() & 100;
-    if (randval > proportion) {
-        requiredAircraft = homePort = "";
-        return;
-    }
-    
-    if (fgGetBool("/sim/traffic-manager/dumpdata") == true) {
-        SG_LOG(SG_AI, SG_ALERT, "Traffic Dump AC," << homePort << "," << registration << "," << requiredAircraft
-               << "," << acType << "," << livery << "," 
-               << airline << ","  << m_class << "," << offset << "," << radius << "," << flighttype << "," << isHeavy << "," << mdl);
-    }
-
-    if (requiredAircraft == "") {
-        char buffer[16];
-        snprintf(buffer, 16, "%d", acCounter);
-        requiredAircraft = buffer;
-    }
-    if (homePort == "") {
-        homePort = departurePort;
-    }
-    
-    scheduledAircraft.push_back(new FGAISchedule(mdl,
-                                                 livery,
-                                                 homePort,
-                                                 registration,
-                                                 requiredAircraft,
-                                                 heavy,
-                                                 acType,
-                                                 airline,
-                                                 m_class,
-                                                 flighttype,
-                                                 radius, offset));
-            
-    acCounter++;
-    requiredAircraft = "";
-    homePort = "";
-    score = 0;
-}
-    
-void FGTrafficManager::data(const char *s, int len)
-{
-    string token = string(s, len);
-    //cout << "Character data " << string(s,len) << endl;
-    elementValueStack.back() += token;
-}
-
-void FGTrafficManager::pi(const char *target, const char *data)
-{
-    //cout << "Processing instruction " << target << ' ' << data << endl;
-}
-
-void FGTrafficManager::warning(const char *message, int line, int column)
-{
-    SG_LOG(SG_IO, SG_WARN,
-           "Warning: " << message << " (" << line << ',' << column << ')');
-}
-
-void FGTrafficManager::error(const char *message, int line, int column)
-{
-    SG_LOG(SG_IO, SG_ALERT,
-           "Error: " << message << " (" << line << ',' << column << ')');
-}
index c4978a8473c4e09ad8b348e3e5ac3df9378f8506..a550431e510882707e3e1e2efe5b06033bb3a9e6 100644 (file)
@@ -51,9 +51,7 @@
 
 #include <simgear/structure/subsystem_mgr.hxx>
 #include <simgear/props/propertyObject.hxx>
-#include <simgear/xml/easyxml.hxx>
 #include <simgear/misc/sg_path.hxx>
-#include <simgear/misc/sg_dir.hxx>
 
 #include "SchedFlight.hxx"
 #include "Schedule.hxx"
@@ -77,7 +75,7 @@ typedef HeuristicMap::iterator             HeuristicMapIterator;
 
 class ScheduleParseThread;
 
-class FGTrafficManager : public SGSubsystem, public XMLVisitor
+class FGTrafficManager : public SGSubsystem
 {
 private:
   bool inited;
@@ -87,24 +85,11 @@ private:
   
   ScheduleVector scheduledAircraft;
   ScheduleVectorIterator currAircraft, currAircraftClosest;
-  vector<string> elementValueStack;
-
-  // record model paths which are missing, to avoid duplicate
-  // warnings when parsing traffic schedules.
-  std::set<std::string> missingModels;
-    
-  std::string mdl, livery, registration, callsign, fltrules, 
-    port, timeString, departurePort, departureTime, arrivalPort, arrivalTime,
-    repeat, acType, airline, m_class, flighttype, requiredAircraft, homePort;
-  int cruiseAlt;
-  int score, acCounter;
-  double radius, offset;
-  bool heavy;
     
   FGScheduledFlightMap flights;
 
   void readTimeTableFromFile(SGPath infilename);
-  void Tokenize(const string& str, vector<string>& tokens, const string& delimiters = " ");
+    void Tokenize(const std::string& str, std::vector<std::string>& tokens, const std::string& delimiters = " ");
 
   simgear::PropertyObject<bool> enabled, aiEnabled, realWxEnabled, metarValid;
   
@@ -129,20 +114,9 @@ public:
   void init();
   void update(double time);
 
-  FGScheduledFlightVecIterator getFirstFlight(const string &ref) { return flights[ref].begin(); }
-  FGScheduledFlightVecIterator getLastFlight(const string &ref) { return flights[ref].end(); }
+    FGScheduledFlightVecIterator getFirstFlight(const std::string &ref) { return flights[ref].begin(); }
+    FGScheduledFlightVecIterator getLastFlight(const std::string &ref) { return flights[ref].end(); }
 
-  void endAircraft();
-  
-  // Some overloaded virtual XMLVisitor members
-  virtual void startXML (); 
-  virtual void endXML   ();
-  virtual void startElement (const char * name, const XMLAttributes &atts);
-  virtual void endElement (const char * name);
-  virtual void data (const char * s, int len);
-  virtual void pi (const char * target, const char * data);
-  virtual void warning (const char * message, int line, int column);
-  virtual void error (const char * message, int line, int column);
 };
 
 #endif