1
0
Fork 0

Fixes for cloning FPs with procedures

This commit is contained in:
James Turner 2020-05-27 16:09:18 +01:00
parent 9ed2406878
commit 55ce199535
3 changed files with 103 additions and 14 deletions

View file

@ -132,15 +132,17 @@ FlightPlan* FlightPlan::clone(const string& newIdent) const
} else if (_destination) { } else if (_destination) {
c->setDestination(_destination); c->setDestination(_destination);
} }
c->setSTAR(_star); c->setSTAR(_star, _starTransition);
c->setSID(_sid); c->setSID(_sid, _sidTransition);
// mark data as unchanged since this is a clean plan // mark data as unchanged since this is a clean plan
c->_arrivalChanged = false; c->_arrivalChanged = false;
c->_departureChanged = false; c->_departureChanged = false;
// copy legs c->_didLoadFP = true; // set the loaded flag to give delegates a chance
// copy legs
c->_waypointsChanged = true; 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));

View file

@ -196,6 +196,7 @@ RunwayWaypt::RunwayWaypt(FGRunway* aPos, RouteBase* aOwner) :
Waypt(aOwner), Waypt(aOwner),
_runway(aPos) _runway(aPos)
{ {
assert(aPos != nullptr);
} }
RunwayWaypt::RunwayWaypt(RouteBase* aOwner) : RunwayWaypt::RunwayWaypt(RouteBase* aOwner) :

View file

@ -8,6 +8,7 @@
#include <simgear/misc/strutils.hxx> #include <simgear/misc/strutils.hxx>
#include <simgear/misc/sg_dir.hxx> #include <simgear/misc/sg_dir.hxx>
#include <simgear/io/iostreams/sgstream.hxx> #include <simgear/io/iostreams/sgstream.hxx>
#include <simgear/structure/exception.hxx>
#include <Navaids/FlightPlan.hxx> #include <Navaids/FlightPlan.hxx>
#include <Navaids/routePath.hxx> #include <Navaids/routePath.hxx>
@ -47,16 +48,83 @@ public:
{ {
} }
void waypointsChanged() override
{
sawWaypointsChange = true;
}
void departureChanged() override void departureChanged() override
{ {
sawDepartureChange = true; sawDepartureChange = true;
// mimic the default delegate, inserting the SID waypoints
// clear anything existing
_plan->clearWayptsWithFlag(WPT_DEPARTURE);
// insert waypt for the dpearture runway
auto dr = new RunwayWaypt(_plan->departureRunway(), _plan);
dr->setFlag(WPT_DEPARTURE);
dr->setFlag(WPT_GENERATED);
_plan->insertWayptAtIndex(dr, 0);
if (_plan->sid()) {
WayptVec sidRoute;
bool ok = _plan->sid()->route(_plan->departureRunway(), _plan->sidTransition(), sidRoute);
if (!ok)
throw sg_exception("failed to route via SID");
int insertIndex = 1;
for (auto w : sidRoute) {
w->setFlag(WPT_DEPARTURE);
w->setFlag(WPT_GENERATED);
_plan->insertWayptAtIndex(w, insertIndex++);
}
}
} }
void arrivalChanged() override void arrivalChanged() override
{ {
sawArrivalChange = true; sawArrivalChange = true;
// mimic the default delegate, inserting the STAR waypoints
// clear anything existing
_plan->clearWayptsWithFlag(WPT_ARRIVAL);
if (!_plan->destinationAirport()) {
return;
}
if (!_plan->destinationRunway()) {
auto ap = new NavaidWaypoint(_plan->destinationAirport(), _plan);
ap->setFlag(WPT_ARRIVAL);
ap->setFlag(WPT_GENERATED);
_plan->insertWayptAtIndex(ap, -1);
return;
}
// insert waypt for the destination runway
auto dr = new RunwayWaypt(_plan->destinationRunway(), _plan);
dr->setFlag(WPT_ARRIVAL);
dr->setFlag(WPT_GENERATED);
auto leg = _plan->insertWayptAtIndex(dr, -1);
if (_plan->star()) {
WayptVec starRoute;
bool ok = _plan->star()->route(_plan->destinationRunway(), _plan->starTransition(), starRoute);
if (!ok)
throw sg_exception("failed to route via STAR");
int insertIndex = leg->index();
for (auto w : starRoute) {
w->setFlag(WPT_ARRIVAL);
w->setFlag(WPT_GENERATED);
_plan->insertWayptAtIndex(w, insertIndex++);
}
}
} }
void loaded() override void loaded() override
{ {
didLoad = true; didLoad = true;
@ -66,6 +134,7 @@ public:
bool didLoad = false; bool didLoad = false;
bool sawDepartureChange = false; bool sawDepartureChange = false;
bool sawArrivalChange = false; bool sawArrivalChange = false;
bool sawWaypointsChange = false;
}; };
class TestFPDelegateFactory : public FlightPlan::DelegateFactory class TestFPDelegateFactory : public FlightPlan::DelegateFactory
@ -940,13 +1009,21 @@ void FlightplanTests::testCloningFGFP()
CPPUNIT_ASSERT(ourDelegate->sawDepartureChange); CPPUNIT_ASSERT(ourDelegate->sawDepartureChange);
auto fp2 = fp1->clone(); auto fp2 = fp1->clone();
auto secondDelegate = TestFPDelegateFactory::delegateForPlan(fp2);
CPPUNIT_ASSERT(secondDelegate->didLoad);
CPPUNIT_ASSERT(secondDelegate->sawWaypointsChange);
CPPUNIT_ASSERT(!secondDelegate->sawArrivalChange);
CPPUNIT_ASSERT(!secondDelegate->sawDepartureChange);
CPPUNIT_ASSERT(fp2->departureAirport()->ident() == "EDDM"); CPPUNIT_ASSERT(fp2->departureAirport()->ident() == "EDDM");
CPPUNIT_ASSERT(fp2->departureRunway()->ident() == "08R"); CPPUNIT_ASSERT(fp2->departureRunway()->ident() == "08R");
CPPUNIT_ASSERT(fp2->destinationAirport()->ident() == "EDDF"); CPPUNIT_ASSERT(fp2->destinationAirport()->ident() == "EDDF");
CPPUNIT_ASSERT(fp2->legAtIndex(0)->waypoint()->source()->ident() == "08R"); CPPUNIT_ASSERT_EQUAL(fp2->legAtIndex(0)->waypoint()->source()->ident(), string{"08R"});
CPPUNIT_ASSERT(fp2->legAtIndex(1)->waypoint()->source()->ident() == "GIVMI"); CPPUNIT_ASSERT_EQUAL(fp2->legAtIndex(1)->waypoint()->source()->ident(), string{"GIVMI"});
CPPUNIT_ASSERT(fp2->legAtIndex(6)->waypoint()->source()->ident() == "PSA"); CPPUNIT_ASSERT_EQUAL(fp2->legAtIndex(5)->waypoint()->source()->ident(), string{"PSA"});
CPPUNIT_ASSERT_EQUAL(fp2->legAtIndex(6)->waypoint()->source()->ident(), string{"EDDF"});
CPPUNIT_ASSERT_EQUAL(7, fp2->numLegs()); CPPUNIT_ASSERT_EQUAL(7, fp2->numLegs());
} }
@ -962,17 +1039,26 @@ void FlightplanTests::testCloningProcedures() {
auto egkk = FGAirport::findByIdent("EGKK"); auto egkk = FGAirport::findByIdent("EGKK");
auto sid = egkk->findSIDWithIdent("SAM3P"); auto sid = egkk->findSIDWithIdent("SAM3P");
FlightPlanRef fp1 = makeTestFP("EGKK", "08R", "EGJJ", "27", FlightPlanRef fp1 = makeTestFP("EGKK", "08R", "EHAM", "18R",
""); "");
auto ourDelegate = TestFPDelegateFactory::delegateForPlan(fp1); auto ourDelegate = TestFPDelegateFactory::delegateForPlan(fp1);
fp1->setSID(sid); fp1->setSID(sid);
auto eham = FGAirport::findByIdent("EHAM");
auto eel1A = eham->findSTARWithIdent("EEL1A");
fp1->setSTAR(eel1A, "BEDUM");
auto fp2 = fp1->clone(); auto fp2 = fp1->clone();
CPPUNIT_ASSERT(fp2->departureAirport()->ident() == "EGKK"); CPPUNIT_ASSERT(fp2->departureAirport()->ident() == "EGKK");
CPPUNIT_ASSERT(fp2->departureRunway()->ident() == "08R"); CPPUNIT_ASSERT(fp2->departureRunway()->ident() == "08R");
CPPUNIT_ASSERT(fp2->destinationAirport()->ident() == "EGJJ"); CPPUNIT_ASSERT(fp2->destinationAirport()->ident() == "EHAM");
CPPUNIT_ASSERT(fp2->destinationRunway()->ident() == "27"); CPPUNIT_ASSERT(fp2->destinationRunway()->ident() == "18R");
CPPUNIT_ASSERT(fp2->legAtIndex(0)->waypoint()->source()->ident() == "08R"); CPPUNIT_ASSERT(fp2->legAtIndex(0)->waypoint()->source()->ident() == "08R");
CPPUNIT_ASSERT_EQUAL(fp2->sid()->ident(), string{"SAM3P"}); CPPUNIT_ASSERT_EQUAL(fp2->sid()->ident(), string{"SAM3P"});
}
CPPUNIT_ASSERT_EQUAL(fp2->star()->ident(), string{"EEL1A"});
CPPUNIT_ASSERT_EQUAL(fp2->starTransition()->ident(), string{"BEDUM"});
}