More route-manager functionality moved to Nasal.
The routing behaviour now happens entirely in Nasal, using a delegate, and can be over-ridden or disable by aircraft authors. Default behaviour should be unchanged.
This commit is contained in:
parent
73a3434421
commit
1ef77b2bc2
6 changed files with 183 additions and 169 deletions
|
@ -585,77 +585,6 @@ void FGRouteMgr::removeLegAtIndex(int aIndex)
|
||||||
_plan->deleteIndex(aIndex);
|
_plan->deleteIndex(aIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGRouteMgr::departureChanged()
|
|
||||||
{
|
|
||||||
_plan->clearWayptsWithFlag(WPT_DEPARTURE);
|
|
||||||
WayptRef enroute;
|
|
||||||
WayptVec wps;
|
|
||||||
buildDeparture(enroute, wps);
|
|
||||||
_plan->insertWayptsAtIndex(wps, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGRouteMgr::buildDeparture(WayptRef enroute, WayptVec& wps)
|
|
||||||
{
|
|
||||||
if (!_plan->departureAirport()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_plan->departureRunway()) {
|
|
||||||
// valid airport, but no runway selected, so just the airport _plan itself
|
|
||||||
WayptRef w = new NavaidWaypoint(_plan->departureAirport(), _plan);
|
|
||||||
w->setFlag(WPT_DEPARTURE);
|
|
||||||
wps.push_back(w);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
WayptRef rwyWaypt = new RunwayWaypt(_plan->departureRunway(), _plan);
|
|
||||||
rwyWaypt->setFlag(WPT_DEPARTURE);
|
|
||||||
wps.push_back(rwyWaypt);
|
|
||||||
|
|
||||||
if (!_plan->sid()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_plan->sid()->route(_plan->departureRunway(), _plan->sidTransition(), wps);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGRouteMgr::arrivalChanged()
|
|
||||||
{
|
|
||||||
_plan->clearWayptsWithFlag(WPT_ARRIVAL);
|
|
||||||
_plan->clearWayptsWithFlag(WPT_APPROACH);
|
|
||||||
WayptVec wps;
|
|
||||||
WayptRef enroute;
|
|
||||||
buildArrival(enroute, wps);
|
|
||||||
_plan->insertWayptsAtIndex(wps, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGRouteMgr::buildArrival(WayptRef enroute, WayptVec& wps)
|
|
||||||
{
|
|
||||||
FGAirportRef apt = _plan->destinationAirport();
|
|
||||||
if (!apt.valid()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_plan->destinationRunway()) {
|
|
||||||
WayptRef w = new NavaidWaypoint(apt.ptr(), _plan);
|
|
||||||
w->setFlag(WPT_ARRIVAL);
|
|
||||||
wps.push_back(w);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_plan->star()) {
|
|
||||||
_plan->star()->route(_plan->destinationRunway(), _plan->starTransition(), wps);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_plan->approach()) {
|
|
||||||
_plan->approach()->route(wps.back(), wps);
|
|
||||||
} else {
|
|
||||||
WayptRef w = new RunwayWaypt(_plan->destinationRunway(), _plan);
|
|
||||||
w->setFlag(WPT_APPROACH);
|
|
||||||
wps.push_back(w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGRouteMgr::waypointsChanged()
|
void FGRouteMgr::waypointsChanged()
|
||||||
{
|
{
|
||||||
update_mirror();
|
update_mirror();
|
||||||
|
|
|
@ -172,12 +172,6 @@ private:
|
||||||
InputListener *listener;
|
InputListener *listener;
|
||||||
SGPropertyNode_ptr mirror;
|
SGPropertyNode_ptr mirror;
|
||||||
|
|
||||||
virtual void departureChanged();
|
|
||||||
void buildDeparture(flightgear::WayptRef enroute, flightgear::WayptVec& wps);
|
|
||||||
|
|
||||||
virtual void arrivalChanged();
|
|
||||||
void buildArrival(flightgear::WayptRef enroute, flightgear::WayptVec& wps);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to keep various pieces of state in sync when the route is
|
* Helper to keep various pieces of state in sync when the route is
|
||||||
* modified (waypoints added, inserted, removed). Notably, this fires the
|
* modified (waypoints added, inserted, removed). Notably, this fires the
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
// std
|
// std
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
// Boost
|
// Boost
|
||||||
#include <boost/algorithm/string/case_conv.hpp>
|
#include <boost/algorithm/string/case_conv.hpp>
|
||||||
|
@ -59,6 +60,7 @@ typedef std::vector<FlightPlan::DelegateFactory*> FPDelegateFactoryVec;
|
||||||
static FPDelegateFactoryVec static_delegateFactories;
|
static FPDelegateFactoryVec static_delegateFactories;
|
||||||
|
|
||||||
FlightPlan::FlightPlan() :
|
FlightPlan::FlightPlan() :
|
||||||
|
_delegateLock(0),
|
||||||
_currentIndex(-1),
|
_currentIndex(-1),
|
||||||
_departureRunway(NULL),
|
_departureRunway(NULL),
|
||||||
_destinationRunway(NULL),
|
_destinationRunway(NULL),
|
||||||
|
@ -67,6 +69,8 @@ FlightPlan::FlightPlan() :
|
||||||
_approach(NULL),
|
_approach(NULL),
|
||||||
_delegate(NULL)
|
_delegate(NULL)
|
||||||
{
|
{
|
||||||
|
_departureChanged = _arrivalChanged = _waypointsChanged = _currentWaypointChanged = false;
|
||||||
|
|
||||||
BOOST_FOREACH(DelegateFactory* factory, static_delegateFactories) {
|
BOOST_FOREACH(DelegateFactory* factory, static_delegateFactories) {
|
||||||
Delegate* d = factory->createFlightPlanDelegate(this);
|
Delegate* d = factory->createFlightPlanDelegate(this);
|
||||||
if (d) { // factory might not always create a delegate
|
if (d) { // factory might not always create a delegate
|
||||||
|
@ -93,6 +97,7 @@ FlightPlan* FlightPlan::clone(const string& newIdent) const
|
||||||
{
|
{
|
||||||
FlightPlan* c = new FlightPlan();
|
FlightPlan* c = new FlightPlan();
|
||||||
c->_ident = newIdent.empty() ? _ident : newIdent;
|
c->_ident = newIdent.empty() ? _ident : newIdent;
|
||||||
|
c->lockDelegate();
|
||||||
|
|
||||||
// copy destination / departure data.
|
// copy destination / departure data.
|
||||||
c->setDeparture(_departure);
|
c->setDeparture(_departure);
|
||||||
|
@ -110,10 +115,11 @@ FlightPlan* FlightPlan::clone(const string& newIdent) const
|
||||||
c->setSID(_sid);
|
c->setSID(_sid);
|
||||||
|
|
||||||
// copy legs
|
// copy legs
|
||||||
|
c->_waypointsChanged = true;
|
||||||
for (int l=0; l < numLegs(); ++l) {
|
for (int l=0; l < numLegs(); ++l) {
|
||||||
c->_legs.push_back(_legs[l]->cloneFor(c));
|
c->_legs.push_back(_legs[l]->cloneFor(c));
|
||||||
}
|
}
|
||||||
|
c->unlockDelegate();
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,12 +175,10 @@ void FlightPlan::insertWayptsAtIndex(const WayptVec& wps, int aIndex)
|
||||||
newLegs.push_back(new Leg(this, wp));
|
newLegs.push_back(new Leg(this, wp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lockDelegate();
|
||||||
|
_waypointsChanged = true;
|
||||||
_legs.insert(it, newLegs.begin(), newLegs.end());
|
_legs.insert(it, newLegs.begin(), newLegs.end());
|
||||||
rebuildLegData();
|
unlockDelegate();
|
||||||
|
|
||||||
if (_delegate) {
|
|
||||||
_delegate->runWaypointsChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlightPlan::deleteIndex(int aIndex)
|
void FlightPlan::deleteIndex(int aIndex)
|
||||||
|
@ -188,77 +192,95 @@ void FlightPlan::deleteIndex(int aIndex)
|
||||||
SG_LOG(SG_AUTOPILOT, SG_WARN, "removeAtIndex with invalid index:" << aIndex);
|
SG_LOG(SG_AUTOPILOT, SG_WARN, "removeAtIndex with invalid index:" << aIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lockDelegate();
|
||||||
|
_waypointsChanged = true;
|
||||||
|
|
||||||
LegVec::iterator it = _legs.begin();
|
LegVec::iterator it = _legs.begin();
|
||||||
it += index;
|
it += index;
|
||||||
Leg* l = *it;
|
Leg* l = *it;
|
||||||
_legs.erase(it);
|
_legs.erase(it);
|
||||||
delete l;
|
delete l;
|
||||||
|
|
||||||
bool curChanged = false;
|
|
||||||
if (_currentIndex == index) {
|
if (_currentIndex == index) {
|
||||||
// current waypoint was removed
|
// current waypoint was removed
|
||||||
curChanged = true;
|
_currentWaypointChanged = true;
|
||||||
} else if (_currentIndex > index) {
|
} else if (_currentIndex > index) {
|
||||||
--_currentIndex; // shift current index down if necessary
|
--_currentIndex; // shift current index down if necessary
|
||||||
}
|
}
|
||||||
|
|
||||||
rebuildLegData();
|
unlockDelegate();
|
||||||
if (_delegate) {
|
|
||||||
_delegate->runWaypointsChanged();
|
|
||||||
if (curChanged) {
|
|
||||||
_delegate->runCurrentWaypointChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlightPlan::clear()
|
void FlightPlan::clear()
|
||||||
{
|
{
|
||||||
|
lockDelegate();
|
||||||
|
_waypointsChanged = true;
|
||||||
|
_currentWaypointChanged = true;
|
||||||
|
_arrivalChanged = true;
|
||||||
|
_departureChanged = true;
|
||||||
|
|
||||||
_currentIndex = -1;
|
_currentIndex = -1;
|
||||||
BOOST_FOREACH(Leg* l, _legs) {
|
BOOST_FOREACH(Leg* l, _legs) {
|
||||||
delete l;
|
delete l;
|
||||||
}
|
}
|
||||||
_legs.clear();
|
_legs.clear();
|
||||||
rebuildLegData();
|
|
||||||
if (_delegate) {
|
unlockDelegate();
|
||||||
_delegate->runDepartureChanged();
|
|
||||||
_delegate->runArrivalChanged();
|
|
||||||
_delegate->runWaypointsChanged();
|
|
||||||
_delegate->runCurrentWaypointChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RemoveWithFlag
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RemoveWithFlag(WayptFlag f) : flag(f), delCount(0) { }
|
||||||
|
|
||||||
|
int numDeleted() const { return delCount; }
|
||||||
|
|
||||||
|
bool operator()(FlightPlan::Leg* leg) const
|
||||||
|
{
|
||||||
|
if (leg->waypoint()->flag(flag)) {
|
||||||
|
std::cout << "deleting" << leg << std::endl;
|
||||||
|
delete leg;
|
||||||
|
++delCount;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
WayptFlag flag;
|
||||||
|
mutable int delCount;
|
||||||
|
};
|
||||||
|
|
||||||
int FlightPlan::clearWayptsWithFlag(WayptFlag flag)
|
int FlightPlan::clearWayptsWithFlag(WayptFlag flag)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (unsigned int i=0; i<_legs.size(); ++i) {
|
// first pass, fix up currentIndex
|
||||||
|
for (int i=0; i<_currentIndex; ++i) {
|
||||||
Leg* l = _legs[i];
|
Leg* l = _legs[i];
|
||||||
if (!l->waypoint()->flag(flag)) {
|
if (l->waypoint()->flag(flag)) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// okay, we're going to clear this leg
|
|
||||||
++count;
|
++count;
|
||||||
if (_currentIndex > (int) i) {
|
}
|
||||||
--_currentIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete l;
|
_currentIndex -= count;
|
||||||
LegVec::iterator it = _legs.begin();
|
|
||||||
it += i;
|
|
||||||
_legs.erase(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count == 0) {
|
// now delete and remove
|
||||||
|
RemoveWithFlag rf(flag);
|
||||||
|
LegVec::iterator it = std::remove_if(_legs.begin(), _legs.end(), rf);
|
||||||
|
if (it == _legs.end()) {
|
||||||
return 0; // nothing was cleared, don't fire the delegate
|
return 0; // nothing was cleared, don't fire the delegate
|
||||||
}
|
}
|
||||||
|
|
||||||
rebuildLegData();
|
lockDelegate();
|
||||||
if (_delegate) {
|
_waypointsChanged = true;
|
||||||
_delegate->runWaypointsChanged();
|
if (count > 0) {
|
||||||
_delegate->runCurrentWaypointChanged();
|
_currentWaypointChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
_legs.erase(it, _legs.end());
|
||||||
|
unlockDelegate();
|
||||||
|
return rf.numDeleted();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlightPlan::setCurrentIndex(int index)
|
void FlightPlan::setCurrentIndex(int index)
|
||||||
|
@ -271,10 +293,10 @@ void FlightPlan::setCurrentIndex(int index)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lockDelegate();
|
||||||
_currentIndex = index;
|
_currentIndex = index;
|
||||||
if (_delegate) {
|
_currentWaypointChanged = true;
|
||||||
_delegate->runCurrentWaypointChanged();
|
unlockDelegate();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int FlightPlan::findWayptIndex(const SGGeod& aPos) const
|
int FlightPlan::findWayptIndex(const SGGeod& aPos) const
|
||||||
|
@ -339,13 +361,12 @@ void FlightPlan::setDeparture(FGAirport* apt)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lockDelegate();
|
||||||
|
_departureChanged = true;
|
||||||
_departure = apt;
|
_departure = apt;
|
||||||
_departureRunway = NULL;
|
_departureRunway = NULL;
|
||||||
setSID((SID*)NULL);
|
setSID((SID*)NULL);
|
||||||
|
unlockDelegate();
|
||||||
if (_delegate) {
|
|
||||||
_delegate->runDepartureChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlightPlan::setDeparture(FGRunway* rwy)
|
void FlightPlan::setDeparture(FGRunway* rwy)
|
||||||
|
@ -354,15 +375,15 @@ void FlightPlan::setDeparture(FGRunway* rwy)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lockDelegate();
|
||||||
|
_departureChanged = true;
|
||||||
|
|
||||||
_departureRunway = rwy;
|
_departureRunway = rwy;
|
||||||
if (rwy->airport() != _departure) {
|
if (rwy->airport() != _departure) {
|
||||||
_departure = rwy->airport();
|
_departure = rwy->airport();
|
||||||
setSID((SID*)NULL);
|
setSID((SID*)NULL);
|
||||||
}
|
}
|
||||||
|
unlockDelegate();
|
||||||
if (_delegate) {
|
|
||||||
_delegate->runDepartureChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlightPlan::setSID(SID* sid, const std::string& transition)
|
void FlightPlan::setSID(SID* sid, const std::string& transition)
|
||||||
|
@ -371,12 +392,11 @@ void FlightPlan::setSID(SID* sid, const std::string& transition)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lockDelegate();
|
||||||
|
_departureChanged = true;
|
||||||
_sid = sid;
|
_sid = sid;
|
||||||
_sidTransition = transition;
|
_sidTransition = transition;
|
||||||
|
unlockDelegate();
|
||||||
if (_delegate) {
|
|
||||||
_delegate->runDepartureChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlightPlan::setSID(Transition* trans)
|
void FlightPlan::setSID(Transition* trans)
|
||||||
|
@ -407,13 +427,13 @@ void FlightPlan::setDestination(FGAirport* apt)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lockDelegate();
|
||||||
|
_arrivalChanged = true;
|
||||||
_destination = apt;
|
_destination = apt;
|
||||||
_destinationRunway = NULL;
|
_destinationRunway = NULL;
|
||||||
setSTAR((STAR*)NULL);
|
setSTAR((STAR*)NULL);
|
||||||
|
setApproach(NULL);
|
||||||
if (_delegate) {
|
unlockDelegate();
|
||||||
_delegate->runArrivalChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlightPlan::setDestination(FGRunway* rwy)
|
void FlightPlan::setDestination(FGRunway* rwy)
|
||||||
|
@ -422,15 +442,15 @@ void FlightPlan::setDestination(FGRunway* rwy)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lockDelegate();
|
||||||
|
_arrivalChanged = true;
|
||||||
_destinationRunway = rwy;
|
_destinationRunway = rwy;
|
||||||
if (_destination != rwy->airport()) {
|
if (_destination != rwy->airport()) {
|
||||||
_destination = rwy->airport();
|
_destination = rwy->airport();
|
||||||
setSTAR((STAR*)NULL);
|
setSTAR((STAR*)NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_delegate) {
|
unlockDelegate();
|
||||||
_delegate->runArrivalChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlightPlan::setSTAR(STAR* star, const std::string& transition)
|
void FlightPlan::setSTAR(STAR* star, const std::string& transition)
|
||||||
|
@ -439,12 +459,11 @@ void FlightPlan::setSTAR(STAR* star, const std::string& transition)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lockDelegate();
|
||||||
|
_arrivalChanged = true;
|
||||||
_star = star;
|
_star = star;
|
||||||
_starTransition = transition;
|
_starTransition = transition;
|
||||||
|
unlockDelegate();
|
||||||
if (_delegate) {
|
|
||||||
_delegate->runArrivalChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlightPlan::setSTAR(Transition* trans)
|
void FlightPlan::setSTAR(Transition* trans)
|
||||||
|
@ -475,6 +494,8 @@ void FlightPlan::setApproach(flightgear::Approach *app)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lockDelegate();
|
||||||
|
_arrivalChanged = true;
|
||||||
_approach = app;
|
_approach = app;
|
||||||
if (app) {
|
if (app) {
|
||||||
// keep runway + airport in sync
|
// keep runway + airport in sync
|
||||||
|
@ -486,10 +507,7 @@ void FlightPlan::setApproach(flightgear::Approach *app)
|
||||||
_destination = _destinationRunway->airport();
|
_destination = _destinationRunway->airport();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
unlockDelegate();
|
||||||
if (_delegate) {
|
|
||||||
_delegate->runArrivalChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FlightPlan::save(const SGPath& path)
|
bool FlightPlan::save(const SGPath& path)
|
||||||
|
@ -554,12 +572,14 @@ bool FlightPlan::load(const SGPath& path)
|
||||||
SG_LOG(SG_IO, SG_INFO, "going to read flight-plan from:" << path.str());
|
SG_LOG(SG_IO, SG_INFO, "going to read flight-plan from:" << path.str());
|
||||||
|
|
||||||
bool Status = false;
|
bool Status = false;
|
||||||
|
lockDelegate();
|
||||||
try {
|
try {
|
||||||
readProperties(path.str(), routeData);
|
readProperties(path.str(), routeData);
|
||||||
} catch (sg_exception& ) {
|
} catch (sg_exception& ) {
|
||||||
// if XML parsing fails, the file might be simple textual list of waypoints
|
// if XML parsing fails, the file might be simple textual list of waypoints
|
||||||
Status = loadPlainTextRoute(path);
|
Status = loadPlainTextRoute(path);
|
||||||
routeData = 0;
|
routeData = 0;
|
||||||
|
_waypointsChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (routeData.valid())
|
if (routeData.valid())
|
||||||
|
@ -581,11 +601,7 @@ bool FlightPlan::load(const SGPath& path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rebuildLegData();
|
unlockDelegate();
|
||||||
if (_delegate) {
|
|
||||||
_delegate->runWaypointsChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -657,6 +673,7 @@ void FlightPlan::loadVersion2XMLRoute(SGPropertyNode_ptr routeData)
|
||||||
Leg* l = new Leg(this, Waypt::createFromProperties(NULL, wpNode));
|
Leg* l = new Leg(this, Waypt::createFromProperties(NULL, wpNode));
|
||||||
_legs.push_back(l);
|
_legs.push_back(l);
|
||||||
} // of route iteration
|
} // of route iteration
|
||||||
|
_waypointsChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlightPlan::loadVersion1XMLRoute(SGPropertyNode_ptr routeData)
|
void FlightPlan::loadVersion1XMLRoute(SGPropertyNode_ptr routeData)
|
||||||
|
@ -671,7 +688,7 @@ void FlightPlan::loadVersion1XMLRoute(SGPropertyNode_ptr routeData)
|
||||||
Leg* l = new Leg(this, parseVersion1XMLWaypt(wpNode));
|
Leg* l = new Leg(this, parseVersion1XMLWaypt(wpNode));
|
||||||
_legs.push_back(l);
|
_legs.push_back(l);
|
||||||
} // of route iteration
|
} // of route iteration
|
||||||
|
_waypointsChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
WayptRef FlightPlan::parseVersion1XMLWaypt(SGPropertyNode* aWP)
|
WayptRef FlightPlan::parseVersion1XMLWaypt(SGPropertyNode* aWP)
|
||||||
|
@ -1003,6 +1020,56 @@ void FlightPlan::rebuildLegData()
|
||||||
} // of legs iteration
|
} // of legs iteration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FlightPlan::lockDelegate()
|
||||||
|
{
|
||||||
|
if (_delegateLock == 0) {
|
||||||
|
assert(!_departureChanged && !_arrivalChanged &&
|
||||||
|
!_waypointsChanged && !_currentWaypointChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
++_delegateLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlightPlan::unlockDelegate()
|
||||||
|
{
|
||||||
|
assert(_delegateLock > 0);
|
||||||
|
if (_delegateLock > 1) {
|
||||||
|
--_delegateLock;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_departureChanged) {
|
||||||
|
_departureChanged = false;
|
||||||
|
if (_delegate) {
|
||||||
|
_delegate->runDepartureChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_arrivalChanged) {
|
||||||
|
_arrivalChanged = false;
|
||||||
|
if (_delegate) {
|
||||||
|
_delegate->runArrivalChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_waypointsChanged) {
|
||||||
|
_waypointsChanged = false;
|
||||||
|
rebuildLegData();
|
||||||
|
if (_delegate) {
|
||||||
|
_delegate->runWaypointsChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_currentWaypointChanged) {
|
||||||
|
_currentWaypointChanged = false;
|
||||||
|
if (_delegate) {
|
||||||
|
_delegate->runCurrentWaypointChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--_delegateLock;
|
||||||
|
}
|
||||||
|
|
||||||
void FlightPlan::registerDelegateFactory(DelegateFactory* df)
|
void FlightPlan::registerDelegateFactory(DelegateFactory* df)
|
||||||
{
|
{
|
||||||
FPDelegateFactoryVec::iterator it = std::find(static_delegateFactories.begin(),
|
FPDelegateFactoryVec::iterator it = std::find(static_delegateFactories.begin(),
|
||||||
|
|
|
@ -224,6 +224,14 @@ public:
|
||||||
void addDelegate(Delegate* d);
|
void addDelegate(Delegate* d);
|
||||||
void removeDelegate(Delegate* d);
|
void removeDelegate(Delegate* d);
|
||||||
private:
|
private:
|
||||||
|
void lockDelegate();
|
||||||
|
void unlockDelegate();
|
||||||
|
|
||||||
|
int _delegateLock;
|
||||||
|
bool _arrivalChanged,
|
||||||
|
_departureChanged,
|
||||||
|
_waypointsChanged,
|
||||||
|
_currentWaypointChanged;
|
||||||
|
|
||||||
bool loadPlainTextRoute(const SGPath& path);
|
bool loadPlainTextRoute(const SGPath& path);
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,9 @@ bool Approach::route(WayptRef aIAF, WayptVec& aWps)
|
||||||
bool Approach::routeFromVectors(WayptVec& aWps)
|
bool Approach::routeFromVectors(WayptVec& aWps)
|
||||||
{
|
{
|
||||||
aWps.insert(aWps.end(), _primary.begin(), _primary.end());
|
aWps.insert(aWps.end(), _primary.begin(), _primary.end());
|
||||||
aWps.push_back(new RunwayWaypt(_runway, NULL));
|
RunwayWaypt* rwy = new RunwayWaypt(_runway, NULL);
|
||||||
|
rwy->setFlag(WPT_APPROACH);
|
||||||
|
aWps.push_back(rwy);
|
||||||
aWps.insert(aWps.end(), _missed.begin(), _missed.end());
|
aWps.insert(aWps.end(), _missed.begin(), _missed.end());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,10 +75,12 @@ static const char* fixGhostGetMember(naContext c, void* g, naRef field, naRef* o
|
||||||
naGhostType FixGhostType = { positionedGhostDestroy, "fix", fixGhostGetMember, 0 };
|
naGhostType FixGhostType = { positionedGhostDestroy, "fix", fixGhostGetMember, 0 };
|
||||||
|
|
||||||
static const char* wayptGhostGetMember(naContext c, void* g, naRef field, naRef* out);
|
static const char* wayptGhostGetMember(naContext c, void* g, naRef field, naRef* out);
|
||||||
|
static void waypointGhostSetMember(naContext c, void* g, naRef field, naRef value);
|
||||||
|
|
||||||
naGhostType WayptGhostType = { wayptGhostDestroy,
|
naGhostType WayptGhostType = { wayptGhostDestroy,
|
||||||
"waypoint",
|
"waypoint",
|
||||||
wayptGhostGetMember,
|
wayptGhostGetMember,
|
||||||
0};
|
waypointGhostSetMember};
|
||||||
|
|
||||||
static const char* legGhostGetMember(naContext c, void* g, naRef field, naRef* out);
|
static const char* legGhostGetMember(naContext c, void* g, naRef field, naRef* out);
|
||||||
static void legGhostSetMember(naContext c, void* g, naRef field, naRef value);
|
static void legGhostSetMember(naContext c, void* g, naRef field, naRef value);
|
||||||
|
@ -382,6 +384,20 @@ static const char* waypointCommonGetMember(naContext c, Waypt* wpt, const char*
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void waypointCommonSetMember(naContext c, Waypt* wpt, const char* fieldName, naRef value)
|
||||||
|
{
|
||||||
|
if (!strcmp(fieldName, "wp_role")) {
|
||||||
|
if (!naIsString(value)) naRuntimeError(c, "wp_role must be a string");
|
||||||
|
if (wpt->owner() != NULL) naRuntimeError(c, "cannot override wp_role on waypoint with parent");
|
||||||
|
WayptFlag f = wayptFlagFromString(naStr_data(value));
|
||||||
|
if (f == 0) {
|
||||||
|
naRuntimeError(c, "unrecognized wp_role value %s", naStr_data(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
wpt->setFlag(f, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const char* wayptGhostGetMember(naContext c, void* g, naRef field, naRef* out)
|
static const char* wayptGhostGetMember(naContext c, void* g, naRef field, naRef* out)
|
||||||
{
|
{
|
||||||
const char* fieldName = naStr_data(field);
|
const char* fieldName = naStr_data(field);
|
||||||
|
@ -450,21 +466,19 @@ static const char* legGhostGetMember(naContext c, void* g, naRef field, naRef* o
|
||||||
return ""; // success
|
return ""; // success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void waypointGhostSetMember(naContext c, void* g, naRef field, naRef value)
|
||||||
|
{
|
||||||
|
const char* fieldName = naStr_data(field);
|
||||||
|
Waypt* wpt = (Waypt*) g;
|
||||||
|
waypointCommonSetMember(c, wpt, fieldName, value);
|
||||||
|
}
|
||||||
|
|
||||||
static void legGhostSetMember(naContext c, void* g, naRef field, naRef value)
|
static void legGhostSetMember(naContext c, void* g, naRef field, naRef value)
|
||||||
{
|
{
|
||||||
const char* fieldName = naStr_data(field);
|
const char* fieldName = naStr_data(field);
|
||||||
FlightPlan::Leg* leg = (FlightPlan::Leg*) g;
|
FlightPlan::Leg* leg = (FlightPlan::Leg*) g;
|
||||||
|
|
||||||
if (!strcmp(fieldName, "wp_role")) {
|
waypointCommonSetMember(c, leg->waypoint(), fieldName, value);
|
||||||
if (!naIsString(value)) naRuntimeError(c, "wp_role must be a string");
|
|
||||||
if (leg->waypoint()->owner() != NULL) naRuntimeError(c, "cannot override wp_role on waypoint with parent");
|
|
||||||
WayptFlag f = wayptFlagFromString(naStr_data(value));
|
|
||||||
if (f == 0) {
|
|
||||||
naRuntimeError(c, "unrecognized wp_role value %s", naStr_data(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
leg->waypoint()->setFlag(f, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* flightplanGhostGetMember(naContext c, void* g, naRef field, naRef* out)
|
static const char* flightplanGhostGetMember(naContext c, void* g, naRef field, naRef* out)
|
||||||
|
|
Loading…
Reference in a new issue