X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FScripting%2FNasalPositioned_cppbind.cxx;h=7ef63d02c5f7aea29c6241d094cb131c87e8e57c;hb=3c0b7f88b80f7d5044d6f734968d7f9568668ccc;hp=aab7489ea7a6a9182fea08a107f6f113f4bc8a01;hpb=8d56b4664ac77597571dbc0a40459fecf2b4c44e;p=flightgear.git diff --git a/src/Scripting/NasalPositioned_cppbind.cxx b/src/Scripting/NasalPositioned_cppbind.cxx index aab7489ea..7ef63d02c 100644 --- a/src/Scripting/NasalPositioned_cppbind.cxx +++ b/src/Scripting/NasalPositioned_cppbind.cxx @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -38,11 +39,13 @@ #include #include +#include #include #include
#include #include #include +#include typedef nasal::Ghost NasalPositioned; typedef nasal::Ghost NasalRunway; @@ -50,30 +53,8 @@ typedef nasal::Ghost NasalParking; typedef nasal::Ghost NasalAirport; typedef nasal::Ghost NasalCommStation; typedef nasal::Ghost NasalNavRecord; - -//------------------------------------------------------------------------------ -naRef to_nasal_helper(naContext c, FGPositioned* positioned) -{ - return NasalPositioned::create(c, positioned); -} - -//------------------------------------------------------------------------------ -naRef to_nasal_helper(naContext c, FGPavement* rwy) -{ - return NasalPositioned::create(c, (FGPositioned*)rwy); -} - -//------------------------------------------------------------------------------ -naRef to_nasal_helper(naContext c, FGRunwayBase* rwy) -{ - return NasalPositioned::create(c, (FGPositioned*)rwy); -} - -//------------------------------------------------------------------------------ -naRef to_nasal_helper(naContext c, FGParking* parking) -{ - return NasalParking::create(c, parking); -} +typedef nasal::Ghost NasalRunway; +typedef nasal::Ghost NasalFix; //------------------------------------------------------------------------------ naRef to_nasal_helper(naContext c, flightgear::SID* sid) @@ -97,23 +78,7 @@ naRef to_nasal_helper(naContext c, flightgear::Approach* iap) } //------------------------------------------------------------------------------ -naRef to_nasal_helper(naContext c, FGAirport* apt) -{ - return NasalAirport::create(c, apt); -} - -//------------------------------------------------------------------------------ -naRef to_nasal_helper(naContext c, const SGGeod& pos) -{ - nasal::Hash hash(c); - hash.set("lat", pos.getLatitudeDeg()); - hash.set("lon", pos.getLongitudeDeg()); - hash.set("elevation", pos.getElevationM()); - return hash.get_naRef(); -} - -//------------------------------------------------------------------------------ -static naRef f_navaid_course(naContext, FGNavRecord& nav) +static naRef f_navaid_course(FGNavRecord& nav, naContext) { if( !( nav.type() == FGPositioned::ILS || nav.type() == FGPositioned::LOC @@ -125,7 +90,7 @@ static naRef f_navaid_course(naContext, FGNavRecord& nav) } //------------------------------------------------------------------------------ -static FGRunwayBase* f_airport_runway(FGAirport& apt, std::string ident) +static FGRunwayBaseRef f_airport_runway(FGAirport& apt, std::string ident) { boost::to_upper(ident); @@ -139,7 +104,7 @@ static FGRunwayBase* f_airport_runway(FGAirport& apt, std::string ident) //------------------------------------------------------------------------------ template -std::vector extract( const std::vector& in, +std::vector extract( const std::vector& in, T (C2::*getter)() const ) { std::vector ret(in.size()); @@ -166,12 +131,12 @@ static naRef f_airport_comms(FGAirport& apt, const nasal::CallContext& ctx) } //------------------------------------------------------------------------------ -FGRunway* runwayFromNasalArg( const FGAirport& apt, +FGRunwayRef runwayFromNasalArg( const FGAirport& apt, const nasal::CallContext& ctx, size_t index = 0 ) { if( index >= ctx.argc ) - return NULL; + return FGRunwayRef(); try { @@ -180,7 +145,7 @@ FGRunway* runwayFromNasalArg( const FGAirport& apt, { if( !apt.hasRunwayWithIdent(ident) ) // TODO warning/exception? - return NULL; + return FGRunwayRef(); return apt.getRunwayByIdent(ident); } @@ -189,7 +154,7 @@ FGRunway* runwayFromNasalArg( const FGAirport& apt, {} // TODO warn/error if no runway? - return NasalRunway::fromNasal(ctx.c, ctx.args[index]); + return ctx.from_nasal(ctx.args[index]); } //------------------------------------------------------------------------------ @@ -280,8 +245,8 @@ static bool extractGeod(nasal::CallContext& ctx, SGGeod& result) if( ctx.isGhost(0) ) { - FGPositioned* pos = - NasalPositioned::fromNasal(ctx.c, ctx.requireArg(0)); + FGPositionedRef pos = + ctx.from_nasal(ctx.requireArg(0)); if( pos ) { @@ -349,10 +314,8 @@ static SGGeod getPosition(nasal::CallContext& ctx) // airportinfo(); type := ("airport"|"seaport"|"heliport") // airportinfo() same as airportinfo("airport") // airportinfo(, [, ]); -static naRef f_airportinfo(naContext c, naRef me, int argc, naRef* args) +static naRef f_airportinfo(nasal::CallContext ctx) { - nasal::CallContext ctx(c, argc, args); - SGGeod pos = getPosition(ctx); if( ctx.argc > 1 ) @@ -375,18 +338,15 @@ static naRef f_airportinfo(naContext c, naRef me, int argc, naRef* args) /** * findAirportsWithinRange([,] [, type]) */ -static naRef f_findAirportsWithinRange(naContext c, naRef me, int argc, naRef* args) +static naRef f_findAirportsWithinRange(nasal::CallContext ctx) { - nasal::CallContext ctx(c, argc, args); - SGGeod pos = getPosition(ctx); double range_nm = ctx.requireArg(0); FGAirport::TypeRunwayFilter filter; // defaults to airports only filter.fromTypeString( ctx.getArg(1) ); - FGPositioned::List apts = - FGPositioned::findWithinRange(pos, range_nm, &filter); + FGPositionedList apts = FGPositioned::findWithinRange(pos, range_nm, &filter); FGPositioned::sortByRange(apts, pos); return ctx.to_nasal(apts); @@ -395,9 +355,8 @@ static naRef f_findAirportsWithinRange(naContext c, naRef me, int argc, naRef* a /** * findAirportsByICAO( [, type]) */ -static naRef f_findAirportsByICAO(naContext c, naRef me, int argc, naRef* args) +static naRef f_findAirportsByICAO(nasal::CallContext ctx) { - nasal::CallContext ctx(c, argc, args); std::string prefix = ctx.requireArg(0); FGAirport::TypeRunwayFilter filter; // defaults to airports only @@ -418,10 +377,8 @@ static naRef f_findAirportsByICAO(naContext c, naRef me, int argc, naRef* args) // navinfo("vor", "HAM") return all vor who's name start with "HAM" //navinfo(34,48,"vor","HAM") return all vor who's name start with "HAM" // sorted by distance relative to lat=34, lon=48 -static naRef f_navinfo(naContext c, naRef me, int argc, naRef* args) +static naRef f_navinfo(nasal::CallContext ctx) { - nasal::CallContext ctx(c, argc, args); - SGGeod pos = getPosition(ctx); std::string id = ctx.getArg(0); @@ -429,31 +386,112 @@ static naRef f_navinfo(naContext c, naRef me, int argc, naRef* args) if( filter.fromTypeString(id) ) id = ctx.getArg(1); else if( ctx.argc > 1 ) - naRuntimeError(c, "navinfo() already got an ident"); + naRuntimeError(ctx.c, "navinfo() already got an ident"); return ctx.to_nasal( FGNavList::findByIdentAndFreq(pos, id, 0.0, &filter) ); } //------------------------------------------------------------------------------ -static naRef f_findNavaidsWithinRange(naContext c, naRef me, int argc, naRef* args) +static naRef f_findWithinRange(nasal::CallContext ctx) { - nasal::CallContext ctx(c, argc, args); - SGGeod pos = getPosition(ctx); double range_nm = ctx.requireArg(0); - FGNavList::TypeFilter filter; - filter.fromTypeString(ctx.getArg(0)); + std::string typeSpec = ctx.getArg(1); + FGPositioned::TypeFilter filter(FGPositioned::TypeFilter::fromString(typeSpec)); - FGPositioned::List navs = - FGPositioned::findWithinRange(pos, range_nm, &filter); - FGPositioned::sortByRange(navs, pos); + FGPositionedList items = FGPositioned::findWithinRange(pos, range_nm, &filter); + FGPositioned::sortByRange(items, pos); + return ctx.to_nasal(items); +} + +static naRef f_findByIdent(nasal::CallContext ctx) +{ + std::string prefix = ctx.requireArg(0); + std::string typeSpec = ctx.getArg(1); + FGPositioned::TypeFilter filter(FGPositioned::TypeFilter::fromString(typeSpec)); + bool exact = ctx.getArg(2, false); - return ctx.to_nasal(navs); + return ctx.to_nasal( FGPositioned::findAllWithIdent(prefix, &filter, exact) ); +} + +static naRef f_findByName(nasal::CallContext ctx) +{ + std::string prefix = ctx.requireArg(0); + std::string typeSpec = ctx.getArg(1); + FGPositioned::TypeFilter filter(FGPositioned::TypeFilter::fromString(typeSpec)); + + return ctx.to_nasal( FGPositioned::findAllWithName(prefix, &filter, false) ); } //------------------------------------------------------------------------------ -naRef initNasalPositioned_cppbind(naRef globalsRef, naContext c, naRef gcSave) + +static naRef f_courseAndDistance(nasal::CallContext ctx) +{ + SGGeod from = globals->get_aircraft_position(), to, pos; + bool ok = extractGeod(ctx, pos); + if (!ok) { + naRuntimeError(ctx.c, "invalid arguments to courseAndDistance"); + } + + if (extractGeod(ctx, to)) { + from = pos; // we parsed both FROM and TO args, so first was FROM + } else { + to = pos; // only parsed one arg, so FROM is current + } + + double course, course2, d; + SGGeodesy::inverse(from, to, course, course2, d); + + naRef result = naNewVector(ctx.c); + naVec_append(result, naNum(course)); + naVec_append(result, naNum(d * SG_METER_TO_NM)); + return result; +} + +static naRef f_sortByRange(nasal::CallContext ctx) +{ + FGPositionedList items = ctx.requireArg(0); + ctx.popFront(); + FGPositioned::sortByRange(items, getPosition(ctx)); + return ctx.to_nasal(items); +} + +//------------------------------------------------------------------------------ +// Get difference between two lists of positioned objects. +// +// For every element in old_list not in new_list the callback cb_remove is +// called with the removed element as single argument. For every element in +// new_list not in old_list cb_add is called. +// +// diff(old_list, new_list, cb_add[, cb_remove]) +// +// example: +// # Print all fixes within a distance of 320 to 640 miles +// diff( findWithinRange(320, "fix"), +// findWithinRange(640, "fix"), +// func(p) print('found fix: ', p.id) ); +static naRef f_diff(nasal::CallContext ctx) +{ + typedef simgear::ListDiff Diff; + Diff::List old_list = ctx.requireArg(0), + new_list = ctx.requireArg(1); + Diff::Callback cb_add = ctx.requireArg(2), + cb_rm = ctx.getArg(3); + + // Note that FGPositionedRef instances are only compared for pointer equality. + // As the NavCache caches every queried positioned instance it is guaranteed + // that only one instance of every positioned object can exist. Therefore we + // can make the comparison faster by just comparing pointers and not also the + // guid. + // (On my machine the difference is 0.27s vs 0.17s) + Diff::inplace(old_list, new_list, cb_add, cb_rm); + + return naNil(); +} + +//------------------------------------------------------------------------------ +naRef initNasalPositioned_cppbind(naRef globalsRef, naContext c) { NasalPositioned::init("Positioned") .member("id", &FGPositioned::ident) @@ -476,6 +514,9 @@ naRef initNasalPositioned_cppbind(naRef globalsRef, naContext c, naRef gcSave) .member("range_nm", &FGNavRecord::get_range) .member("course", &f_navaid_course); + NasalFix::init("Fix") + .bases(); + NasalAirport::init("FGAirport") .bases() .member("has_metar", &FGAirport::getMetar) @@ -495,7 +536,7 @@ naRef initNasalPositioned_cppbind(naRef globalsRef, naContext c, naRef gcSave) .method("getStar", &FGAirport::findSTARWithIdent) .method("getIAP", &FGAirport::findApproachWithIdent) .method("tostring", &FGAirport::toString); - + nasal::Hash globals(globalsRef, c), positioned( globals.createHash("positioned") ); @@ -503,7 +544,14 @@ naRef initNasalPositioned_cppbind(naRef globalsRef, naContext c, naRef gcSave) positioned.set("findAirportsWithinRange", f_findAirportsWithinRange); positioned.set("findAirportsByICAO", &f_findAirportsByICAO); positioned.set("navinfo", &f_navinfo); - positioned.set("findNavaidsWithinRange", &f_findNavaidsWithinRange); + + positioned.set("findWithinRange", &f_findWithinRange); + positioned.set("findByIdent", &f_findByIdent); + positioned.set("findByName", &f_findByName); + positioned.set("courseAndDistance", &f_courseAndDistance); + positioned.set("sortByRange", &f_sortByRange); + + positioned.set("diff", &f_diff); return naNil(); }