1
0
Fork 0
terragear/src/Airports/GenAirports850/scheduler.cxx
2012-11-29 09:51:11 +01:00

514 lines
14 KiB
C++

#ifdef _MSC_VER
# include <windows.h>
# define sleep(x) Sleep(x*1000)
#endif
#include <cstring>
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sgstream.hxx>
#include "airport.hxx"
#include "parser.hxx"
#include "scheduler.hxx"
extern double gSnap;
SGLockedQueue<AirportInfo> global_workQueue;
ostream& operator<< (ostream &out, const AirportInfo &ai)
{
char snap_string[32];
sprintf( snap_string, "%1.8lf", ai.snap );
out << ai.icao;
out << ",";
out << ai.numRunways;
out << ",";
out << ai.numPavements;
out << ",";
out << ai.numFeats;
out << ",";
out << ai.numTaxiways;
out << ",";
out << ai.parseTime;
out << ",";
out << ai.buildTime;
out << ",";
out << ai.cleanTime;
out << ",";
out << ai.tessTime;
out << ",";
out << ai.parseTime+ai.buildTime+ai.cleanTime+ai.tessTime;
out << ",";
out << snap_string,
out << ",";
out << ai.errString;
return out; // MSVC
}
void Scheduler::set_debug( std::string path, std::vector<std::string> runway_defs,
std::vector<std::string> pavement_defs,
std::vector<std::string> taxiway_defs,
std::vector<std::string> feature_defs )
{
GENAPT_LOG(SG_GENERAL, SG_ALERT, "Set debug Path " << path);
debug_path = path;
/* Find any ids for our tile */
for (unsigned int i=0; i< runway_defs.size(); i++) {
std::string dsd = runway_defs[i];
size_t d_pos = dsd.find(":");
std::string icao = dsd.substr(0, d_pos);
std::vector<int> shapes;
shapes.clear();
dsd.erase(0, d_pos+1);
if ( dsd == "all" ) {
shapes.push_back( std::numeric_limits<int>::max() );
} else {
std::stringstream ss(dsd);
int i;
while (ss >> i)
{
GENAPT_LOG(SG_GENERAL, SG_ALERT, "Adding debug runway " << i << " for " << icao );
shapes.push_back(i);
if (ss.peek() == ',')
ss.ignore();
}
}
debug_runways[icao] = shapes;
}
for (unsigned int i=0; i< pavement_defs.size(); i++) {
std::string dsd = pavement_defs[i];
size_t d_pos = dsd.find(":");
std::string icao = dsd.substr(0, d_pos);
std::vector<int> shapes;
shapes.clear();
dsd.erase(0, d_pos+1);
if ( dsd == "all" ) {
shapes.push_back( std::numeric_limits<int>::max() );
} else {
std::stringstream ss(dsd);
int i;
while (ss >> i)
{
GENAPT_LOG(SG_GENERAL, SG_ALERT, "Adding debug pavement " << i << " for " << icao );
shapes.push_back(i);
if (ss.peek() == ',')
ss.ignore();
}
}
debug_pavements[icao] = shapes;
}
for (unsigned int i=0; i< taxiway_defs.size(); i++) {
std::string dsd = taxiway_defs[i];
size_t d_pos = dsd.find(":");
std::string icao = dsd.substr(0, d_pos);
std::vector<int> shapes;
shapes.clear();
dsd.erase(0, d_pos+1);
if ( dsd == "all" ) {
shapes.push_back( std::numeric_limits<int>::max() );
} else {
std::stringstream ss(dsd);
int i;
while (ss >> i)
{
GENAPT_LOG(SG_GENERAL, SG_ALERT, "Adding debug taxiway " << i << " for " << icao );
shapes.push_back(i);
if (ss.peek() == ',')
ss.ignore();
}
}
debug_taxiways[icao] = shapes;
}
for (unsigned int i=0; i< feature_defs.size(); i++) {
std::string dsd = feature_defs[i];
size_t d_pos = dsd.find(":");
std::string icao = dsd.substr(0, d_pos);
std::vector<int> shapes;
shapes.clear();
dsd.erase(0, d_pos+1);
if ( dsd == "all" ) {
shapes.push_back( std::numeric_limits<int>::max() );
} else {
std::stringstream ss(dsd);
int i;
while (ss >> i)
{
GENAPT_LOG(SG_GENERAL, SG_ALERT, "Adding debug feature " << i << " for " << icao );
shapes.push_back(i);
if (ss.peek() == ',')
ss.ignore();
}
}
debug_features[icao] = shapes;
}
}
bool Scheduler::IsAirportDefinition( char* line, std::string icao )
{
char* tok;
int code;
Airport* airport = NULL;
bool match = false;
// Get the number code
tok = strtok(line, " \t\r\n");
if (tok)
{
line += strlen(tok)+1;
code = atoi(tok);
switch(code)
{
case LAND_AIRPORT_CODE:
case SEA_AIRPORT_CODE:
case HELIPORT_CODE:
airport = new Airport( code, line );
if ( airport->GetIcao() == icao )
{
match = true;
}
break;
case LAND_RUNWAY_CODE:
case WATER_RUNWAY_CODE:
case HELIPAD_CODE:
case PAVEMENT_CODE:
case LINEAR_FEATURE_CODE:
case BOUNDRY_CODE:
case NODE_CODE:
case BEZIER_NODE_CODE:
case CLOSE_NODE_CODE:
case CLOSE_BEZIER_NODE_CODE:
case TERM_NODE_CODE:
case TERM_BEZIER_NODE_CODE:
case AIRPORT_VIEWPOINT_CODE:
case AIRPLANE_STARTUP_LOCATION_CODE:
case LIGHT_BEACON_CODE:
case WINDSOCK_CODE:
case TAXIWAY_SIGN:
case LIGHTING_OBJECT:
case COMM_FREQ1_CODE:
case COMM_FREQ2_CODE:
case COMM_FREQ3_CODE:
case COMM_FREQ4_CODE:
case COMM_FREQ5_CODE:
case COMM_FREQ6_CODE:
case COMM_FREQ7_CODE:
case END_OF_FILE :
break;
}
}
return match;
}
void Scheduler::AddAirport( std::string icao )
{
char line[2048];
long cur_pos;
bool found = false;
AirportInfo ai;
std::ifstream in( filename.c_str() );
if ( !in.is_open() )
{
GENAPT_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << filename );
exit(-1);
}
GENAPT_LOG( SG_GENERAL, SG_INFO, "Adding airport " << icao << " to parse list");
while ( !in.eof() && !found )
{
// remember the position of this line
cur_pos = in.tellg();
// get a line
in.getline(line, 2048);
// this is and airport definition - remember it
if ( IsAirportDefinition( line, icao ) )
{
GENAPT_LOG( SG_GENERAL, SG_DEBUG, "Found airport " << icao << " at " << cur_pos );
ai = AirportInfo( icao, cur_pos, gSnap );
global_workQueue.push( ai );
found = true;
}
}
}
long Scheduler::FindAirport( std::string icao )
{
char line[2048];
long cur_pos = 0;
bool found = false;
std::ifstream in( filename.c_str() );
if ( !in.is_open() )
{
GENAPT_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << filename );
exit(-1);
}
GENAPT_LOG( SG_GENERAL, SG_DEBUG, "Finding airport " << icao );
while ( !in.eof() && !found )
{
// remember the position of this line
cur_pos = in.tellg();
// get a line
in.getline(line, 2048);
// this is and airport definition - remember it
if ( IsAirportDefinition( line, icao ) )
{
GENAPT_LOG( SG_GENERAL, SG_DEBUG, "Found airport " << line << " at " << cur_pos );
found = true;
}
}
if (found)
{
return cur_pos;
}
else
{
return 0;
}
}
void Scheduler::RetryAirport( AirportInfo* pai )
{
// retryList.push_back( *pai );
}
bool Scheduler::AddAirports( long start_pos, tg::Rectangle* boundingBox )
{
char line[2048];
char* def;
long cur_pos;
long cur_apt_pos = 0;
std::string cur_apt_name;
char* tok;
int code;
bool match;
bool done;
done = false;
match = false;
// start from current position, and push all airports where a runway start or end
// lies within the given min/max coordinates
std::ifstream in( filename.c_str() );
if ( !in.is_open() )
{
GENAPT_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << filename );
exit(-1);
}
if (start_pos)
{
in.seekg(start_pos, std::ios::beg);
}
while (!done)
{
// remember the position of this line
cur_pos = in.tellg();
// get a line
in.getline(line, 2048);
def = &line[0];
// Get the number code
tok = strtok(def, " \t\r\n");
if (tok)
{
def += strlen(tok)+1;
code = atoi(tok);
switch(code)
{
case LAND_AIRPORT_CODE:
case SEA_AIRPORT_CODE:
case HELIPORT_CODE:
{
Airport* airport = new Airport( code, def );
if (match)
{
// Start off with given snap value
AirportInfo ai = AirportInfo( cur_apt_name, cur_apt_pos, gSnap );
global_workQueue.push( ai );
}
// remember this new apt pos and name, and clear match
cur_apt_pos = cur_pos;
cur_apt_name = airport->GetIcao();
delete airport;
match = false;
}
break;
case END_OF_FILE:
if (match)
{
// Start off with given snap value
AirportInfo ai = AirportInfo( cur_apt_name, cur_apt_pos, gSnap );
global_workQueue.push( ai );
}
done = true;
break;
case LAND_RUNWAY_CODE:
// if the the runway start / end coords are within the rect,
// we have a winner
{
Runway* runway = new Runway(def);
if ( boundingBox->isInside(runway->GetStart()) ) {
match = true;
}
else if ( boundingBox->isInside(runway->GetEnd()) ) {
match = true;
}
delete runway;
}
break;
case WATER_RUNWAY_CODE:
// if the the runway start / end coords are within the rect,
// we have a winner
{
WaterRunway* runway = new WaterRunway(def);
if ( boundingBox->isInside(runway->GetStart()) ) {
match = true;
}
else if ( boundingBox->isInside(runway->GetEnd()) ) {
match = true;
}
delete runway;
}
break;
case HELIPAD_CODE:
// if the heliport coords are within the rect, we have
// a winner
{
Helipad* helipad = new Helipad(def);
if ( boundingBox->isInside(helipad->GetLoc()) ) {
match = true;
}
delete helipad;
}
break;
case TAXIWAY_CODE:
case PAVEMENT_CODE:
case LINEAR_FEATURE_CODE:
case BOUNDRY_CODE:
case NODE_CODE:
case BEZIER_NODE_CODE:
case CLOSE_NODE_CODE:
case CLOSE_BEZIER_NODE_CODE:
case TERM_NODE_CODE:
case TERM_BEZIER_NODE_CODE:
case AIRPORT_VIEWPOINT_CODE:
case AIRPLANE_STARTUP_LOCATION_CODE:
case LIGHT_BEACON_CODE:
case WINDSOCK_CODE:
case TAXIWAY_SIGN:
case LIGHTING_OBJECT:
case COMM_FREQ1_CODE:
case COMM_FREQ2_CODE:
case COMM_FREQ3_CODE:
case COMM_FREQ4_CODE:
case COMM_FREQ5_CODE:
case COMM_FREQ6_CODE:
case COMM_FREQ7_CODE:
break;
}
}
}
// did we add airports to the parse list?
if ( global_workQueue.size() ) {
return true;
} else {
return false;
}
}
Scheduler::Scheduler(std::string& datafile, const std::string& root, const string_list& elev_src)
{
filename = datafile;
work_dir = root;
elevation = elev_src;
std::ifstream in( filename.c_str() );
if ( !in.is_open() )
{
GENAPT_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << filename );
exit(-1);
}
}
void Scheduler::Schedule( int num_threads, std::string& summaryfile )
{
// std::ofstream csvfile;
// open and truncate the summary file : monitor only appends
// csvfile.open( summaryfile.c_str(), std::ios_base::out | std::ios_base::trunc );
// csvfile.close();
std::vector<Parser *> parsers;
for (int i=0; i<num_threads; i++) {
Parser* parser = new Parser( filename, work_dir, elevation );
// parser->set_debug();
parser->start();
parsers.push_back( parser );
}
while (!global_workQueue.empty()) {
sleep(1);
}
// Then wait until they are finished
for (unsigned int i=0; i<parsers.size(); i++) {
parsers[i]->join();
}
}