]> git.mxchange.org Git - flightgear.git/commitdiff
Start porting NasalPositioned to cppbind.
authorThomas Geymayer <tomgey@gmail.com>
Mon, 4 Mar 2013 18:24:47 +0000 (19:24 +0100)
committerThomas Geymayer <tomgey@gmail.com>
Mon, 4 Mar 2013 18:24:47 +0000 (19:24 +0100)
For now it is available in the positioned Nasal
module. FGAirport is fully ported, but especially
procedures/navaids and free functions are still
missing.

12 files changed:
src/AIModel/AIFlightPlan.hxx
src/Airports/airport.hxx
src/Airports/airports_fwd.hxx
src/Airports/parking.hxx
src/Navaids/FlightPlan.hxx
src/Navaids/awynet.cxx
src/Navaids/procedure.hxx
src/Navaids/waypoint.hxx
src/Scripting/CMakeLists.txt
src/Scripting/NasalPositioned.hxx
src/Scripting/NasalPositioned_cppbind.cxx [new file with mode: 0644]
src/Scripting/NasalSys.cxx

index 7c9881ada3235b5b4bc5c51f8cf6f391c43e5328..bfd445b27b54ef4ff33064953c7ced2493178ac3 100644 (file)
 #include <Navaids/positioned.hxx>
 #include <Airports/dynamics.hxx>
 
-// forward decls
-class FGTaxiRoute;
-class FGRunway;
-class FGAIAircraft;
-class FGAirport;
-
-typedef SGSharedPtr<FGAirport> FGAirportRef;
-
 class FGAIWaypoint {
 private:
    std::string name;
index 3ca4d62c7face5c45ee89a39e48c30586ec78112..d32326c65de2102b03de0d70187d89ba65efb67c 100644 (file)
@@ -51,6 +51,8 @@ public:
 
     const std::string& getId() const { return ident(); }
     const std::string& getName() const { return _name; }
+    std::string toString() const { return "an airport " + ident(); }
+
     double getLongitude() const { return longitude(); }
     // Returns degrees
     double getLatitude()  const { return latitude(); }
index ecb76a50fcd8a732810d78c8f7cea47e9be85104..6ea223441b8c1a743355a5123fd074de106a8c97 100644 (file)
@@ -59,12 +59,17 @@ namespace flightgear {
   typedef std::map<std::string, FGAirport*> AirportCache;
 }
 
+typedef SGSharedPtr<FGAirport> FGAirportRef;
+typedef SGSharedPtr<FGRunway> FGRunwayRef;
+typedef SGSharedPtr<FGParking> FGParkingRef;
+
 typedef std::vector<FGRunway*> FGRunwayList;
 typedef std::map<std::string, FGRunway*> FGRunwayMap;
 typedef std::map<std::string, FGHelipad*> FGHelipadMap;
 
 typedef std::vector<FGTaxiway*> FGTaxiwayList;
 typedef std::vector<FGPavement*> FGPavementList;
+typedef std::vector<FGParking*> FGParkingList;
 
 typedef std::vector<FGTaxiSegment*>  FGTaxiSegmentVector;
 typedef FGTaxiSegmentVector::iterator FGTaxiSegmentVectorIterator;
@@ -83,10 +88,6 @@ typedef std::vector<time_t>::iterator TimeVectorIterator;
 typedef std::vector<FGTaxiRoute> TaxiRouteVector;
 typedef std::vector<FGTaxiRoute>::iterator TaxiRouteVectorIterator;
 
-typedef std::vector<FGParking*> FGParkingVec;
-typedef FGParkingVec::iterator FGParkingVecIterator;
-typedef FGParkingVec::const_iterator FGParkingVecConstIterator;
-
 typedef std::vector<RunwayList> RunwayListVec;
 typedef std::vector<RunwayList>::iterator RunwayListVectorIterator;
 typedef std::vector<RunwayList>::const_iterator RunwayListVecConstIterator;
index 6d8892c802d6307cce06f42996013d42f07fd6fe..92b79008430d79282963aa8d619fb45a49c60475 100644 (file)
@@ -72,6 +72,9 @@ public:
   std::string getCodes    () const { return airlineCodes;};
   std::string getName     () const { return parkingName; };
 
+  // TODO do parkings have different name and ident?
+  virtual const std::string& name() const { return parkingName; }
+
   int getPushBackPoint () { return pushBackPoint; };
 
   bool operator< (const FGParking &other) const {
index d00c4860f11094c921c65b29a01d1faad51ecc40..fd44b38de247742d4131cea094f57052889c000f 100644 (file)
@@ -27,8 +27,6 @@
 #include <Navaids/route.hxx>
 #include <Airports/airport.hxx>
 
-typedef SGSharedPtr<FGAirport> FGAirportRef;
-    
 namespace flightgear
 {
 
index 7642673b5fc6ec5857347948d6aaf9cdf7ceae82..e1476615a0e20e5d58e56bda299fdb08aa98f50b 100644 (file)
@@ -163,10 +163,10 @@ void FGAirwayNetwork::addAirway(const FGAirway &seg)
 //}
 
 /*
-  void FGAirwayNetwork::addNodes(FGParkingVec *parkings)
+  void FGAirwayNetwork::addNodes(FGParkingList *parkings)
   {
   FGTaxiNode n;
-  FGParkingVecIterator i = parkings->begin();
+  FGParkingList::iterator i = parkings->begin();
   while (i != parkings->end())
   {
   n.setIndex(i->getIndex());
index 146e237ad43352e5b51b34b80559b0b62238b72e..d1ecf980482b40547cb619d875615378539819c1 100644 (file)
@@ -26,8 +26,6 @@
 #include <Airports/airports_fwd.hxx>
 #include <Navaids/route.hxx>
 
-typedef SGSharedPtr<FGRunway> FGRunwayRef;
-
 namespace flightgear {
 
 // forward decls
index d01070b6f7f6b023354e06849abb209ff31f988d..377049ab0919153e0a680fce529c4894bb477c09 100644 (file)
 #ifndef FG_WAYPOINT_HXX
 #define FG_WAYPOINT_HXX
 
+#include <Airports/airports_fwd.hxx>
 #include <Navaids/route.hxx>
 #include <Navaids/positioned.hxx>
 
-class FGAirport;
-typedef SGSharedPtr<FGAirport> FGAirportRef;
-class FGRunway;
-
 namespace flightgear
 {
 
index 586d4a4a7582cc64c320f5442d739c9df118949d..e91d6aeb649caf148bb13359e2efc4ed64cdd913 100644 (file)
@@ -4,6 +4,7 @@ set(SOURCES
        NasalSys.cxx
        nasal-props.cxx
     NasalPositioned.cxx
+    NasalPositioned_cppbind.cxx
     NasalCanvas.cxx
     NasalClipboard.cxx
     NasalCondition.cxx
index a3b7514d2e22c0cdd878c6560b494115e025d077..14401e9c2c08678f476213895279b4702e62435e 100644 (file)
@@ -29,6 +29,7 @@ class SGGeod;
 bool geodFromHash(naRef ref, SGGeod& result); 
 
 naRef initNasalPositioned(naRef globals, naContext c, naRef gcSave);
+naRef initNasalPositioned_cppbind(naRef globals, naContext c, naRef gcSave);
 void postinitNasalPositioned(naRef globals, naContext c);
 
 #endif // of SCRIPTING_NASAL_POSITIONED_HXX
diff --git a/src/Scripting/NasalPositioned_cppbind.cxx b/src/Scripting/NasalPositioned_cppbind.cxx
new file mode 100644 (file)
index 0000000..b2ae98c
--- /dev/null
@@ -0,0 +1,312 @@
+// NasalPositioned_cppbind.cxx -- expose FGPositioned classes to Nasal
+//
+// Port of NasalPositioned.cpp to the new nasal/cppbind helpers. Will replace
+// old NasalPositioned.cpp once finished.
+//
+// Copyright (C) 2013  Thomas Geymayer <tomgey@gmail.com>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include "NasalPositioned.hxx"
+
+#include <algorithm>
+#include <functional>
+
+#include <boost/foreach.hpp>
+#include <boost/algorithm/string/case_conv.hpp>
+
+#include <simgear/nasal/cppbind/from_nasal.hxx>
+#include <simgear/nasal/cppbind/to_nasal.hxx>
+#include <simgear/nasal/cppbind/NasalHash.hxx>
+#include <simgear/nasal/cppbind/Ghost.hxx>
+
+#include <Airports/airport.hxx>
+#include <Airports/dynamics.hxx>
+#include <ATC/CommStation.hxx>
+#include <Navaids/NavDataCache.hxx>
+
+typedef nasal::Ghost<FGPositionedRef> NasalPositioned;
+typedef nasal::Ghost<FGRunwayRef> NasalRunway;
+typedef nasal::Ghost<FGParkingRef> NasalParking;
+typedef nasal::Ghost<FGAirportRef> NasalAirport;
+typedef nasal::Ghost<flightgear::CommStationRef> NasalCommStation;
+
+//------------------------------------------------------------------------------
+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);
+}
+
+//------------------------------------------------------------------------------
+naRef to_nasal_helper(naContext c, flightgear::SID* sid)
+{
+  // TODO SID ghost
+  return nasal::to_nasal(c, sid->ident());
+}
+
+//------------------------------------------------------------------------------
+naRef to_nasal_helper(naContext c, flightgear::STAR* star)
+{
+  // TODO STAR ghost
+  return nasal::to_nasal(c, star->ident());
+}
+
+//------------------------------------------------------------------------------
+naRef to_nasal_helper(naContext c, flightgear::Approach* iap)
+{
+  // TODO Approach ghost
+  return nasal::to_nasal(c, iap->ident());
+}
+
+//------------------------------------------------------------------------------
+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 FGRunwayBase* f_airport_runway(FGAirport& apt, std::string ident)
+{
+  boost::to_upper(ident);
+
+  if( apt.hasRunwayWithIdent(ident) )
+    return apt.getRunwayByIdent(ident);
+  else if( apt.hasHelipadWithIdent(ident) )
+    return apt.getHelipadByIdent(ident);
+
+  return 0;
+}
+
+//------------------------------------------------------------------------------
+template<class T, class C1, class C2>
+std::vector<T> extract( const std::vector<C1*>& in,
+                        T (C2::*getter)() const )
+{
+  std::vector<T> ret(in.size());
+  std::transform(in.begin(), in.end(), ret.begin(), std::mem_fun(getter));
+  return ret;
+}
+
+//------------------------------------------------------------------------------
+static naRef f_airport_comms(FGAirport& apt, const nasal::CallContext& ctx)
+{
+  FGPositioned::Type comm_type =
+    FGPositioned::typeFromName( ctx.getArg<std::string>(0) );
+
+  // if we have an explicit type, return a simple vector of frequencies
+  if( comm_type != FGPositioned::INVALID )
+    return ctx.to_nasal
+    (
+      extract( apt.commStationsOfType(comm_type),
+               &flightgear::CommStation::freqMHz )
+    );
+  else
+    // otherwise return a vector of ghosts, one for each comm station.
+    return ctx.to_nasal(apt.commStations());
+}
+
+//------------------------------------------------------------------------------
+FGRunway* runwayFromNasalArg( const FGAirport& apt,
+                              const nasal::CallContext& ctx,
+                              size_t index = 0 )
+{
+  if( index >= ctx.argc )
+    return NULL;
+
+  try
+  {
+    std::string ident = ctx.getArg<std::string>(index);
+    if( !ident.empty() )
+    {
+      if( !apt.hasRunwayWithIdent(ident) )
+        // TODO warning/exception?
+        return NULL;
+
+      return apt.getRunwayByIdent(ident);
+    }
+  }
+  catch(...)
+  {}
+
+  // TODO warn/error if no runway?
+  return NasalRunway::fromNasal(ctx.c, ctx.args[index]);
+}
+
+//------------------------------------------------------------------------------
+static naRef f_airport_sids(FGAirport& apt, const nasal::CallContext& ctx)
+{
+  FGRunway* rwy = runwayFromNasalArg(apt, ctx);
+  return ctx.to_nasal
+  (
+    extract(rwy ? rwy->getSIDs() : apt.getSIDs(), &flightgear::SID::ident)
+  );
+}
+
+//------------------------------------------------------------------------------
+static naRef f_airport_stars(FGAirport& apt, const nasal::CallContext& ctx)
+{
+  FGRunway* rwy = runwayFromNasalArg(apt, ctx);
+  return ctx.to_nasal
+  (
+    extract(rwy ? rwy->getSTARs() : apt.getSTARs(), &flightgear::STAR::ident)
+  );
+}
+
+//------------------------------------------------------------------------------
+static naRef f_airport_approaches(FGAirport& apt, const nasal::CallContext& ctx)
+{
+  FGRunway* rwy = runwayFromNasalArg(apt, ctx);
+
+  flightgear::ProcedureType type = flightgear::PROCEDURE_INVALID;
+  std::string type_str = ctx.getArg<std::string>(1);
+  if( !type_str.empty() )
+  {
+    boost::to_upper(type_str);
+    if(      type_str == "NDB" ) type = flightgear::PROCEDURE_APPROACH_NDB;
+    else if( type_str == "VOR" ) type = flightgear::PROCEDURE_APPROACH_VOR;
+    else if( type_str == "ILS" ) type = flightgear::PROCEDURE_APPROACH_ILS;
+    else if( type_str == "RNAV") type = flightgear::PROCEDURE_APPROACH_RNAV;
+  }
+
+  return ctx.to_nasal
+  (
+    extract( rwy ? rwy->getApproaches(type)
+                 // no runway specified, report them all
+                 : apt.getApproaches(type),
+             &flightgear::Approach::ident )
+  );
+}
+
+//------------------------------------------------------------------------------
+static FGParkingList
+f_airport_parking(FGAirport& apt, const nasal::CallContext& ctx)
+{
+  std::string type = ctx.getArg<std::string>(0);
+  bool only_available = ctx.getArg<bool>(1);
+
+  FGAirportDynamics* dynamics = apt.getDynamics();
+  PositionedIDVec parkings =
+    flightgear::NavDataCache::instance()
+      ->airportItemsOfType(apt.guid(), FGPositioned::PARKING);
+
+  FGParkingList ret;
+  BOOST_FOREACH(PositionedID parking, parkings)
+  {
+    // filter out based on availability and type
+    if( only_available && !dynamics->isParkingAvailable(parking) )
+      continue;
+
+    FGParking* park = dynamics->getParking(parking);
+    if( !type.empty() && (park->getType() != type) )
+      continue;
+
+    ret.push_back(park);
+  }
+
+  return ret;
+}
+
+//------------------------------------------------------------------------------
+// Returns Nasal ghost for particular or nearest airport of a <type>, or nil
+// on error. (Currently only airportinfo(<id>) is implemented)
+//
+// airportinfo(<id>);                   e.g. "KSFO"
+// airportinfo(<type>);                 type := ("airport"|"seaport"|"heliport")
+// airportinfo()                        same as  airportinfo("airport")
+// airportinfo(<lat>, <lon> [, <type>]);
+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.
+  return ctx.to_nasal(FGAirport::findByIdent( ctx.requireArg<std::string>(0) ));
+}
+
+//------------------------------------------------------------------------------
+naRef initNasalPositioned_cppbind(naRef globalsRef, naContext c, naRef gcSave)
+{
+  NasalPositioned::init("FGPositioned")
+    .member("id", &FGPositioned::ident)
+    .member("ident", &FGPositioned::ident) // TODO to we really need id and ident?
+    .member("name", &FGPositioned::name)
+    .member("lat", &FGPositioned::latitude)
+    .member("lon", &FGPositioned::longitude)
+    .member("elevation", &FGPositioned::elevationM);
+  NasalRunway::init("FGRunway")
+    .bases<NasalPositioned>();
+  NasalParking::init("FGParking")
+    .bases<NasalPositioned>();
+  NasalCommStation::init("CommStation")
+    .bases<NasalPositioned>()
+    .member("frequency", &flightgear::CommStation::freqMHz);
+  NasalAirport::init("FGAirport")
+    .bases<NasalPositioned>()
+    .member("has_metar", &FGAirport::getMetar)
+    .member("runways", &FGAirport::getRunwayMap)
+    .member("helipads", &FGAirport::getHelipadMap)
+    .member("taxiways", &FGAirport::getTaxiways)
+    .member("pavements", &FGAirport::getPavements)
+    .method("runway", &f_airport_runway)
+    .method("helipad", &f_airport_runway)
+    .method("tower", &FGAirport::getTowerLocation)
+    .method("comms", &f_airport_comms)
+    .method("sids", &f_airport_sids)
+    .method("stars", &f_airport_stars)
+    .method("getApproachList", f_airport_approaches)
+    .method("parking", &f_airport_parking)
+    .method("getSid", &FGAirport::findSIDWithIdent)
+    .method("getStar", &FGAirport::findSTARWithIdent)
+    .method("getIAP", &FGAirport::findApproachWithIdent)
+    .method("tostring", &FGAirport::toString);
+
+  nasal::Hash globals(globalsRef, c),
+              positioned( globals.createHash("positioned") );
+
+  positioned.set("airportinfo", &f_airportinfo);
+
+  return naNil();
+}
index cc99763f519039f727ec2be05fd6ab59cf45de7e..f9e29b9afde8bb6d4e99402ab1e129ffb2331a49 100644 (file)
@@ -665,6 +665,7 @@ void FGNasalSys::init()
     initNasalString(_globals, _string, _context, _gcHash);
 
     initNasalPositioned(_globals, _context, _gcHash);
+    initNasalPositioned_cppbind(_globals, _context, _gcHash);
     NasalClipboard::init(this);
     initNasalCanvas(_globals, _context, _gcHash);
     initNasalCondition(_globals, _context, _gcHash);