1
0
Fork 0

Work on extending the Nasal airports API - attempt to give methods to airport hashes.

This commit is contained in:
James Turner 2012-04-21 11:15:23 +01:00
parent 2e5febec7d
commit 3edd350c55

View file

@ -40,11 +40,18 @@
#include <Main/globals.hxx> #include <Main/globals.hxx>
#include <Main/fg_props.hxx> #include <Main/fg_props.hxx>
#include <Scenery/scenery.hxx> #include <Scenery/scenery.hxx>
#include <ATC/CommStation.hxx>
static void ghostDestroy(void* g); static void ghostDestroy(void* g);
naGhostType PositionedGhostType = { ghostDestroy, "positioned" }; naGhostType PositionedGhostType = { ghostDestroy, "positioned" };
static naRef stringToNasal(naContext c, const std::string& s)
{
return naStr_fromdata(naNewString(c),
const_cast<char *>(s.c_str()),
s.length());
}
static FGPositioned* positionedGhost(naRef r) static FGPositioned* positionedGhost(naRef r)
{ {
if (naGhost_type(r) == &PositionedGhostType) if (naGhost_type(r) == &PositionedGhostType)
@ -59,6 +66,8 @@ static void ghostDestroy(void* g)
SGReferenced::put(pos); // unref SGReferenced::put(pos); // unref
} }
static naRef airportPrototype;
naRef ghostForPositioned(naContext c, const FGPositioned* pos) naRef ghostForPositioned(naContext c, const FGPositioned* pos)
{ {
if (!pos) { if (!pos) {
@ -78,20 +87,15 @@ naRef hashForAirport(naContext c, const FGAirport* apt)
naRef rwys = naNewHash(c); naRef rwys = naNewHash(c);
for(unsigned int r=0; r<apt->numRunways(); ++r) { for(unsigned int r=0; r<apt->numRunways(); ++r) {
FGRunway* rwy(apt->getRunwayByIndex(r)); FGRunway* rwy(apt->getRunwayByIndex(r));
naRef rwyid = stringToNasal(c, rwy->ident());
naRef rwyid = naStr_fromdata(naNewString(c),
const_cast<char *>(rwy->ident().c_str()),
rwy->ident().length());
naRef rwydata = hashForRunway(c, rwy); naRef rwydata = hashForRunway(c, rwy);
naHash_set(rwys, rwyid, rwydata); naHash_set(rwys, rwyid, rwydata);
} }
naRef aptdata = naNewHash(c); naRef aptdata = naNewHash(c);
#define HASHSET(s,l,n) naHash_set(aptdata, naStr_fromdata(naNewString(c),s,l),n) #define HASHSET(s,l,n) naHash_set(aptdata, naStr_fromdata(naNewString(c),s,l),n)
HASHSET("id", 2, naStr_fromdata(naNewString(c), HASHSET("id", 2, stringToNasal(c, id));
const_cast<char *>(id.c_str()), id.length())); HASHSET("name", 4, stringToNasal(c, name));
HASHSET("name", 4, naStr_fromdata(naNewString(c),
const_cast<char *>(name.c_str()), name.length()));
HASHSET("lat", 3, naNum(apt->getLatitude())); HASHSET("lat", 3, naNum(apt->getLatitude()));
HASHSET("lon", 3, naNum(apt->getLongitude())); HASHSET("lon", 3, naNum(apt->getLongitude()));
HASHSET("elevation", 9, naNum(apt->getElevation() * SG_FEET_TO_METER)); HASHSET("elevation", 9, naNum(apt->getElevation() * SG_FEET_TO_METER));
@ -99,6 +103,10 @@ naRef hashForAirport(naContext c, const FGAirport* apt)
HASHSET("runways", 7, rwys); HASHSET("runways", 7, rwys);
HASHSET("_positioned", 11, ghostForPositioned(c, apt)); HASHSET("_positioned", 11, ghostForPositioned(c, apt));
naRef parents = naNewVector(c);
naVec_append(parents, airportPrototype);
HASHSET("parents", 7, parents);
#undef HASHSET #undef HASHSET
return aptdata; return aptdata;
@ -106,10 +114,7 @@ naRef hashForAirport(naContext c, const FGAirport* apt)
naRef hashForRunway(naContext c, FGRunway* rwy) naRef hashForRunway(naContext c, FGRunway* rwy)
{ {
naRef rwyid = naStr_fromdata(naNewString(c), naRef rwyid = stringToNasal(c, rwy->ident());
const_cast<char *>(rwy->ident().c_str()),
rwy->ident().length());
naRef rwydata = naNewHash(c); naRef rwydata = naNewHash(c);
#define HASHSET(s,l,n) naHash_set(rwydata, naStr_fromdata(naNewString(c),s,l),n) #define HASHSET(s,l,n) naHash_set(rwydata, naStr_fromdata(naNewString(c),s,l),n)
HASHSET("id", 2, rwyid); HASHSET("id", 2, rwyid);
@ -129,18 +134,14 @@ naRef hashForRunway(naContext c, FGRunway* rwy)
naRef sidVec = naNewVector(c); naRef sidVec = naNewVector(c);
BOOST_FOREACH(flightgear::SID* sid, rwy->getSIDs()) { BOOST_FOREACH(flightgear::SID* sid, rwy->getSIDs()) {
naRef procId = naStr_fromdata(naNewString(c), naRef procId = stringToNasal(c, sid->ident());
const_cast<char *>(sid->ident().c_str()),
sid->ident().length());
naVec_append(sidVec, procId); naVec_append(sidVec, procId);
} }
HASHSET("sids", 4, sidVec); HASHSET("sids", 4, sidVec);
naRef starVec = naNewVector(c); naRef starVec = naNewVector(c);
BOOST_FOREACH(flightgear::STAR* star, rwy->getSTARs()) { BOOST_FOREACH(flightgear::STAR* star, rwy->getSTARs()) {
naRef procId = naStr_fromdata(naNewString(c), naRef procId = stringToNasal(c, star->ident());
const_cast<char *>(star->ident().c_str()),
star->ident().length());
naVec_append(starVec, procId); naVec_append(starVec, procId);
} }
HASHSET("stars", 5, starVec); HASHSET("stars", 5, starVec);
@ -154,16 +155,15 @@ naRef hashForNavRecord(naContext c, const FGNavRecord* nav, const SGGeod& rel)
{ {
naRef navdata = naNewHash(c); naRef navdata = naNewHash(c);
#define HASHSET(s,l,n) naHash_set(navdata, naStr_fromdata(naNewString(c),s,l),n) #define HASHSET(s,l,n) naHash_set(navdata, naStr_fromdata(naNewString(c),s,l),n)
HASHSET("id", 2, naStr_fromdata(naNewString(c), HASHSET("id", 2, stringToNasal(c, nav->ident()));
const_cast<char *>(nav->ident().c_str()), nav->ident().length())); HASHSET("name", 4, stringToNasal(c, nav->name()));
HASHSET("name", 4, naStr_fromdata(naNewString(c),
const_cast<char *>(nav->name().c_str()), nav->name().length()));
HASHSET("frequency", 9, naNum(nav->get_freq())); HASHSET("frequency", 9, naNum(nav->get_freq()));
HASHSET("lat", 3, naNum(nav->get_lat())); HASHSET("lat", 3, naNum(nav->get_lat()));
HASHSET("lon", 3, naNum(nav->get_lon())); HASHSET("lon", 3, naNum(nav->get_lon()));
HASHSET("elevation", 9, naNum(nav->get_elev_ft() * SG_FEET_TO_METER)); HASHSET("elevation", 9, naNum(nav->get_elev_ft() * SG_FEET_TO_METER));
HASHSET("type", 4, naStr_fromdata(naNewString(c), HASHSET("type", 4, stringToNasal(c, nav->nameForType(nav->type())));
const_cast<char *>(nav->nameForType(nav->type())), strlen(nav->nameForType(nav->type()))));
// FIXME - get rid of these, people should use courseAndDistance instead
HASHSET("distance", 8, naNum(SGGeodesy::distanceNm( rel, nav->geod() ) * SG_NM_TO_METER ) ); HASHSET("distance", 8, naNum(SGGeodesy::distanceNm( rel, nav->geod() ) * SG_NM_TO_METER ) );
HASHSET("bearing", 7, naNum(SGGeodesy::courseDeg( rel, nav->geod() ) ) ); HASHSET("bearing", 7, naNum(SGGeodesy::courseDeg( rel, nav->geod() ) ) );
@ -260,10 +260,9 @@ static naRef f_geodinfo(naContext c, naRef me, int argc, naRef* args)
if(mat) { if(mat) {
matdata = naNewHash(c); matdata = naNewHash(c);
naRef names = naNewVector(c); naRef names = naNewVector(c);
const std::vector<std::string> n = mat->get_names(); BOOST_FOREACH(const std::string& n, mat->get_names())
for(unsigned int i=0; i<n.size(); i++) naVec_append(names, stringToNasal(c, n));
naVec_append(names, naStr_fromdata(naNewString(c),
const_cast<char*>(n[i].c_str()), n[i].size()));
HASHSET("names", 5, names); HASHSET("names", 5, names);
HASHSET("solid", 5, naNum(mat->get_solid())); HASHSET("solid", 5, naNum(mat->get_solid()));
HASHSET("friction_factor", 15, naNum(mat->get_friction_factor())); HASHSET("friction_factor", 15, naNum(mat->get_friction_factor()));
@ -363,16 +362,16 @@ static FGAirport* airportFromRef(naRef ref)
return NULL; return NULL;
} }
static naRef f_airporttower(naContext c, naRef me, int argc, naRef* args) static naRef f_airport_tower(naContext c, naRef me, int argc, naRef* args)
{ {
if (argc != 1) { FGPositioned* pos = positionedGhost(me);
naRuntimeError(c, "airporttower needs an airport object or ID argument"); if (!pos ||! FGAirport::isAirportType(pos)) {
naRuntimeError(c, "airport_tower called on non-airport object");
} }
FGAirport* apt = airportFromRef(args[0]); FGAirport* apt = (FGAirport*) pos;
// build a hash for the tower position
// include the frequencies ?
// build a hash for the tower position
SGGeod towerLoc = apt->getTowerLocation(); SGGeod towerLoc = apt->getTowerLocation();
naRef tower = naNewHash(c); naRef tower = naNewHash(c);
#define HASHSET(s,l,n) naHash_set(tower, naStr_fromdata(naNewString(c),s,l),n) #define HASHSET(s,l,n) naHash_set(tower, naStr_fromdata(naNewString(c),s,l),n)
@ -383,17 +382,38 @@ static naRef f_airporttower(naContext c, naRef me, int argc, naRef* args)
return tower; return tower;
} }
static naRef f_airportcomms(naContext c, naRef me, int argc, naRef* args) static naRef f_airport_comms(naContext c, naRef me, int argc, naRef* args)
{ {
if (argc == 0) { FGPositioned* pos = positionedGhost(me);
naRuntimeError(c, "airportcomms needs an airport object or ID argument"); if (!pos ||! FGAirport::isAirportType(pos)) {
naRuntimeError(c, "airport_comms called on non-airport object");
} }
FGAirport* apt = airportFromRef(args[0]); FGAirport* apt = (FGAirport*) pos;
naRef comms = naNewHash(c); naRef comms;
#define HASHSET(s,l,n) naHash_set(comms, naStr_fromdata(naNewString(c),s,l),n)
// if we have an explicit type, return a simple vector of frequencies
if (argc > 0 && naIsScalar(args[0])) {
std::string commName = naStr_data(args[0]);
FGPositioned::Type commType = FGPositioned::typeFromName(commName);
naRef comms = naNewVector(c);
BOOST_FOREACH(flightgear::CommStation* comm, apt->commStationsOfType(commType)) {
naVec_append(comms, naNum(comm->freqMHz()));
}
} else {
// otherwise return a vector of hashes, one for each comm station.
BOOST_FOREACH(flightgear::CommStation* comm, apt->commStations()) {
naRef commHash = naNewHash(c);
#define HASHSET(s,n) naHash_set(commHash, naStr_fromdata(naNewString(c),s,strlen(s)),n)
HASHSET("frequency", naNum(comm->freqMHz()));
HASHSET("ident", stringToNasal(c, comm->ident()));
#undef HASHSET #undef HASHSET
naVec_append(comms, commHash);
}
}
return comms; return comms;
} }
@ -541,10 +561,7 @@ static naRef f_tilePath(naContext c, naRef me, int argc, naRef* args)
} }
SGBucket b(pos); SGBucket b(pos);
const char* path = b.gen_base_path().c_str(); return stringToNasal(c, b.gen_base_path());
naRef s = naNewString(c);
naStr_fromdata(s, (char*)path, strlen(path));
return s;
} }
// Table of extension functions. Terminate with zeros. // Table of extension functions. Terminate with zeros.
@ -553,8 +570,6 @@ static struct { const char* name; naCFunction func; } funcs[] = {
{ "geodtocart", f_geodtocart }, { "geodtocart", f_geodtocart },
{ "geodinfo", f_geodinfo }, { "geodinfo", f_geodinfo },
{ "airportinfo", f_airportinfo }, { "airportinfo", f_airportinfo },
{ "airporttower", f_airporttower },
{ "airportcomms", f_airportcomms },
{ "navinfo", f_navinfo }, { "navinfo", f_navinfo },
{ "magvar", f_magvar }, { "magvar", f_magvar },
{ "courseAndDistance", f_courseAndDistance }, { "courseAndDistance", f_courseAndDistance },
@ -571,6 +586,10 @@ static void hashset(naContext c, naRef hash, const char* key, naRef val)
naRef initNasalPositioned(naRef globals, naContext c) naRef initNasalPositioned(naRef globals, naContext c)
{ {
airportPrototype = naNewHash(c);
hashset(c, airportPrototype, "tower", naNewFunc(c, naNewCCode(c, f_airport_tower)));
hashset(c, airportPrototype, "comms", naNewFunc(c, naNewCCode(c, f_airport_comms)));
for(int i=0; funcs[i].name; i++) { for(int i=0; funcs[i].name; i++) {
hashset(c, globals, funcs[i].name, hashset(c, globals, funcs[i].name,
naNewFunc(c, naNewCCode(c, funcs[i].func))); naNewFunc(c, naNewCCode(c, funcs[i].func)));