From ac1fc699b7ef2a5e56210b4bb34d295c3d44976d Mon Sep 17 00:00:00 2001 From: Stuart Buchanan Date: Wed, 19 Sep 2012 22:33:43 +0100 Subject: [PATCH] Expose surface types and taxiways via the airportinfo() Nasal call. --- src/Airports/simple.cxx | 19 +++++++- src/Airports/simple.hxx | 7 ++- src/Scripting/NasalPositioned.cxx | 72 +++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 3 deletions(-) diff --git a/src/Airports/simple.cxx b/src/Airports/simple.cxx index 613be049f..adfc3cb91 100644 --- a/src/Airports/simple.cxx +++ b/src/Airports/simple.cxx @@ -69,7 +69,7 @@ FGAirport::FGAirport(PositionedID aGuid, const string &id, const SGGeod& locatio _dynamics(0), mTowerDataLoaded(false), mRunwaysLoaded(false), - mTaxiwaysLoaded(true) + mTaxiwaysLoaded(false) { } @@ -234,10 +234,27 @@ unsigned int FGAirport::numTaxiways() const FGTaxiway* FGAirport::getTaxiwayByIndex(unsigned int aIndex) const { loadTaxiways(); + assert(aIndex >= 0 && aIndex < mTaxiways.size()); return (FGTaxiway*) flightgear::NavDataCache::instance()->loadById(mTaxiways[aIndex]); } +bool FGAirport::hasTaxiwayWithIdent(const string& aIdent) const +{ + return flightgear::NavDataCache::instance()->airportItemWithIdent(guid(), FGPositioned::RUNWAY, aIdent) != 0; +} + +FGTaxiway* FGAirport::getTaxiwayByIdent(const string& aIdent) const +{ + PositionedID id = flightgear::NavDataCache::instance()->airportItemWithIdent(guid(), FGPositioned::RUNWAY, aIdent); + if (id == 0) { + SG_LOG(SG_GENERAL, SG_ALERT, "no such runway '" << aIdent << "' at airport " << ident()); + throw sg_range_exception("unknown runway " + aIdent + " at airport:" + ident(), "FGAirport::getTaxiwayByIdent"); + } + + return (FGTaxiway*) flightgear::NavDataCache::instance()->loadById(id); +} + unsigned int FGAirport::numPavements() const { loadTaxiways(); diff --git a/src/Airports/simple.hxx b/src/Airports/simple.hxx index 1409e3fde..dafe33496 100644 --- a/src/Airports/simple.hxx +++ b/src/Airports/simple.hxx @@ -123,6 +123,9 @@ public: unsigned int numTaxiways() const; FGTaxiway* getTaxiwayByIndex(unsigned int aIndex) const; + bool hasTaxiwayWithIdent(const std::string& aIdent) const; + FGTaxiway* getTaxiwayByIdent(const std::string& aIdent) const; + unsigned int numPavements() const; FGPavement* getPavementByIndex(unsigned int aIndex) const; @@ -235,7 +238,7 @@ private: void readThresholdData(SGPropertyNode* aRoot); void processThreshold(SGPropertyNode* aThreshold); - void readILSData(SGPropertyNode* aRoot); + void readILSData(SGPropertyNode* aRoot); void validateTowerData() const; @@ -256,7 +259,7 @@ private: mutable bool mRunwaysLoaded; mutable bool mTaxiwaysLoaded; mutable bool mProceduresLoaded; - bool mILSDataLoaded; + bool mILSDataLoaded; mutable PositionedIDVec mRunways; mutable PositionedIDVec mTaxiways; diff --git a/src/Scripting/NasalPositioned.cxx b/src/Scripting/NasalPositioned.cxx index 4af3d4fe1..e322ff20c 100644 --- a/src/Scripting/NasalPositioned.cxx +++ b/src/Scripting/NasalPositioned.cxx @@ -72,6 +72,9 @@ naGhostType NavaidGhostType = { positionedGhostDestroy, "navaid", navaidGhostGet static const char* runwayGhostGetMember(naContext c, void* g, naRef field, naRef* out); naGhostType RunwayGhostType = { positionedGhostDestroy, "runway", runwayGhostGetMember, 0 }; +static const char* taxiwayGhostGetMember(naContext c, void* g, naRef field, naRef* out); +naGhostType TaxiwayGhostType = { positionedGhostDestroy, "taxiway", taxiwayGhostGetMember, 0 }; + static const char* fixGhostGetMember(naContext c, void* g, naRef field, naRef* out); naGhostType FixGhostType = { positionedGhostDestroy, "fix", fixGhostGetMember, 0 }; @@ -175,6 +178,13 @@ static FGRunway* runwayGhost(naRef r) return 0; } +static FGTaxiway* taxiwayGhost(naRef r) +{ + if (naGhost_type(r) == &TaxiwayGhostType) + return (FGTaxiway*) naGhost_ptr(r); + return 0; +} + static FGFix* fixGhost(naRef r) { if (naGhost_type(r) == &FixGhostType) @@ -279,6 +289,16 @@ naRef ghostForRunway(naContext c, const FGRunway* r) return naNewGhost2(c, &RunwayGhostType, (void*) r); } +naRef ghostForTaxiway(naContext c, const FGTaxiway* r) +{ + if (!r) { + return naNil(); + } + + FGPositioned::get(r); // take a ref + return naNewGhost2(c, &TaxiwayGhostType, (void*) r); +} + naRef ghostForFix(naContext c, const FGFix* r) { if (!r) { @@ -359,6 +379,14 @@ static const char* airportGhostGetMember(naContext c, void* g, naRef field, naRe naHash_set(*out, rwyid, rwydata); } + } else if (!strcmp(fieldName, "taxiways")) { + *out = naNewVector(c); + for(unsigned int r=0; rnumTaxiways(); ++r) { + FGTaxiway* taxi(apt->getTaxiwayByIndex(r)); + naRef taxidata = ghostForTaxiway(c, taxi); + naVec_append(*out, taxidata); + } + } else { return 0; } @@ -704,6 +732,7 @@ static const char* runwayGhostGetMember(naContext c, void* g, naRef field, naRef else if (!strcmp(fieldName, "width")) *out = naNum(rwy->widthM()); else if (!strcmp(fieldName, "threshold")) *out = naNum(rwy->displacedThresholdM()); else if (!strcmp(fieldName, "stopway")) *out = naNum(rwy->stopwayM()); + else if (!strcmp(fieldName, "surface")) *out = naNum(rwy->surface()); else if (!strcmp(fieldName, "ils_frequency_mhz")) { *out = rwy->ILS() ? naNum(rwy->ILS()->get_freq() / 100.0) : naNil(); } else if (!strcmp(fieldName, "ils")) { @@ -715,6 +744,23 @@ static const char* runwayGhostGetMember(naContext c, void* g, naRef field, naRef return ""; } +static const char* taxiwayGhostGetMember(naContext c, void* g, naRef field, naRef* out) +{ + const char* fieldName = naStr_data(field); + FGTaxiway* taxi = (FGTaxiway*) g; + + if (!strcmp(fieldName, "id")) *out = stringToNasal(c, taxi->ident()); + else if (!strcmp(fieldName, "lat")) *out = naNum(taxi->latitude()); + else if (!strcmp(fieldName, "lon")) *out = naNum(taxi->longitude()); + else if (!strcmp(fieldName, "heading")) *out = naNum(taxi->headingDeg()); + else if (!strcmp(fieldName, "length")) *out = naNum(taxi->lengthM()); + else if (!strcmp(fieldName, "width")) *out = naNum(taxi->widthM()); + else if (!strcmp(fieldName, "surface")) *out = naNum(taxi->surface()); + else return 0; + + return ""; +} + static const char* navaidGhostGetMember(naContext c, void* g, naRef field, naRef* out) { const char* fieldName = naStr_data(field); @@ -825,6 +871,11 @@ static int geodFromArgs(naRef* args, int offset, int argc, SGGeod& result) return 1; } + if (gt == &TaxiwayGhostType) { + result = taxiwayGhost(args[offset])->geod(); + return 1; + } + if (gt == &FixGhostType) { result = fixGhost(args[offset])->geod(); return 1; @@ -1135,6 +1186,26 @@ static naRef f_airport_runway(naContext c, naRef me, int argc, naRef* args) return ghostForRunway(c, apt->getRunwayByIdent(ident)); } +static naRef f_airport_taxiway(naContext c, naRef me, int argc, naRef* args) +{ + FGAirport* apt = airportGhost(me); + if (!apt) { + naRuntimeError(c, "airport.taxiway called on non-airport object"); + } + + if ((argc < 1) || !naIsString(args[0])) { + naRuntimeError(c, "airport.taxiway expects a taxiway ident argument"); + } + + std::string ident(naStr_data(args[0])); + boost::to_upper(ident); + if (!apt->hasTaxiwayWithIdent(ident)) { + return naNil(); + } + + return ghostForTaxiway(c, apt->getTaxiwayByIdent(ident)); +} + static naRef f_airport_sids(naContext c, naRef me, int argc, naRef* args) { FGAirport* apt = airportGhost(me); @@ -2277,6 +2348,7 @@ naRef initNasalPositioned(naRef globals, naContext c, naRef gcSave) hashset(c, gcSave, "airportProto", airportPrototype); hashset(c, airportPrototype, "runway", naNewFunc(c, naNewCCode(c, f_airport_runway))); + hashset(c, airportPrototype, "taxiway", naNewFunc(c, naNewCCode(c, f_airport_taxiway))); hashset(c, airportPrototype, "tower", naNewFunc(c, naNewCCode(c, f_airport_tower))); hashset(c, airportPrototype, "comms", naNewFunc(c, naNewCCode(c, f_airport_comms))); hashset(c, airportPrototype, "sids", naNewFunc(c, naNewCCode(c, f_airport_sids))); -- 2.39.5