diff --git a/src/AIModel/AIManager.cxx b/src/AIModel/AIManager.cxx index fe9e4ee13..ae6c75321 100644 --- a/src/AIModel/AIManager.cxx +++ b/src/AIModel/AIManager.cxx @@ -182,6 +182,9 @@ FGAIManager::shutdown() unloadAllScenarios(); BOOST_FOREACH(FGAIBase* ai, ai_list) { + // other subsystems, especially ATC, may have references. This + // lets them detect if the AI object should be skipped + ai->setDie(true); ai->unbind(); } diff --git a/src/ATC/GroundController.cxx b/src/ATC/GroundController.cxx index d4b71f3db..60699ebc7 100644 --- a/src/ATC/GroundController.cxx +++ b/src/ATC/GroundController.cxx @@ -116,7 +116,7 @@ void FGGroundController::announcePosition(int id, TrafficVectorIterator i = activeTraffic.begin(); // Search search if the current id alread has an entry // This might be faster using a map instead of a vector, but let's start by taking a safe route - if (activeTraffic.size()) { + if (!activeTraffic.empty()) { //while ((i->getId() != id) && i != activeTraffic.end()) { while (i != activeTraffic.end()) { if (i->getId() == id) { @@ -126,7 +126,7 @@ void FGGroundController::announcePosition(int id, } } // Add a new TrafficRecord if no one exsists for this aircraft. - if (i == activeTraffic.end() || (activeTraffic.size() == 0)) { + if (i == activeTraffic.end() || (activeTraffic.empty())) { FGTrafficRecord rec; rec.setId(id); rec.setLeg(leg); @@ -973,6 +973,9 @@ void FGGroundController::update(double dt) for (i = activeTraffic.begin(); i != activeTraffic.end(); i++) { updateActiveTraffic(i, priority, now); } + + eraseDeadTraffic(startupTraffic); + eraseDeadTraffic(activeTraffic); } void FGGroundController::updateStartupTraffic(TrafficVectorIterator i, @@ -1044,18 +1047,23 @@ void FGGroundController::updateStartupTraffic(TrafficVectorIterator i, } } -void FGGroundController::updateActiveTraffic(TrafficVectorIterator i, +bool FGGroundController::updateActiveTraffic(TrafficVectorIterator i, int& priority, time_t now) { if (!i->getAircraft()) { SG_LOG(SG_ATC, SG_ALERT, "updateActiveTraffic: missing aircraft"); - return; + return false; + } + + if (i->getAircraft()->getDie()) { + // aircraft has died + return false; } if (!i->getAircraft()->getPerformance()) { SG_LOG(SG_ATC, SG_ALERT, "updateActiveTraffic: missing aircraft performance"); - return; + return false; } double length = 0; @@ -1064,7 +1072,7 @@ void FGGroundController::updateActiveTraffic(TrafficVectorIterator i, if (!network) { SG_LOG(SG_ATC, SG_ALERT, "updateActiveTraffic: missing ground network"); - return; + return false; } i->setPriority(priority++); @@ -1097,4 +1105,6 @@ void FGGroundController::updateActiveTraffic(TrafficVectorIterator i, network->blockSegmentsEndingAt(seg, i->getId(), blockTime - 30, now); } } + + return true; } diff --git a/src/ATC/GroundController.hxx b/src/ATC/GroundController.hxx index 42fe0583e..d200cfb4a 100644 --- a/src/ATC/GroundController.hxx +++ b/src/ATC/GroundController.hxx @@ -59,7 +59,7 @@ private: void updateStartupTraffic(TrafficVectorIterator i, int& priority, time_t now); - void updateActiveTraffic(TrafficVectorIterator i, int& priority, time_t now); + bool updateActiveTraffic(TrafficVectorIterator i, int& priority, time_t now); public: FGGroundController(); ~FGGroundController(); diff --git a/src/ATC/trafficcontrol.cxx b/src/ATC/trafficcontrol.cxx index 6b77890a0..dda040118 100644 --- a/src/ATC/trafficcontrol.cxx +++ b/src/ATC/trafficcontrol.cxx @@ -459,6 +459,10 @@ bool FGTrafficRecord::isOpposing(FGGroundNetwork * net, bool FGTrafficRecord::isActive(int margin) const { + if (aircraft->getDie()) { + return false; + } + time_t now = globals->get_time_params()->get_cur_time(); time_t deptime = aircraft->getTrafficRef()->getDepartureTime(); return ((now + margin) > deptime); @@ -839,6 +843,26 @@ void FGATCController::init() } } +class AircraftIsDead +{ +public: + bool operator()(const FGTrafficRecord& traffic) const + { + if (!traffic.getAircraft()) { + return true; + } + + return traffic.getAircraft()->getDie(); + } +}; + +void FGATCController::eraseDeadTraffic(TrafficVector& vec) +{ + TrafficVector::iterator it = std::remove_if(vec.begin(), vec.end(), AircraftIsDead()); + vec.erase(it, vec.end()); +} + + /*************************************************************************** * class FGTowerController * @@ -1108,7 +1132,7 @@ string FGTowerController::getName() { void FGTowerController::update(double dt) { - + eraseDeadTraffic(activeTraffic); } @@ -1572,7 +1596,7 @@ string FGStartupController::getName() { void FGStartupController::update(double dt) { - + eraseDeadTraffic(activeTraffic); } @@ -1706,11 +1730,9 @@ void FGApproachController::signOff(int id) void FGApproachController::update(double dt) { - + eraseDeadTraffic(activeTraffic); } - - bool FGApproachController::hasInstruction(int id) { TrafficVectorIterator i = activeTraffic.begin(); diff --git a/src/ATC/trafficcontrol.hxx b/src/ATC/trafficcontrol.hxx index ab3432573..f6fb7d70d 100644 --- a/src/ATC/trafficcontrol.hxx +++ b/src/ATC/trafficcontrol.hxx @@ -387,6 +387,7 @@ protected: std::string genTransponderCode(const std::string& fltRules); bool isUserAircraft(FGAIAircraft*); + void eraseDeadTraffic(TrafficVector& vec); public: typedef enum { MSG_ANNOUNCE_ENGINE_START,