]> git.mxchange.org Git - flightgear.git/blobdiff - src/Scripting/NasalPositioned_cppbind.cxx
Remove debug console output in FGApproachController
[flightgear.git] / src / Scripting / NasalPositioned_cppbind.cxx
index 2191ecd3061f5dc3bac2a732b63db4078b149075..7ef63d02c5f7aea29c6241d094cb131c87e8e57c 100644 (file)
@@ -31,6 +31,7 @@
 #include <boost/foreach.hpp>
 #include <boost/algorithm/string/case_conv.hpp>
 
+#include <simgear/misc/ListDiff.hxx>
 #include <simgear/nasal/cppbind/from_nasal.hxx>
 #include <simgear/nasal/cppbind/to_nasal.hxx>
 #include <simgear/nasal/cppbind/NasalHash.hxx>
@@ -44,6 +45,7 @@
 #include <Navaids/NavDataCache.hxx>
 #include <Navaids/navlist.hxx>
 #include <Navaids/navrecord.hxx>
+#include <Navaids/fix.hxx>
 
 typedef nasal::Ghost<FGPositionedRef> NasalPositioned;
 typedef nasal::Ghost<FGRunwayRef> NasalRunway;
@@ -51,6 +53,8 @@ typedef nasal::Ghost<FGParkingRef> NasalParking;
 typedef nasal::Ghost<FGAirportRef> NasalAirport;
 typedef nasal::Ghost<flightgear::CommStationRef> NasalCommStation;
 typedef nasal::Ghost<FGNavRecordRef> NasalNavRecord;
+typedef nasal::Ghost<FGRunwayRef> NasalRunway;
+typedef nasal::Ghost<FGFixRef> NasalFix;
 
 //------------------------------------------------------------------------------
 naRef to_nasal_helper(naContext c, flightgear::SID* sid)
@@ -74,17 +78,7 @@ naRef to_nasal_helper(naContext c, flightgear::Approach* iap)
 }
 
 //------------------------------------------------------------------------------
-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
@@ -137,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
   {
@@ -151,7 +145,7 @@ FGRunway* runwayFromNasalArg( const FGAirport& apt,
     {
       if( !apt.hasRunwayWithIdent(ident) )
         // TODO warning/exception?
-        return NULL;
+        return FGRunwayRef();
 
       return apt.getRunwayByIdent(ident);
     }
@@ -160,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<FGRunwayRef>(ctx.args[index]);
 }
 
 //------------------------------------------------------------------------------
@@ -251,8 +245,8 @@ static bool extractGeod(nasal::CallContext& ctx, SGGeod& result)
 
   if( ctx.isGhost(0) )
   {
-    FGPositioned* pos =
-      NasalPositioned::fromNasal(ctx.c, ctx.requireArg<naRef>(0));
+    FGPositionedRef pos =
+      ctx.from_nasal<FGPositionedRef>(ctx.requireArg<naRef>(0));
 
     if( pos )
     {
@@ -398,22 +392,106 @@ static naRef f_navinfo(nasal::CallContext ctx)
 }
 
 //------------------------------------------------------------------------------
-static naRef f_findNavaidsWithinRange(nasal::CallContext ctx)
+static naRef f_findWithinRange(nasal::CallContext ctx)
 {
   SGGeod pos = getPosition(ctx);
   double range_nm = ctx.requireArg<double>(0);
 
-  FGNavList::TypeFilter filter;
-  filter.fromTypeString(ctx.getArg<std::string>(0));
+    std::string typeSpec = ctx.getArg<std::string>(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);
+}
+
+static naRef f_findByIdent(nasal::CallContext ctx)
+{
+  std::string prefix = ctx.requireArg<std::string>(0);
+  std::string typeSpec = ctx.getArg<std::string>(1);
+  FGPositioned::TypeFilter filter(FGPositioned::TypeFilter::fromString(typeSpec));
+  bool exact = ctx.getArg<bool>(2, false);
 
-  FGPositionedList navs = FGPositioned::findWithinRange(pos, range_nm, &filter);
-  FGPositioned::sortByRange(navs, pos);
+  return ctx.to_nasal( FGPositioned::findAllWithIdent(prefix, &filter, exact) );
+}
 
-  return ctx.to_nasal(navs);
+static naRef f_findByName(nasal::CallContext ctx)
+{
+  std::string prefix = ctx.requireArg<std::string>(0);
+  std::string typeSpec = ctx.getArg<std::string>(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<FGPositionedList>(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<FGPositionedRef> Diff;
+  Diff::List old_list = ctx.requireArg<FGPositionedList>(0),
+             new_list = ctx.requireArg<FGPositionedList>(1);
+  Diff::Callback cb_add = ctx.requireArg<Diff::Callback>(2),
+                 cb_rm  = ctx.getArg<Diff::Callback>(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)
@@ -436,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<NasalPositioned>();
+  
   NasalAirport::init("FGAirport")
     .bases<NasalPositioned>()
     .member("has_metar", &FGAirport::getMetar)
@@ -455,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") );
 
@@ -463,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();
 }