X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FScripting%2FNasalPositioned_cppbind.cxx;h=7ef63d02c5f7aea29c6241d094cb131c87e8e57c;hb=3c0b7f88b80f7d5044d6f734968d7f9568668ccc;hp=34162e17ff829cd04e41ba08fd8ce8f2d481f31a;hpb=913727239d6776c0508d206f395e16c265413ec3;p=flightgear.git diff --git a/src/Scripting/NasalPositioned_cppbind.cxx b/src/Scripting/NasalPositioned_cppbind.cxx index 34162e17f..7ef63d02c 100644 --- a/src/Scripting/NasalPositioned_cppbind.cxx +++ b/src/Scripting/NasalPositioned_cppbind.cxx @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -77,7 +78,7 @@ naRef to_nasal_helper(naContext c, flightgear::Approach* iap) } //------------------------------------------------------------------------------ -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 @@ -130,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 { @@ -144,7 +145,7 @@ FGRunway* runwayFromNasalArg( const FGAirport& apt, { if( !apt.hasRunwayWithIdent(ident) ) // TODO warning/exception? - return NULL; + return FGRunwayRef(); return apt.getRunwayByIdent(ident); } @@ -153,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]); } //------------------------------------------------------------------------------ @@ -244,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 ) { @@ -396,8 +397,9 @@ static naRef f_findWithinRange(nasal::CallContext ctx) SGGeod pos = getPosition(ctx); double range_nm = ctx.requireArg(0); - FGPositioned::TypeFilter filter(FGPositioned::typeFromName(ctx.getArg(1))); - + std::string typeSpec = ctx.getArg(1); + FGPositioned::TypeFilter filter(FGPositioned::TypeFilter::fromString(typeSpec)); + FGPositionedList items = FGPositioned::findWithinRange(pos, range_nm, &filter); FGPositioned::sortByRange(items, pos); return ctx.to_nasal(items); @@ -406,8 +408,8 @@ static naRef f_findWithinRange(nasal::CallContext ctx) static naRef f_findByIdent(nasal::CallContext ctx) { std::string prefix = ctx.requireArg(0); - - FGPositioned::TypeFilter filter(FGPositioned::typeFromName(ctx.getArg(1))); + std::string typeSpec = ctx.getArg(1); + FGPositioned::TypeFilter filter(FGPositioned::TypeFilter::fromString(typeSpec)); bool exact = ctx.getArg(2, false); return ctx.to_nasal( FGPositioned::findAllWithIdent(prefix, &filter, exact) ); @@ -416,8 +418,8 @@ static naRef f_findByIdent(nasal::CallContext ctx) static naRef f_findByName(nasal::CallContext ctx) { std::string prefix = ctx.requireArg(0); - - FGPositioned::TypeFilter filter(FGPositioned::typeFromName(ctx.getArg(1))); + std::string typeSpec = ctx.getArg(1); + FGPositioned::TypeFilter filter(FGPositioned::TypeFilter::fromString(typeSpec)); return ctx.to_nasal( FGPositioned::findAllWithName(prefix, &filter, false) ); } @@ -456,7 +458,40 @@ static naRef f_sortByRange(nasal::CallContext ctx) } //------------------------------------------------------------------------------ -naRef initNasalPositioned_cppbind(naRef globalsRef, naContext c, naRef gcSave) +// 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) @@ -501,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") ); @@ -516,5 +551,7 @@ naRef initNasalPositioned_cppbind(naRef globalsRef, naContext c, naRef gcSave) positioned.set("courseAndDistance", &f_courseAndDistance); positioned.set("sortByRange", &f_sortByRange); + positioned.set("diff", &f_diff); + return naNil(); }