From 9eb0f67a821b72dc41ecf2e3b36ab249cf020a38 Mon Sep 17 00:00:00 2001 From: James Turner Date: Mon, 23 Apr 2012 15:03:08 +0100 Subject: [PATCH] Make traffic-manager schedule XML loading incremental, to avoid a long pause during startup. --- src/Traffic/CMakeLists.txt | 11 ++- src/Traffic/TrafficMgr.cxx | 171 ++++++++++++++++++++----------------- src/Traffic/TrafficMgr.hxx | 10 +++ 3 files changed, 114 insertions(+), 78 deletions(-) diff --git a/src/Traffic/CMakeLists.txt b/src/Traffic/CMakeLists.txt index 6b6bfc88a..adc7fcd2d 100644 --- a/src/Traffic/CMakeLists.txt +++ b/src/Traffic/CMakeLists.txt @@ -5,5 +5,12 @@ set(SOURCES Schedule.cxx TrafficMgr.cxx ) - -flightgear_component(Traffic "${SOURCES}") \ No newline at end of file + +set(HEADERS + SchedFlight.hxx + Schedule.hxx + TrafficMgr.hxx +) + + +flightgear_component(Traffic "${SOURCES}" "${HEADERS}") \ No newline at end of file diff --git a/src/Traffic/TrafficMgr.cxx b/src/Traffic/TrafficMgr.cxx index 44e85676d..9822bea6c 100644 --- a/src/Traffic/TrafficMgr.cxx +++ b/src/Traffic/TrafficMgr.cxx @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -77,6 +78,7 @@ using std::strcmp; *****************************************************************************/ FGTrafficManager::FGTrafficManager() : inited(false), + doingInit(false), enabled("/sim/traffic-manager/enabled"), aiEnabled("/sim/ai/enabled"), realWxEnabled("/environment/realwx/enabled"), @@ -135,23 +137,17 @@ void FGTrafficManager::init() if (!enabled || !aiEnabled) { return; } - - heuristicsVector heuristics; - HeuristicMap heurMap; + assert(!doingInit); + doingInit = true; if (string(fgGetString("/sim/traffic-manager/datafile")) == string("")) { simgear::Dir trafficDir(SGPath(globals->get_fg_root(), "AI/Traffic")); simgear::PathList d = trafficDir.children(simgear::Dir::TYPE_DIR | simgear::Dir::NO_DOT_OR_DOTDOT); - for (unsigned int i=0; i> revisionStr; - if (revisionStr != "[TrafficManagerCachedata:ref:2011:09:04]") { - SG_LOG(SG_GENERAL, SG_ALERT,"Traffic Manager Warning: discarding outdated cachefile " << - cacheData.c_str() << " for Airport " << airport); - } else { - while (1) { - Heuristic h; // = new Heuristic; - data >> h.registration >> h.runCount >> h.hits >> h.lastRun; - if (data.eof()) - break; - HeuristicMapIterator itr = heurMap.find(h.registration); - if (itr != heurMap.end()) { - SG_LOG(SG_GENERAL, SG_WARN,"Traffic Manager Warning: found duplicate tailnumber " << - h.registration << " for AI aircraft"); - } else { - heurMap[h.registration] = h; - heuristics.push_back(h); - } - } - } - } - } - for (currAircraft = scheduledAircraft.begin(); - currAircraft != scheduledAircraft.end(); currAircraft++) { - string registration = (*currAircraft)->getRegistration(); - HeuristicMapIterator itr = heurMap.find(registration); - //cerr << "Processing heuristics for" << (*currAircraft)->getRegistration() << endl; - if (itr == heurMap.end()) { - //cerr << "No heuristics found for " << registration << endl; - } else { - (*currAircraft)->setrunCount(itr->second.runCount); - (*currAircraft)->setHits(itr->second.hits); - (*currAircraft)->setLastUsed(itr->second.lastRun); - //cerr <<"Runcount " << itr->second.runCount << ". Hits " << itr->second.hits << ". Last run " << itr->second.lastRun<< endl; - } - } - //cerr << "Done" << endl; - //for (heuristicsVectorIterator hvi = heuristics.begin(); - // hvi != heuristics.end(); hvi++) { - // delete(*hvi); - //} +} + +void FGTrafficManager::initStep() +{ + assert(doingInit); + if (schedulesToRead.empty()) { + finishInit(); + return; } + + SGPath path = schedulesToRead.front(); + schedulesToRead.erase(schedulesToRead.begin()); + SG_LOG(SG_AI, SG_DEBUG, path << " for traffic"); + readXML(path.str(), *this); +} + +void FGTrafficManager::finishInit() +{ + assert(doingInit); + SG_LOG(SG_AI, SG_INFO, "finishing AI-Traffic init"); + loadHeuristics(); + // Do sorting and scoring separately, to take advantage of the "homeport| variable for (currAircraft = scheduledAircraft.begin(); currAircraft != scheduledAircraft.end(); currAircraft++) { (*currAircraft)->setScore(); } - + sort(scheduledAircraft.begin(), scheduledAircraft.end(), compareSchedules); currAircraft = scheduledAircraft.begin(); currAircraftClosest = scheduledAircraft.begin(); + + doingInit = false; inited = true; } +void FGTrafficManager::loadHeuristics() +{ + if (!fgGetBool("/sim/traffic-manager/heuristics")) { + return; + } + + HeuristicMap heurMap; + //cerr << "Processing Heuristics" << endl; + // Load the heuristics data + SGPath cacheData(fgGetString("/sim/fg-home")); + cacheData.append("ai"); + string airport = fgGetString("/sim/presets/airport-id"); + if ((airport) != "") { + char buffer[128]; + ::snprintf(buffer, 128, "%c/%c/%c/", + airport[0], airport[1], airport[2]); + cacheData.append(buffer); + cacheData.append(airport + "-cache.txt"); + string revisionStr; + if (cacheData.exists()) { + ifstream data(cacheData.c_str()); + data >> revisionStr; + if (revisionStr != "[TrafficManagerCachedata:ref:2011:09:04]") { + SG_LOG(SG_GENERAL, SG_ALERT,"Traffic Manager Warning: discarding outdated cachefile " << + cacheData.c_str() << " for Airport " << airport); + } else { + while (1) { + Heuristic h; // = new Heuristic; + data >> h.registration >> h.runCount >> h.hits >> h.lastRun; + if (data.eof()) + break; + HeuristicMapIterator itr = heurMap.find(h.registration); + if (itr != heurMap.end()) { + SG_LOG(SG_GENERAL, SG_WARN,"Traffic Manager Warning: found duplicate tailnumber " << + h.registration << " for AI aircraft"); + } else { + heurMap[h.registration] = h; + } + } + } + } + } + + for(currAircraft = scheduledAircraft.begin(); currAircraft != scheduledAircraft.end(); ++currAircraft) { + string registration = (*currAircraft)->getRegistration(); + HeuristicMapIterator itr = heurMap.find(registration); + if (itr != heurMap.end()) { + (*currAircraft)->setrunCount(itr->second.runCount); + (*currAircraft)->setHits(itr->second.hits); + (*currAircraft)->setLastUsed(itr->second.lastRun); + } + } +} + void FGTrafficManager::update(double /*dt */ ) { if (!enabled || !aiEnabled || (realWxEnabled && !metarValid)) { @@ -249,9 +266,14 @@ void FGTrafficManager::update(double /*dt */ ) } if (!inited) { - // lazy-initialization, we've been enabled at run-time - SG_LOG(SG_GENERAL, SG_INFO, "doing lazy-init of TrafficManager"); - init(); + if (!doingInit) { + init(); + } + + initStep(); + if (!inited) { + return; // still more to do on next update() call + } } time_t now = time(NULL) + fgGetLong("/sim/time/warp"); @@ -259,10 +281,7 @@ void FGTrafficManager::update(double /*dt */ ) return; } - SGVec3d userCart = - SGVec3d::fromGeod(SGGeod:: - fromDeg(fgGetDouble("/position/longitude-deg"), - fgGetDouble("/position/latitude-deg"))); + SGVec3d userCart = globals->get_aircraft_positon_cart(); if (currAircraft == scheduledAircraft.end()) { currAircraft = scheduledAircraft.begin(); diff --git a/src/Traffic/TrafficMgr.hxx b/src/Traffic/TrafficMgr.hxx index c8f9faca1..aab3c8ae3 100644 --- a/src/Traffic/TrafficMgr.hxx +++ b/src/Traffic/TrafficMgr.hxx @@ -50,6 +50,7 @@ #include #include #include +#include #include "SchedFlight.hxx" #include "Schedule.hxx" @@ -80,6 +81,7 @@ class FGTrafficManager : public SGSubsystem, public XMLVisitor { private: bool inited; + bool doingInit; ScheduleVector scheduledAircraft; ScheduleVectorIterator currAircraft, currAircraftClosest; @@ -101,6 +103,14 @@ private: void Tokenize(const string& str, vector& tokens, const string& delimiters = " "); simgear::PropertyObject enabled, aiEnabled, realWxEnabled, metarValid; + + void loadHeuristics(); + + void initStep(); + void finishInit(); + + // during incremental init, contains the XML files still be read in + simgear::PathList schedulesToRead; public: FGTrafficManager(); ~FGTrafficManager(); -- 2.39.5