114
125
virtual void run()
119
simgear::Dir trafficDir(_trafficDirPath);
120
simgear::PathList d = trafficDir.children(simgear::Dir::TYPE_DIR | simgear::Dir::NO_DOT_OR_DOTDOT);
122
BOOST_FOREACH(SGPath p, d) {
124
simgear::PathList trafficFiles = d2.children(simgear::Dir::TYPE_FILE, ".xml");
125
BOOST_FOREACH(SGPath xml, trafficFiles) {
126
_trafficManager->parseSchedule(xml);
127
BOOST_FOREACH(SGPath p, _trafficDirPaths) {
131
} // of sub-directories in AI/Traffic iteration
133
// _trafficManager->parseSchedules(schedulesToRead);
134
SG_LOG(SG_AI, SG_INFO, "parsing traffic schedules took:" << st.elapsedMSec() << "msec");
136
134
SGGuard<SGMutex> g(_lock);
137
135
_isFinished = true;
140
//cout << "Start XML" << endl;
141
requiredAircraft = "";
147
//cout << "End XML" << endl;
150
void startElement(const char *name,
151
const XMLAttributes & atts)
154
//cout << "Start element " << name << endl;
155
//FGTrafficManager temp;
156
//for (int i = 0; i < atts.size(); i++)
157
// if (string(atts.getName(i)) == string("include"))
158
attval = atts.getValue("include");
160
//cout << "including " << attval << endl;
161
SGPath path = globals->get_fg_root();
162
path.append("/Traffic/");
164
readXML(path.str(), *this);
166
elementValueStack.push_back("");
167
// cout << " " << atts.getName(i) << '=' << atts.getValue(i) << endl;
170
void endElement(const char *name)
172
//cout << "End element " << name << endl;
173
const string & value = elementValueStack.back();
175
if (!strcmp(name, "model"))
177
else if (!strcmp(name, "livery"))
179
else if (!strcmp(name, "home-port"))
181
else if (!strcmp(name, "registration"))
182
registration = value;
183
else if (!strcmp(name, "airline"))
185
else if (!strcmp(name, "actype"))
187
else if (!strcmp(name, "required-aircraft"))
188
requiredAircraft = value;
189
else if (!strcmp(name, "flighttype"))
191
else if (!strcmp(name, "radius"))
192
radius = atoi(value.c_str());
193
else if (!strcmp(name, "offset"))
194
offset = atoi(value.c_str());
195
else if (!strcmp(name, "performance-class"))
197
else if (!strcmp(name, "heavy")) {
198
if (value == string("true"))
202
} else if (!strcmp(name, "callsign"))
204
else if (!strcmp(name, "fltrules"))
206
else if (!strcmp(name, "port"))
208
else if (!strcmp(name, "time"))
210
else if (!strcmp(name, "departure")) {
211
departurePort = port;
212
departureTime = timeString;
213
} else if (!strcmp(name, "cruise-alt"))
214
cruiseAlt = atoi(value.c_str());
215
else if (!strcmp(name, "arrival")) {
217
arrivalTime = timeString;
218
} else if (!strcmp(name, "repeat"))
220
else if (!strcmp(name, "flight")) {
221
// We have loaded and parsed all the information belonging to this flight
222
// so we temporarily store it.
223
//cerr << "Pusing back flight " << callsign << endl;
224
//cerr << callsign << " " << fltrules << " "<< departurePort << " " << arrivalPort << " "
225
// << cruiseAlt << " " << departureTime<< " "<< arrivalTime << " " << repeat << endl;
227
//Prioritize aircraft
228
string apt = fgGetString("/sim/presets/airport-id");
229
//cerr << "Airport information: " << apt << " " << departurePort << " " << arrivalPort << endl;
230
//if (departurePort == apt) score++;
231
//flights.push_back(new FGScheduledFlight(callsign,
239
if (requiredAircraft == "") {
241
snprintf(buffer, 16, "%d", acCounter);
242
requiredAircraft = buffer;
244
SG_LOG(SG_AI, SG_DEBUG, "Adding flight: " << callsign << " "
246
<< departurePort << " "
247
<< arrivalPort << " "
249
<< departureTime << " "
250
<< arrivalTime << " " << repeat << " " << requiredAircraft);
251
// For database maintainance purposes, it may be convenient to
253
if (fgGetBool("/sim/traffic-manager/dumpdata") == true) {
254
SG_LOG(SG_AI, SG_ALERT, "Traffic Dump FLIGHT," << callsign << ","
256
<< departurePort << ","
257
<< arrivalPort << ","
259
<< departureTime << ","
260
<< arrivalTime << "," << repeat << "," << requiredAircraft);
263
_trafficManager->flights[requiredAircraft].push_back(new FGScheduledFlight(callsign,
272
requiredAircraft = "";
273
} else if (!strcmp(name, "aircraft")) {
277
elementValueStack.pop_back();
281
void data(const char *s, int len)
283
string token = string(s, len);
284
//cout << "Character data " << string(s,len) << endl;
285
elementValueStack.back() += token;
288
void pi(const char *target, const char *data)
290
//cout << "Processing instruction " << target << ' ' << data << endl;
293
void warning(const char *message, int line, int column)
295
SG_LOG(SG_IO, SG_WARN,
296
"Warning: " << message << " (" << line << ',' << column << ')');
299
void error(const char *message, int line, int column)
301
SG_LOG(SG_IO, SG_ALERT,
302
"Error: " << message << " (" << line << ',' << column << ')');
308
string isHeavy = heavy ? "true" : "false";
310
if (missingModels.find(mdl) != missingModels.end()) {
311
// don't stat() or warn again
312
requiredAircraft = homePort = "";
316
if (!FGAISchedule::validModelPath(mdl)) {
317
missingModels.insert(mdl);
318
SG_LOG(SG_AI, SG_WARN, "TrafficMgr: Missing model path:" << mdl);
319
requiredAircraft = homePort = "";
324
(int) (fgGetDouble("/sim/traffic-manager/proportion") * 100);
325
int randval = rand() & 100;
326
if (randval > proportion) {
327
requiredAircraft = homePort = "";
331
if (fgGetBool("/sim/traffic-manager/dumpdata") == true) {
332
SG_LOG(SG_AI, SG_ALERT, "Traffic Dump AC," << homePort << "," << registration << "," << requiredAircraft
333
<< "," << acType << "," << livery << ","
334
<< airline << "," << m_class << "," << offset << "," << radius << "," << flighttype << "," << isHeavy << "," << mdl);
337
if (requiredAircraft == "") {
339
snprintf(buffer, 16, "%d", acCounter);
340
requiredAircraft = buffer;
342
if (homePort == "") {
343
homePort = departurePort;
346
// caution, modifying the scheduled aircraft strucutre from the
347
// 'wrong' thread. This is safe becuase FGTrafficManager won't touch
348
// the structure while we exist.
349
_trafficManager->scheduledAircraft.push_back(new FGAISchedule(mdl,
362
requiredAircraft = "";
367
void parseTrafficDir(const SGPath& path)
372
simgear::Dir trafficDir(path);
373
simgear::PathList d = trafficDir.children(simgear::Dir::TYPE_DIR | simgear::Dir::NO_DOT_OR_DOTDOT);
375
BOOST_FOREACH(SGPath p, d) {
377
SG_LOG(SG_AI, SG_INFO, "parsing traffic in:" << p);
378
simgear::PathList trafficFiles = d2.children(simgear::Dir::TYPE_FILE, ".xml");
379
BOOST_FOREACH(SGPath xml, trafficFiles) {
380
readXML(xml.str(), *this);
385
} // of sub-directories iteration
387
SG_LOG(SG_AI, SG_INFO, "parsing traffic schedules took:" << st.elapsedMSec() << "msec");
140
390
FGTrafficManager* _trafficManager;
141
391
mutable SGMutex _lock;
142
392
bool _isFinished;
143
393
bool _cancelThread;
144
SGPath _trafficDirPath;
394
PathList _trafficDirPaths;
398
string_list elementValueStack;
399
// record model paths which are missing, to avoid duplicate
400
// warnings when parsing traffic schedules.
401
std::set<std::string> missingModels;
403
std::string mdl, livery, registration, callsign, fltrules,
404
port, timeString, departurePort, departureTime, arrivalPort, arrivalTime,
405
repeat, acType, airline, m_class, flighttype, requiredAircraft, homePort;
407
int score, acCounter;
408
double radius, offset;
147
413
/******************************************************************************
601
void FGTrafficManager::startXML()
603
//cout << "Start XML" << endl;
604
requiredAircraft = "";
608
void FGTrafficManager::endXML()
610
//cout << "End XML" << endl;
613
void FGTrafficManager::startElement(const char *name,
614
const XMLAttributes & atts)
617
//cout << "Start element " << name << endl;
618
//FGTrafficManager temp;
619
//for (int i = 0; i < atts.size(); i++)
620
// if (string(atts.getName(i)) == string("include"))
621
attval = atts.getValue("include");
623
//cout << "including " << attval << endl;
624
SGPath path = globals->get_fg_root();
625
path.append("/Traffic/");
627
readXML(path.str(), *this);
629
elementValueStack.push_back("");
630
// cout << " " << atts.getName(i) << '=' << atts.getValue(i) << endl;
633
void FGTrafficManager::endElement(const char *name)
635
//cout << "End element " << name << endl;
636
const string & value = elementValueStack.back();
638
if (!strcmp(name, "model"))
640
else if (!strcmp(name, "livery"))
642
else if (!strcmp(name, "home-port"))
644
else if (!strcmp(name, "registration"))
645
registration = value;
646
else if (!strcmp(name, "airline"))
648
else if (!strcmp(name, "actype"))
650
else if (!strcmp(name, "required-aircraft"))
651
requiredAircraft = value;
652
else if (!strcmp(name, "flighttype"))
654
else if (!strcmp(name, "radius"))
655
radius = atoi(value.c_str());
656
else if (!strcmp(name, "offset"))
657
offset = atoi(value.c_str());
658
else if (!strcmp(name, "performance-class"))
660
else if (!strcmp(name, "heavy")) {
661
if (value == string("true"))
665
} else if (!strcmp(name, "callsign"))
667
else if (!strcmp(name, "fltrules"))
669
else if (!strcmp(name, "port"))
671
else if (!strcmp(name, "time"))
673
else if (!strcmp(name, "departure")) {
674
departurePort = port;
675
departureTime = timeString;
676
} else if (!strcmp(name, "cruise-alt"))
677
cruiseAlt = atoi(value.c_str());
678
else if (!strcmp(name, "arrival")) {
680
arrivalTime = timeString;
681
} else if (!strcmp(name, "repeat"))
683
else if (!strcmp(name, "flight")) {
684
// We have loaded and parsed all the information belonging to this flight
685
// so we temporarily store it.
686
//cerr << "Pusing back flight " << callsign << endl;
687
//cerr << callsign << " " << fltrules << " "<< departurePort << " " << arrivalPort << " "
688
// << cruiseAlt << " " << departureTime<< " "<< arrivalTime << " " << repeat << endl;
690
//Prioritize aircraft
691
string apt = fgGetString("/sim/presets/airport-id");
692
//cerr << "Airport information: " << apt << " " << departurePort << " " << arrivalPort << endl;
693
//if (departurePort == apt) score++;
694
//flights.push_back(new FGScheduledFlight(callsign,
702
if (requiredAircraft == "") {
704
snprintf(buffer, 16, "%d", acCounter);
705
requiredAircraft = buffer;
707
SG_LOG(SG_AI, SG_DEBUG, "Adding flight: " << callsign << " "
709
<< departurePort << " "
710
<< arrivalPort << " "
712
<< departureTime << " "
713
<< arrivalTime << " " << repeat << " " << requiredAircraft);
714
// For database maintainance purposes, it may be convenient to
716
if (fgGetBool("/sim/traffic-manager/dumpdata") == true) {
717
SG_LOG(SG_AI, SG_ALERT, "Traffic Dump FLIGHT," << callsign << ","
719
<< departurePort << ","
720
<< arrivalPort << ","
722
<< departureTime << ","
723
<< arrivalTime << "," << repeat << "," << requiredAircraft);
725
flights[requiredAircraft].push_back(new FGScheduledFlight(callsign,
734
requiredAircraft = "";
735
} else if (!strcmp(name, "aircraft")) {
739
elementValueStack.pop_back();
742
void FGTrafficManager::endAircraft()
744
string isHeavy = heavy ? "true" : "false";
746
if (missingModels.find(mdl) != missingModels.end()) {
747
// don't stat() or warn again
748
requiredAircraft = homePort = "";
752
if (!FGAISchedule::validModelPath(mdl)) {
753
missingModels.insert(mdl);
754
SG_LOG(SG_AI, SG_WARN, "TrafficMgr: Missing model path:" << mdl);
755
requiredAircraft = homePort = "";
760
(int) (fgGetDouble("/sim/traffic-manager/proportion") * 100);
761
int randval = rand() & 100;
762
if (randval > proportion) {
763
requiredAircraft = homePort = "";
767
if (fgGetBool("/sim/traffic-manager/dumpdata") == true) {
768
SG_LOG(SG_AI, SG_ALERT, "Traffic Dump AC," << homePort << "," << registration << "," << requiredAircraft
769
<< "," << acType << "," << livery << ","
770
<< airline << "," << m_class << "," << offset << "," << radius << "," << flighttype << "," << isHeavy << "," << mdl);
773
if (requiredAircraft == "") {
775
snprintf(buffer, 16, "%d", acCounter);
776
requiredAircraft = buffer;
778
if (homePort == "") {
779
homePort = departurePort;
782
scheduledAircraft.push_back(new FGAISchedule(mdl,
795
requiredAircraft = "";
800
void FGTrafficManager::data(const char *s, int len)
802
string token = string(s, len);
803
//cout << "Character data " << string(s,len) << endl;
804
elementValueStack.back() += token;
807
void FGTrafficManager::pi(const char *target, const char *data)
809
//cout << "Processing instruction " << target << ' ' << data << endl;
812
void FGTrafficManager::warning(const char *message, int line, int column)
814
SG_LOG(SG_IO, SG_WARN,
815
"Warning: " << message << " (" << line << ',' << column << ')');
818
void FGTrafficManager::error(const char *message, int line, int column)
820
SG_LOG(SG_IO, SG_ALERT,
821
"Error: " << message << " (" << line << ',' << column << ')');