From c7e846bd2a952a73b87f4fc0e99a486c79842f35 Mon Sep 17 00:00:00 2001 From: Thomas Geymayer Date: Tue, 5 Mar 2013 17:29:48 +0100 Subject: [PATCH] Parse geod/position and use it with new airportinfo. --- src/Scripting/NasalPositioned_cppbind.cxx | 91 ++++++++++++++++++----- 1 file changed, 71 insertions(+), 20 deletions(-) diff --git a/src/Scripting/NasalPositioned_cppbind.cxx b/src/Scripting/NasalPositioned_cppbind.cxx index aeede726b..f0eb9331d 100644 --- a/src/Scripting/NasalPositioned_cppbind.cxx +++ b/src/Scripting/NasalPositioned_cppbind.cxx @@ -224,7 +224,7 @@ static naRef f_airport_approaches(FGAirport& apt, const nasal::CallContext& ctx) //------------------------------------------------------------------------------ static FGParkingList -f_airport_parking(FGAirport& apt, const nasal::CallContext& ctx) +f_airport_parking(FGAirport& apt, nasal::CallContext ctx) { std::string type = ctx.getArg(0); bool only_available = ctx.getArg(1); @@ -251,6 +251,69 @@ f_airport_parking(FGAirport& apt, const nasal::CallContext& ctx) return ret; } +/** + * Extract a SGGeod from a nasal function argument list. + * + * , + * {"lat": , "lon": } + * geo.Coord.new() (aka. {"_lat": , "_lon": }) + */ +static bool extractGeod(nasal::CallContext& ctx, SGGeod& result) +{ + if( !ctx.argc ) + return false; + + if( ctx.isGhost(0) ) + { + FGPositioned* pos = + NasalPositioned::fromNasal(ctx.c, ctx.requireArg(0)); + + if( pos ) + { + result = pos->geod(); + ctx.popFront(); + return true; + } + } + else if( ctx.isHash(0) ) + { + nasal::Hash pos_hash = ctx.requireArg(0); + + // check for manual latitude / longitude names + naRef lat = pos_hash.get("lat"), + lon = pos_hash.get("lon"); + if( naIsNum(lat) && naIsNum(lon) ) + { + result = SGGeod::fromDeg( ctx.from_nasal(lon), + ctx.from_nasal(lat) ); + ctx.popFront(); + return true; + } + + // geo.Coord uses _lat/_lon in radians + // TODO should we check if its really a geo.Coord? + lat = pos_hash.get("_lat"); + lon = pos_hash.get("_lon"); + if( naIsNum(lat) && naIsNum(lon) ) + { + result = SGGeod::fromRad( ctx.from_nasal(lon), + ctx.from_nasal(lat) ); + ctx.popFront(); + return true; + } + } + else if( ctx.isNumeric(0) && ctx.isNumeric(1) ) + { + // lat, lon + result = SGGeod::fromDeg( ctx.requireArg(1), + ctx.requireArg(0) ); + ctx.popFront(2); + return true; + } + + return false; +} + //------------------------------------------------------------------------------ // Returns Nasal ghost for particular or nearest airport of a , or nil // on error. @@ -262,28 +325,16 @@ f_airport_parking(FGAirport& apt, const nasal::CallContext& ctx) static naRef f_airportinfo(naContext c, naRef me, int argc, naRef* args) { nasal::CallContext ctx(c, argc, args); - // TODO think of something comfortable to overload functions or use variable - // number/types of arguments. - - std::string ident = "airport"; - SGGeod pos = globals->get_aircraft_position(); - if( ctx.argc == 1 ) - { - ident = ctx.requireArg(0); - } - else if( ctx.argc >= 2 ) - { - // Why are lat/lon swapped? - pos = SGGeod::fromDeg( ctx.requireArg(1), - ctx.requireArg(0) ); + SGGeod pos; + if( !extractGeod(ctx, pos) ) + pos = globals->get_aircraft_position(); - if( ctx.argc >= 3 ) - ident = ctx.requireArg(2); + if( ctx.argc > 1 ) + naRuntimeError(ctx.c, "airportinfo() with invalid function arguments"); - if( ctx.argc > 3 ) - naRuntimeError(ctx.c, "airportinfo() with invalid function arguments"); - } + // optional type/ident + std::string ident = ctx.getArg(0, "airport"); FGAirport::TypeRunwayFilter filter; if( !filter.fromTypeString(ident) ) -- 2.39.5