From c28f63132f3ed6c24593d8822d77fac0329e729a Mon Sep 17 00:00:00 2001
From: Florent Rougon <f.rougon@free.fr>
Date: Tue, 12 Dec 2017 15:13:22 +0100
Subject: [PATCH] Re-add airport(), navaid() and runway() methods of
 flightplan-leg ghosts

These methods were removed by mistake in commit 0dbb0dff9, which broke
code that relies on them (e.g., FMSDelegate.currentWaypointChanged() in
$FG_ROOT/Nasal/route_manager.nas).

Also remove 'waypointPrototype' from NasalPositioned.cxx, since it is
not used anymore.

Note: the methods can't be easily re-enabled by means of
      'waypointPrototype', because for FPLeg ghosts, 'waypointPrototype'
      was emulated as a parent class before this commit, and thus when
      querying an FPLeg ghost for its 'airport', 'runway' or 'navaid'
      member, the corresponding data member returned by
      waypointCommonGetMember() would be found by legGhostGetMember()
      *before* parent classes are searched. This commit prevents this
      from happening by returning 'airport', 'runway' and 'navaid' as
      member functions *directly* in legGhostGetMember(), before
      waypointCommonGetMember() is queried as a fallback.

Thanks to Eric van den Berg for the bug report.
---
 src/Scripting/NasalPositioned.cxx | 51 +++++++++++++++++++++++++++----
 1 file changed, 45 insertions(+), 6 deletions(-)

diff --git a/src/Scripting/NasalPositioned.cxx b/src/Scripting/NasalPositioned.cxx
index fcf7e75e7..335779e34 100644
--- a/src/Scripting/NasalPositioned.cxx
+++ b/src/Scripting/NasalPositioned.cxx
@@ -269,7 +269,6 @@ static void routeBaseGhostDestroy(void* g)
 
 static naRef airportPrototype;
 static naRef flightplanPrototype;
-static naRef waypointPrototype;
 static naRef geoCoordClass;
 static naRef fpLegPrototype;
 static naRef procedurePrototype;
@@ -558,6 +557,45 @@ naRef routeRestrictionToNasal(naContext c, RouteRestriction rr)
   return naNil();
 }
 
+// navaid() method of FPLeg ghosts
+static naRef f_fpLeg_navaid(naContext c, naRef me, int argc, naRef* args)
+{
+  flightgear::Waypt* w = wayptGhost(me);
+  if (!w) {
+    naRuntimeError(c,
+                   "flightplan-leg.navaid() called, but can't find the "
+                   "underlying waypoint for the flightplan-leg object");
+  }
+
+  return waypointNavaid(c, w);
+}
+
+// airport() method of FPLeg ghosts
+static naRef f_fpLeg_airport(naContext c, naRef me, int argc, naRef* args)
+{
+  flightgear::Waypt* w = wayptGhost(me);
+  if (!w) {
+    naRuntimeError(c,
+                   "flightplan-leg.airport() called, but can't find the "
+                   "underlying waypoint for the flightplan-leg object");
+  }
+
+  return waypointAirport(c, w);
+}
+
+// runway() method of FPLeg ghosts
+static naRef f_fpLeg_runway(naContext c, naRef me, int argc, naRef* args)
+{
+  flightgear::Waypt* w = wayptGhost(me);
+  if (!w) {
+    naRuntimeError(c,
+                   "flightplan-leg.runway() called, but can't find the "
+                   "underlying waypoint for the flightplan-leg object");
+  }
+
+  return waypointRunway(c, w);
+}
+
 static const char* legGhostGetMember(naContext c, void* g, naRef field, naRef* out)
 {
   const char* fieldName = naStr_data(field);
@@ -567,7 +605,6 @@ static const char* legGhostGetMember(naContext c, void* g, naRef field, naRef* o
   if (!strcmp(fieldName, "parents")) {
     *out = naNewVector(c);
     naVec_append(*out, fpLegPrototype);
-    naVec_append(*out, waypointPrototype);
   } else if (!strcmp(fieldName, "index")) {
     *out = naNum(leg->index());
   } else if (!strcmp(fieldName, "alt_cstr")) {
@@ -585,6 +622,12 @@ static const char* legGhostGetMember(naContext c, void* g, naRef field, naRef* o
     *out = naNum(leg->courseDeg());
   } else if (!strcmp(fieldName, "distance_along_route")) {
     *out = naNum(leg->distanceAlongRoute());
+  } else if (!strcmp(fieldName, "airport")) {
+    *out = naNewFunc(c, naNewCCode(c, f_fpLeg_airport));
+  } else if (!strcmp(fieldName, "navaid")) {
+    *out = naNewFunc(c, naNewCCode(c, f_fpLeg_navaid));
+  } else if (!strcmp(fieldName, "runway")) {
+    *out = naNewFunc(c, naNewCCode(c, f_fpLeg_runway));
   } else { // check for fields defined on the underlying waypoint
     return waypointCommonGetMember(c, wpt, fieldName, out);
   }
@@ -2823,10 +2866,6 @@ naRef initNasalPositioned(naRef globals, naContext c)
 
     hashset(c, flightplanPrototype, "save", naNewFunc(c, naNewCCode(c, f_flightplan_save)));
 
-  
-    waypointPrototype = naNewHash(c);
-    naSave(c, waypointPrototype);
-
     procedurePrototype = naNewHash(c);
     naSave(c, procedurePrototype);
     hashset(c, procedurePrototype, "transition", naNewFunc(c, naNewCCode(c, f_procedure_transition)));