From: James Turner Date: Sat, 5 Dec 2015 00:25:29 +0000 (+0000) Subject: Add airport dynamics manager X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=2af076e6cb12764c53a300c19c8d5310693b1b29;p=flightgear.git Add airport dynamics manager - decouple dynamic airport data from the static (nav-db) data. --- diff --git a/src/ATC/atc_mgr.cxx b/src/ATC/atc_mgr.cxx index c511b66f6..fc5a06c2a 100644 --- a/src/ATC/atc_mgr.cxx +++ b/src/ATC/atc_mgr.cxx @@ -27,6 +27,7 @@ #include #include +#include #include #include #include "atc_mgr.hxx" @@ -102,17 +103,17 @@ void FGATCManager::init() { //time_t deptime = 0; // just make sure how flightplan processing is affected by this... - FGAirport *apt = FGAirport::findByIdent(airport); - if (apt && onGround) {// && !runway.empty()) { - FGAirportDynamics* dcs = apt->getDynamics(); + FGAirportDynamicsRef dcs(flightgear::AirportDynamicsManager::find(airport)); + if (dcs && onGround) {// && !runway.empty()) { + ParkingAssignment pk(dcs->getParkingByName(parking)); // No valid parking location, so either at the runway or at a random location. if (pk.isValid()) { dcs->setParkingAvailable(pk.parking(), false); fp = new FGAIFlightPlan; - controller = apt->getDynamics()->getStartupController(); - int stationFreq = apt->getDynamics()->getGroundFrequency(1); + controller = dcs->getStartupController(); + int stationFreq = dcs->getGroundFrequency(1); if (stationFreq > 0) { //cerr << "Setting radio frequency to : " << stationFreq << endl; @@ -128,7 +129,7 @@ void FGATCManager::init() { fp->setGate(pk); if (!(fp->createPushBack(&ai_ac, false, - apt, + dcs->parent(), aircraftRadius, fltType, aircraftType, @@ -140,8 +141,8 @@ void FGATCManager::init() { } else if (!runway.empty()) { - controller = apt->getDynamics()->getTowerController(); - int stationFreq = apt->getDynamics()->getTowerFrequency(2); + controller = dcs->getTowerController(); + int stationFreq = dcs->getTowerFrequency(2); if (stationFreq > 0) { //cerr << "Setting radio frequency to in airfrequency: " << stationFreq << endl; @@ -151,7 +152,7 @@ void FGATCManager::init() { leg = 3; string fltType = "ga"; fp->setRunway(runway); - fp->createTakeOff(&ai_ac, false, apt, 0, fltType); + fp->createTakeOff(&ai_ac, false, dcs->parent(), 0, fltType); ai_ac.setTakeOffStatus(2); } else { // We're on the ground somewhere. Handle this case later. @@ -189,6 +190,15 @@ void FGATCManager::addController(FGATCController *controller) { activeStations.push_back(controller); } +void FGATCManager::removeController(FGATCController *controller) +{ + AtcVecIterator it; + it = std::find(activeStations.begin(), activeStations.end(), controller); + if (it != activeStations.end()) { + activeStations.erase(it); + } +} + void FGATCManager::update ( double time ) { //cerr << "ATC update code is running at time: " << time << endl; // Test code: let my virtual co-pilot handle ATC: diff --git a/src/ATC/atc_mgr.hxx b/src/ATC/atc_mgr.hxx index 09d40197a..9f9545730 100644 --- a/src/ATC/atc_mgr.hxx +++ b/src/ATC/atc_mgr.hxx @@ -59,6 +59,7 @@ public: ~FGATCManager(); void init(); void addController(FGATCController *controller); + void removeController(FGATCController* controller); void update(double time); }; diff --git a/src/ATC/trafficcontrol.cxx b/src/ATC/trafficcontrol.cxx index 065658058..e86ad1e53 100644 --- a/src/ATC/trafficcontrol.cxx +++ b/src/ATC/trafficcontrol.cxx @@ -490,7 +490,8 @@ FGATCController::FGATCController() FGATCController::~FGATCController() { - //cerr << "running FGATController destructor" << endl; + FGATCManager *mgr = (FGATCManager*) globals->get_subsystem("ATC"); + mgr->removeController(this); } string FGATCController::getGateName(FGAIAircraft * ref) diff --git a/src/Airports/CMakeLists.txt b/src/Airports/CMakeLists.txt index e83261507..48e8cf824 100644 --- a/src/Airports/CMakeLists.txt +++ b/src/Airports/CMakeLists.txt @@ -15,6 +15,7 @@ set(SOURCES sidstar.cxx airport.cxx xmlloader.cxx + airportdynamicsmanager.cxx ) set(HEADERS @@ -33,6 +34,7 @@ set(HEADERS sidstar.hxx airport.hxx xmlloader.hxx + airportdynamicsmanager.hxx ) -flightgear_component(Airports "${SOURCES}" "${HEADERS}") \ No newline at end of file +flightgear_component(Airports "${SOURCES}" "${HEADERS}") diff --git a/src/Airports/airport.cxx b/src/Airports/airport.cxx index 13f7a7a87..f284fb55a 100644 --- a/src/Airports/airport.cxx +++ b/src/Airports/airport.cxx @@ -46,8 +46,9 @@ #include
#include #include -#include #include +#include +#include #include #include #include @@ -74,7 +75,6 @@ FGAirport::FGAirport( PositionedID aGuid, FGPositioned(aGuid, aType, id, location), _name(name), _has_metar(has_metar), - _dynamics(0), mTowerDataLoaded(false), mHasTower(false), mRunwaysLoaded(false), @@ -90,8 +90,6 @@ FGAirport::FGAirport( PositionedID aGuid, FGAirport::~FGAirport() { - SG_LOG(SG_NAVAID, SG_INFO, "deleting airport:" << ident()); - delete _dynamics; } bool FGAirport::isAirport() const @@ -118,23 +116,6 @@ bool FGAirport::isAirportType(FGPositioned* pos) return (pos->type() >= AIRPORT) && (pos->type() <= SEAPORT); } -FGAirportDynamics * FGAirport::getDynamics() -{ - if (_dynamics) { - return _dynamics; - } - - _dynamics = new FGAirportDynamics(this); - XMLLoader::load(_dynamics); - _dynamics->init(); - - FGRunwayPreference rwyPrefs(this); - XMLLoader::load(&rwyPrefs); - _dynamics->setRwyUse(rwyPrefs); - - return _dynamics; -} - //------------------------------------------------------------------------------ unsigned int FGAirport::numRunways() const { @@ -983,6 +964,11 @@ void FGAirport::sortBySize(FGPositionedList& airportList) } } +FGAirportDynamicsRef FGAirport::getDynamics() const +{ + return flightgear::AirportDynamicsManager::find(const_cast(this)); +} + // get airport elevation double fgGetAirportElev( const std::string& id ) { diff --git a/src/Airports/airport.hxx b/src/Airports/airport.hxx index 598a1df07..d5ad1a0e3 100644 --- a/src/Airports/airport.hxx +++ b/src/Airports/airport.hxx @@ -89,7 +89,7 @@ class FGAirport : public FGPositioned FGRunwayRef getActiveRunwayForUsage() const; - FGAirportDynamics *getDynamics(); + FGAirportDynamicsRef getDynamics() const; unsigned int numRunways() const; unsigned int numHelipads() const; @@ -323,7 +323,6 @@ private: std::string _name; bool _has_metar; - FGAirportDynamics *_dynamics; void loadRunways() const; void loadHelipads() const; diff --git a/src/Airports/airportdynamicsmanager.cxx b/src/Airports/airportdynamicsmanager.cxx new file mode 100644 index 000000000..99885fb2e --- /dev/null +++ b/src/Airports/airportdynamicsmanager.cxx @@ -0,0 +1,107 @@ +// airportdynamicsmanager.cxx - manager for dynamic (changeable) +// part of airport state +// +// Written by James Turner, started December 2015 +// +// Copyright (C) 2015 James Turner +// +// 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. + +#include "airportdynamicsmanager.hxx" + +#include + +#include "airport.hxx" +#include "xmlloader.hxx" +#include "dynamics.hxx" +#include "runwayprefs.hxx" + +#include
+ +namespace flightgear +{ + +AirportDynamicsManager::AirportDynamicsManager() +{ + +} + + +AirportDynamicsManager::~AirportDynamicsManager() +{ + + +} + +void AirportDynamicsManager::init() +{ + + +} + +void AirportDynamicsManager::shutdown() +{ + m_dynamics.clear(); +} + +void AirportDynamicsManager::update(double dt) +{ + SG_UNUSED(dt); +} + +void AirportDynamicsManager::reinit() +{ + shutdown(); + init(); +} + +FGAirportDynamicsRef AirportDynamicsManager::dynamicsForICAO(const std::string &icao) +{ + ICAODynamicsDict::iterator it = m_dynamics.find(icao); + if (it != m_dynamics.end()) { + return it->second; + } + + FGAirportRef apt(FGAirport::findByIdent(icao)); + if (!apt) + throw sg_exception("dynamicsForICAO: Invalid ICAO:" + icao); + FGAirportDynamicsRef d(new FGAirportDynamics(apt)); + + XMLLoader::load(d.ptr()); + d->init(); + + FGRunwayPreference rwyPrefs(apt); + XMLLoader::load(&rwyPrefs); + d->setRwyUse(rwyPrefs); + + m_dynamics[icao] = d; + return d; +} + +FGAirportDynamicsRef AirportDynamicsManager::find(const std::string &icao) +{ + AirportDynamicsManager* instance = static_cast(globals->get_subsystem("airport-dynamics")); + if (!instance) + return FGAirportDynamicsRef(); + + return instance->dynamicsForICAO(icao); +} + +FGAirportDynamicsRef AirportDynamicsManager::find(const FGAirportRef& apt) +{ + return find(apt->ident()); +} + +} // of namespace flightgear diff --git a/src/Airports/airportdynamicsmanager.hxx b/src/Airports/airportdynamicsmanager.hxx new file mode 100644 index 000000000..26172dbda --- /dev/null +++ b/src/Airports/airportdynamicsmanager.hxx @@ -0,0 +1,58 @@ +// airportdynamicsmanager.hxx - manager for dynamic (changeable) +// part of airport state +// +// Written by James Turner, started December 2015 +// +// Copyright (C) 2015 James Turner +// +// 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. + +#ifndef AIRPORTDYNAMICSMANAGER_H +#define AIRPORTDYNAMICSMANAGER_H + +#include +#include + +#include + +#include "airports_fwd.hxx" + +namespace flightgear +{ + +class AirportDynamicsManager : public SGSubsystem +{ +public: + AirportDynamicsManager(); + virtual ~AirportDynamicsManager(); + + virtual void init(); + virtual void shutdown(); + virtual void update (double dt); + virtual void reinit(); + + static FGAirportDynamicsRef find(const std::string& icao); + + static FGAirportDynamicsRef find(const FGAirportRef& apt); + + FGAirportDynamicsRef dynamicsForICAO(const std::string& icao); +private: + typedef std::map ICAODynamicsDict; + ICAODynamicsDict m_dynamics; +}; + +} // of namespace + +#endif // AIRPORTDYNAMICSMANAGER_H diff --git a/src/Airports/airports_fwd.hxx b/src/Airports/airports_fwd.hxx index a596f3db9..3918a8834 100644 --- a/src/Airports/airports_fwd.hxx +++ b/src/Airports/airports_fwd.hxx @@ -79,6 +79,7 @@ typedef SGSharedPtr FGHelipadRef; typedef SGSharedPtr FGTaxiwayRef; typedef SGSharedPtr FGPavementRef; typedef SGSharedPtr FGParkingRef; +typedef SGSharedPtr FGAirportDynamicsRef; typedef std::vector FGRunwayList; typedef std::map FGRunwayMap; diff --git a/src/Airports/dynamics.cxx b/src/Airports/dynamics.cxx index 9d17f2b34..ffc4a0959 100644 --- a/src/Airports/dynamics.cxx +++ b/src/Airports/dynamics.cxx @@ -53,19 +53,19 @@ using std::random_shuffle; class ParkingAssignment::ParkingAssignmentPrivate { public: - ParkingAssignmentPrivate(FGParking* pk, FGAirport* apt) : + ParkingAssignmentPrivate(FGParking* pk, FGAirportDynamics* dyn) : refCount(0), parking(pk), - airport(apt) + dynamics(dyn) { assert(pk); - assert(apt); + assert(dyn); retain(); // initial count of 1 } ~ParkingAssignmentPrivate() { - airport->getDynamics()->releaseParking(parking); + dynamics->releaseParking(parking); } void release() @@ -82,7 +82,7 @@ public: unsigned int refCount; FGParkingRef parking; - FGAirportRef airport; + FGAirportDynamicsRef dynamics; }; ParkingAssignment::ParkingAssignment() : @@ -97,11 +97,11 @@ ParkingAssignment::~ParkingAssignment() } } -ParkingAssignment::ParkingAssignment(FGParking* pk, FGAirport* apt) : +ParkingAssignment::ParkingAssignment(FGParking* pk, FGAirportDynamics* dyn) : _sharedData(NULL) { if (pk) { - _sharedData = new ParkingAssignmentPrivate(pk, apt); + _sharedData = new ParkingAssignmentPrivate(pk, dyn); } } @@ -164,13 +164,14 @@ FGAirportDynamics::FGAirportDynamics(FGAirport * ap): // Destructor FGAirportDynamics::~FGAirportDynamics() { + SG_LOG(SG_AI, SG_INFO, "destroyed dynamics for:" << _ap->ident()); } // Initialization required after XMLRead void FGAirportDynamics::init() { - groundNetwork.init(_ap); + groundNetwork.init(this); groundNetwork.setTowerController(&towerController); } @@ -213,18 +214,18 @@ ParkingAssignment FGAirportDynamics::getAvailableParking(double radius, const st // most exact seach - airline codes must be present and match FGParking* result = innerGetAvailableParking(radius, flType, airline, true); if (result) { - return ParkingAssignment(result, _ap); + return ParkingAssignment(result, this); } // more tolerant - gates with empty airline codes are permitted result = innerGetAvailableParking(radius, flType, airline, false); if (result) { - return ParkingAssignment(result, _ap); + return ParkingAssignment(result, this); } // fallback - ignore the airline code entirely result = innerGetAvailableParking(radius, flType, string(), false); - return result ? ParkingAssignment(result, _ap) : ParkingAssignment(); + return result ? ParkingAssignment(result, this) : ParkingAssignment(); } ParkingAssignment FGAirportDynamics::getParkingByName(const std::string& name) const @@ -233,7 +234,7 @@ ParkingAssignment FGAirportDynamics::getParkingByName(const std::string& name) c FGParkingList::const_iterator it; for (it = parkings.begin(); it != parkings.end(); ++it) { if ((*it)->name() == name) { - return ParkingAssignment(*it, _ap); + return ParkingAssignment(*it, const_cast(this)); } } diff --git a/src/Airports/dynamics.hxx b/src/Airports/dynamics.hxx index 75a97f598..85c98b9d8 100644 --- a/src/Airports/dynamics.hxx +++ b/src/Airports/dynamics.hxx @@ -24,6 +24,8 @@ #include +#include + #include #include "airports_fwd.hxx" #include "parking.hxx" @@ -37,7 +39,7 @@ public: ~ParkingAssignment(); // create a parking assignment (and mark it as unavailable) - ParkingAssignment(FGParking* pk, FGAirport* apt); + ParkingAssignment(FGParking* pk, FGAirportDynamics* apt); ParkingAssignment(const ParkingAssignment& aOther); void operator=(const ParkingAssignment& aOther); @@ -53,7 +55,8 @@ private: ParkingAssignmentPrivate* _sharedData; }; -class FGAirportDynamics { +class FGAirportDynamics : public SGReferenced +{ private: FGAirport* _ap; @@ -140,7 +143,6 @@ public: bool isParkingAvailable(FGParking* parking) const; - FGParkingRef getParking(FGParking* i) const; void releaseParking(FGParking* id); FGParkingList getParkings(bool onlyAvailable, const std::string& type) const; diff --git a/src/Airports/groundnetwork.cxx b/src/Airports/groundnetwork.cxx index a2c9b39ae..1f337a957 100644 --- a/src/Airports/groundnetwork.cxx +++ b/src/Airports/groundnetwork.cxx @@ -175,7 +175,8 @@ bool compare_trafficrecords(FGTrafficRecord a, FGTrafficRecord b) } FGGroundNetwork::FGGroundNetwork() : - parent(NULL) + dynamics(NULL), + parent(NULL) { hasNetwork = false; totalDistance = 0; @@ -199,7 +200,7 @@ FGGroundNetwork::~FGGroundNetwork() // owning references to ground-net nodes will also drop } -void FGGroundNetwork::init(FGAirport* pr) +void FGGroundNetwork::init(FGAirportDynamics* dyn) { if (networkInitialized) { SG_LOG(SG_GENERAL, SG_WARN, "duplicate ground-network init"); @@ -207,7 +208,8 @@ void FGGroundNetwork::init(FGAirport* pr) return; } - parent = pr; + dynamics = dyn; + parent = dyn->parent(); assert(parent); hasNetwork = true; nextSave = 0; @@ -407,8 +409,8 @@ void FGGroundNetwork::announcePosition(int id, FGAIAircraft * aircraft) { - assert(parent); - init(parent); + assert(dynamics); + init(dynamics); TrafficVectorIterator i = activeTraffic.begin(); // Search search if the current id alread has an entry @@ -495,11 +497,11 @@ bool FGGroundNetwork::checkTransmissionState(int minState, int maxState, Traffic FGATCDialogNew::instance()->removeEntry(1); } else { //cerr << "creating message for " << i->getAircraft()->getCallSign() << endl; - transmit(&(*i), &(*parent->getDynamics()), msgId, msgDir, false); + transmit(&(*i), dynamics, msgId, msgDir, false); return false; } } - transmit(&(*i), &(*parent->getDynamics()), msgId, msgDir, true); + transmit(&(*i), dynamics, msgId, msgDir, true); i->updateState(); lastTransmission = now; available = false; @@ -846,11 +848,11 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat, if ((origStatus != currStatus) && available) { //cerr << "Issueing hold short instrudtion " << currStatus << " " << available << endl; if (currStatus == true) { // No has a hold short instruction - transmit(&(*current), &(*parent->getDynamics()), MSG_HOLD_POSITION, ATC_GROUND_TO_AIR, true); + transmit(&(*current), dynamics, MSG_HOLD_POSITION, ATC_GROUND_TO_AIR, true); //cerr << "Transmittin hold short instrudtion " << currStatus << " " << available << endl; current->setState(1); } else { - transmit(&(*current), &(*parent->getDynamics()), MSG_RESUME_TAXI, ATC_GROUND_TO_AIR, true); + transmit(&(*current), dynamics, MSG_RESUME_TAXI, ATC_GROUND_TO_AIR, true); //cerr << "Transmittig resume instrudtion " << currStatus << " " << available << endl; current->setState(2); } @@ -1305,8 +1307,8 @@ void FGGroundNetwork::update(double dt) //sort(activeTraffic.begin(), activeTraffic.end(), compare_trafficrecords); // Handle traffic that is under ground control first; this way we'll prevent clutter at the gate areas. // Don't allow an aircraft to pushback when a taxiing aircraft is currently using part of the intended route. - for (TrafficVectorIterator i = parent->getDynamics()->getStartupController()->getActiveTraffic().begin(); - i != parent->getDynamics()->getStartupController()->getActiveTraffic().end(); i++) { + for (TrafficVectorIterator i = dynamics->getStartupController()->getActiveTraffic().begin(); + i != dynamics->getStartupController()->getActiveTraffic().end(); i++) { i->allowPushBack(); i->setPriority(priority++); // in meters per second; diff --git a/src/Airports/groundnetwork.hxx b/src/Airports/groundnetwork.hxx index 8e9b55cf9..3dd4c1cf0 100644 --- a/src/Airports/groundnetwork.hxx +++ b/src/Airports/groundnetwork.hxx @@ -177,6 +177,7 @@ class FGGroundNetwork : public FGATCController private: friend class FGAirportDynamicsXMLLoader; + FGAirportDynamics* dynamics; // weak back-pointer to our owner bool hasNetwork; bool networkInitialized; time_t nextSave; @@ -218,7 +219,7 @@ public: void setVersion (int v) { version = v;}; int getVersion() { return version; }; - void init(FGAirport* pr); + void init(FGAirportDynamics* pr); bool exists() { return hasNetwork; }; diff --git a/src/Airports/xmlloader.cxx b/src/Airports/xmlloader.cxx index bc54e1247..cdd362714 100644 --- a/src/Airports/xmlloader.cxx +++ b/src/Airports/xmlloader.cxx @@ -49,9 +49,9 @@ void XMLLoader::load(FGAirportDynamics* d) return; } - SG_LOG(SG_NAVAID, SG_INFO, "reading groundnet data from " << path); SGTimeStamp t; + t.stamp(); try { FGAirportDynamicsXMLLoader visitor(d); readXML(path.str(), visitor); diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 6e803d94f..56111fbc9 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -80,6 +80,7 @@ #include #include #include +#include #include @@ -712,6 +713,11 @@ void fgCreateSubsystems(bool duringReset) { globals->add_subsystem("properties", new FGProperties); + //////////////////////////////////////////////////////////////////// + // Add the FlightGear property utilities. + //////////////////////////////////////////////////////////////////// + globals->add_subsystem("airport-dynamics", new flightgear::AirportDynamicsManager); + //////////////////////////////////////////////////////////////////// // Add the performance monitoring system. //////////////////////////////////////////////////////////////////// diff --git a/src/Main/positioninit.cxx b/src/Main/positioninit.cxx index 366f122cb..b2221842b 100644 --- a/src/Main/positioninit.cxx +++ b/src/Main/positioninit.cxx @@ -196,7 +196,7 @@ static bool fgSetPosFromAirportIDandParkpos( const string& id, const string& par SG_LOG( SG_GENERAL, SG_ALERT, "Failed to find airport " << id ); return false; } - FGAirportDynamics* dcs = apt->getDynamics(); + FGAirportDynamicsRef dcs = apt->getDynamics(); if (!dcs) { SG_LOG( SG_GENERAL, SG_ALERT, "Airport " << id << "does not appear to have parking information available"); diff --git a/src/Scripting/NasalPositioned.cxx b/src/Scripting/NasalPositioned.cxx index 275929de2..4fe2ef9f7 100644 --- a/src/Scripting/NasalPositioned.cxx +++ b/src/Scripting/NasalPositioned.cxx @@ -1351,7 +1351,7 @@ static naRef f_airport_parking(naContext c, naRef me, int argc, naRef* args) onlyAvailable = (args[1].num != 0.0); } - FGAirportDynamics* dynamics = apt->getDynamics(); + FGAirportDynamicsRef dynamics = apt->getDynamics(); FGParkingList parkings = dynamics->getParkings(onlyAvailable, type); FGParkingList::const_iterator it; for (it = parkings.begin(); it != parkings.end(); ++it) { diff --git a/src/Scripting/NasalPositioned_cppbind.cxx b/src/Scripting/NasalPositioned_cppbind.cxx index eef345155..35de1747a 100644 --- a/src/Scripting/NasalPositioned_cppbind.cxx +++ b/src/Scripting/NasalPositioned_cppbind.cxx @@ -208,7 +208,7 @@ f_airport_parking(FGAirport& apt, nasal::CallContext ctx) { std::string type = ctx.getArg(0); bool only_available = ctx.getArg(1); - FGAirportDynamics* dynamics = apt.getDynamics(); + FGAirportDynamicsRef dynamics = apt.getDynamics(); return dynamics->getParkings(only_available, type); }