From 4b573ebd13bbf301795f57293a0e190d0993ea47 Mon Sep 17 00:00:00 2001 From: Thomas Geymayer Date: Mon, 4 Mar 2013 19:24:47 +0100 Subject: [PATCH] Start porting NasalPositioned to cppbind. For now it is available in the positioned Nasal module. FGAirport is fully ported, but especially procedures/navaids and free functions are still missing. --- src/AIModel/AIFlightPlan.hxx | 8 - src/Airports/airport.hxx | 2 + src/Airports/airports_fwd.hxx | 9 +- src/Airports/parking.hxx | 3 + src/Navaids/FlightPlan.hxx | 2 - src/Navaids/awynet.cxx | 4 +- src/Navaids/procedure.hxx | 2 - src/Navaids/waypoint.hxx | 5 +- src/Scripting/CMakeLists.txt | 1 + src/Scripting/NasalPositioned.hxx | 1 + src/Scripting/NasalPositioned_cppbind.cxx | 312 ++++++++++++++++++++++ src/Scripting/NasalSys.cxx | 1 + 12 files changed, 328 insertions(+), 22 deletions(-) create mode 100644 src/Scripting/NasalPositioned_cppbind.cxx diff --git a/src/AIModel/AIFlightPlan.hxx b/src/AIModel/AIFlightPlan.hxx index 7c9881ada..bfd445b27 100644 --- a/src/AIModel/AIFlightPlan.hxx +++ b/src/AIModel/AIFlightPlan.hxx @@ -28,14 +28,6 @@ #include #include -// forward decls -class FGTaxiRoute; -class FGRunway; -class FGAIAircraft; -class FGAirport; - -typedef SGSharedPtr FGAirportRef; - class FGAIWaypoint { private: std::string name; diff --git a/src/Airports/airport.hxx b/src/Airports/airport.hxx index 3ca4d62c7..d32326c65 100644 --- a/src/Airports/airport.hxx +++ b/src/Airports/airport.hxx @@ -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(); } diff --git a/src/Airports/airports_fwd.hxx b/src/Airports/airports_fwd.hxx index ecb76a50f..6ea223441 100644 --- a/src/Airports/airports_fwd.hxx +++ b/src/Airports/airports_fwd.hxx @@ -59,12 +59,17 @@ namespace flightgear { typedef std::map AirportCache; } +typedef SGSharedPtr FGAirportRef; +typedef SGSharedPtr FGRunwayRef; +typedef SGSharedPtr FGParkingRef; + typedef std::vector FGRunwayList; typedef std::map FGRunwayMap; typedef std::map FGHelipadMap; typedef std::vector FGTaxiwayList; typedef std::vector FGPavementList; +typedef std::vector FGParkingList; typedef std::vector FGTaxiSegmentVector; typedef FGTaxiSegmentVector::iterator FGTaxiSegmentVectorIterator; @@ -83,10 +88,6 @@ typedef std::vector::iterator TimeVectorIterator; typedef std::vector TaxiRouteVector; typedef std::vector::iterator TaxiRouteVectorIterator; -typedef std::vector FGParkingVec; -typedef FGParkingVec::iterator FGParkingVecIterator; -typedef FGParkingVec::const_iterator FGParkingVecConstIterator; - typedef std::vector RunwayListVec; typedef std::vector::iterator RunwayListVectorIterator; typedef std::vector::const_iterator RunwayListVecConstIterator; diff --git a/src/Airports/parking.hxx b/src/Airports/parking.hxx index 6d8892c80..92b790084 100644 --- a/src/Airports/parking.hxx +++ b/src/Airports/parking.hxx @@ -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 { diff --git a/src/Navaids/FlightPlan.hxx b/src/Navaids/FlightPlan.hxx index d00c4860f..fd44b38de 100644 --- a/src/Navaids/FlightPlan.hxx +++ b/src/Navaids/FlightPlan.hxx @@ -27,8 +27,6 @@ #include #include -typedef SGSharedPtr FGAirportRef; - namespace flightgear { diff --git a/src/Navaids/awynet.cxx b/src/Navaids/awynet.cxx index 7642673b5..e1476615a 100644 --- a/src/Navaids/awynet.cxx +++ b/src/Navaids/awynet.cxx @@ -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()); diff --git a/src/Navaids/procedure.hxx b/src/Navaids/procedure.hxx index 146e237ad..d1ecf9804 100644 --- a/src/Navaids/procedure.hxx +++ b/src/Navaids/procedure.hxx @@ -26,8 +26,6 @@ #include #include -typedef SGSharedPtr FGRunwayRef; - namespace flightgear { // forward decls diff --git a/src/Navaids/waypoint.hxx b/src/Navaids/waypoint.hxx index d01070b6f..377049ab0 100644 --- a/src/Navaids/waypoint.hxx +++ b/src/Navaids/waypoint.hxx @@ -20,13 +20,10 @@ #ifndef FG_WAYPOINT_HXX #define FG_WAYPOINT_HXX +#include #include #include -class FGAirport; -typedef SGSharedPtr FGAirportRef; -class FGRunway; - namespace flightgear { diff --git a/src/Scripting/CMakeLists.txt b/src/Scripting/CMakeLists.txt index 586d4a4a7..e91d6aeb6 100644 --- a/src/Scripting/CMakeLists.txt +++ b/src/Scripting/CMakeLists.txt @@ -4,6 +4,7 @@ set(SOURCES NasalSys.cxx nasal-props.cxx NasalPositioned.cxx + NasalPositioned_cppbind.cxx NasalCanvas.cxx NasalClipboard.cxx NasalCondition.cxx diff --git a/src/Scripting/NasalPositioned.hxx b/src/Scripting/NasalPositioned.hxx index a3b7514d2..14401e9c2 100644 --- a/src/Scripting/NasalPositioned.hxx +++ b/src/Scripting/NasalPositioned.hxx @@ -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 index 000000000..b2ae98c4d --- /dev/null +++ b/src/Scripting/NasalPositioned_cppbind.cxx @@ -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 +// +// 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 +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +typedef nasal::Ghost NasalPositioned; +typedef nasal::Ghost NasalRunway; +typedef nasal::Ghost NasalParking; +typedef nasal::Ghost NasalAirport; +typedef nasal::Ghost 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 +std::vector extract( const std::vector& in, + T (C2::*getter)() const ) +{ + std::vector 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(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(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(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(0); + bool only_available = ctx.getArg(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 , or nil +// on error. (Currently only airportinfo() is implemented) +// +// airportinfo(); e.g. "KSFO" +// airportinfo(); type := ("airport"|"seaport"|"heliport") +// airportinfo() same as airportinfo("airport") +// airportinfo(, [, ]); +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(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(); + NasalParking::init("FGParking") + .bases(); + NasalCommStation::init("CommStation") + .bases() + .member("frequency", &flightgear::CommStation::freqMHz); + NasalAirport::init("FGAirport") + .bases() + .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(); +} diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx index cc99763f5..f9e29b9af 100644 --- a/src/Scripting/NasalSys.cxx +++ b/src/Scripting/NasalSys.cxx @@ -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); -- 2.39.5