Work on extending the Nasal airports API - attempt to give methods to airport hashes.
This commit is contained in:
parent
2e5febec7d
commit
3edd350c55
1 changed files with 66 additions and 47 deletions
|
@ -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)));
|
||||||
|
|
Loading…
Reference in a new issue