- decouple dynamic airport data from the static (nav-db) data.
#include <iostream>
#include <Airports/dynamics.hxx>
+#include <Airports/airportdynamicsmanager.hxx>
#include <Airports/airport.hxx>
#include <Scenery/scenery.hxx>
#include "atc_mgr.hxx"
//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;
fp->setGate(pk);
if (!(fp->createPushBack(&ai_ac,
false,
- apt,
+ dcs->parent(),
aircraftRadius,
fltType,
aircraftType,
} 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;
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.
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:
~FGATCManager();
void init();
void addController(FGATCController *controller);
+ void removeController(FGATCController* controller);
void update(double time);
};
FGATCController::~FGATCController()
{
- //cerr << "running FGATController destructor" << endl;
+ FGATCManager *mgr = (FGATCManager*) globals->get_subsystem("ATC");
+ mgr->removeController(this);
}
string FGATCController::getGateName(FGAIAircraft * ref)
sidstar.cxx
airport.cxx
xmlloader.cxx
+ airportdynamicsmanager.cxx
)
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}")
#include <Main/fg_props.hxx>
#include <Airports/runways.hxx>
#include <Airports/pavement.hxx>
-#include <Airports/dynamics.hxx>
#include <Airports/xmlloader.hxx>
+#include <Airports/dynamics.hxx>
+#include <Airports/airportdynamicsmanager.hxx>
#include <Navaids/procedure.hxx>
#include <Navaids/waypoint.hxx>
#include <ATC/CommStation.hxx>
FGPositioned(aGuid, aType, id, location),
_name(name),
_has_metar(has_metar),
- _dynamics(0),
mTowerDataLoaded(false),
mHasTower(false),
mRunwaysLoaded(false),
FGAirport::~FGAirport()
{
- SG_LOG(SG_NAVAID, SG_INFO, "deleting airport:" << ident());
- delete _dynamics;
}
bool FGAirport::isAirport() const
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
{
}
}
+FGAirportDynamicsRef FGAirport::getDynamics() const
+{
+ return flightgear::AirportDynamicsManager::find(const_cast<FGAirport*>(this));
+}
+
// get airport elevation
double fgGetAirportElev( const std::string& id )
{
FGRunwayRef getActiveRunwayForUsage() const;
- FGAirportDynamics *getDynamics();
+ FGAirportDynamicsRef getDynamics() const;
unsigned int numRunways() const;
unsigned int numHelipads() const;
std::string _name;
bool _has_metar;
- FGAirportDynamics *_dynamics;
void loadRunways() const;
void loadHelipads() const;
--- /dev/null
+// airportdynamicsmanager.cxx - manager for dynamic (changeable)
+// part of airport state
+//
+// Written by James Turner, started December 2015
+//
+// Copyright (C) 2015 James Turner <zakalawe@mac.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.
+
+#include "airportdynamicsmanager.hxx"
+
+#include <simgear/structure/exception.hxx>
+
+#include "airport.hxx"
+#include "xmlloader.hxx"
+#include "dynamics.hxx"
+#include "runwayprefs.hxx"
+
+#include <Main/globals.hxx>
+
+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<AirportDynamicsManager*>(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
--- /dev/null
+// airportdynamicsmanager.hxx - manager for dynamic (changeable)
+// part of airport state
+//
+// Written by James Turner, started December 2015
+//
+// Copyright (C) 2015 James Turner <zakalawe@mac.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.
+
+#ifndef AIRPORTDYNAMICSMANAGER_H
+#define AIRPORTDYNAMICSMANAGER_H
+
+#include <simgear/structure/subsystem_mgr.hxx>
+#include <simgear/structure/SGSharedPtr.hxx>
+
+#include <map>
+
+#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<std::string, FGAirportDynamicsRef> ICAODynamicsDict;
+ ICAODynamicsDict m_dynamics;
+};
+
+} // of namespace
+
+#endif // AIRPORTDYNAMICSMANAGER_H
typedef SGSharedPtr<FGTaxiway> FGTaxiwayRef;
typedef SGSharedPtr<FGPavement> FGPavementRef;
typedef SGSharedPtr<FGParking> FGParkingRef;
+typedef SGSharedPtr<FGAirportDynamics> FGAirportDynamicsRef;
typedef std::vector<FGRunwayRef> FGRunwayList;
typedef std::map<std::string, FGRunwayRef> FGRunwayMap;
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()
unsigned int refCount;
FGParkingRef parking;
- FGAirportRef airport;
+ FGAirportDynamicsRef dynamics;
};
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);
}
}
// 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);
}
// 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
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<FGAirportDynamics*>(this));
}
}
#include <set>
+#include <simgear/structure/SGReferenced.hxx>
+
#include <ATC/trafficcontrol.hxx>
#include "airports_fwd.hxx"
#include "parking.hxx"
~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);
ParkingAssignmentPrivate* _sharedData;
};
-class FGAirportDynamics {
+class FGAirportDynamics : public SGReferenced
+{
private:
FGAirport* _ap;
bool isParkingAvailable(FGParking* parking) const;
- FGParkingRef getParking(FGParking* i) const;
void releaseParking(FGParking* id);
FGParkingList getParkings(bool onlyAvailable, const std::string& type) const;
}
FGGroundNetwork::FGGroundNetwork() :
- parent(NULL)
+ dynamics(NULL),
+ parent(NULL)
{
hasNetwork = false;
totalDistance = 0;
// 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");
return;
}
- parent = pr;
+ dynamics = dyn;
+ parent = dyn->parent();
assert(parent);
hasNetwork = true;
nextSave = 0;
FGAIAircraft * aircraft)
{
- assert(parent);
- init(parent);
+ assert(dynamics);
+ init(dynamics);
TrafficVectorIterator i = activeTraffic.begin();
// Search search if the current id alread has an entry
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;
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);
}
//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;
private:
friend class FGAirportDynamicsXMLLoader;
+ FGAirportDynamics* dynamics; // weak back-pointer to our owner
bool hasNetwork;
bool networkInitialized;
time_t nextSave;
void setVersion (int v) { version = v;};
int getVersion() { return version; };
- void init(FGAirport* pr);
+ void init(FGAirportDynamics* pr);
bool exists() {
return hasNetwork;
};
return;
}
-
SG_LOG(SG_NAVAID, SG_INFO, "reading groundnet data from " << path);
SGTimeStamp t;
+ t.stamp();
try {
FGAirportDynamicsXMLLoader visitor(d);
readXML(path.str(), visitor);
#include <Airports/runways.hxx>
#include <Airports/airport.hxx>
#include <Airports/dynamics.hxx>
+#include <Airports/airportdynamicsmanager.hxx>
#include <AIModel/AIManager.hxx>
globals->add_subsystem("properties", new FGProperties);
+ ////////////////////////////////////////////////////////////////////
+ // Add the FlightGear property utilities.
+ ////////////////////////////////////////////////////////////////////
+ globals->add_subsystem("airport-dynamics", new flightgear::AirportDynamicsManager);
+
////////////////////////////////////////////////////////////////////
// Add the performance monitoring system.
////////////////////////////////////////////////////////////////////
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");
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) {
{
std::string type = ctx.getArg<std::string>(0);
bool only_available = ctx.getArg<bool>(1);
- FGAirportDynamics* dynamics = apt.getDynamics();
+ FGAirportDynamicsRef dynamics = apt.getDynamics();
return dynamics->getParkings(only_available, type);
}