1
0
Fork 0

Fix for loading of FGFP plans.

Where the plan does not contain departure / arrival WPs, fire the
corresponding delegate methods after load, to run the selection logic.

Also, add a ‘loaded’ delegate callback, to give delegates a chance to
perform validation and fix-up after all flight-plan loads.
This commit is contained in:
James Turner 2020-05-19 22:01:42 +01:00
parent 63fe5237c6
commit 8af20fbcab
5 changed files with 53 additions and 12 deletions

View file

@ -334,6 +334,7 @@ void FlightPlan::setCurrentIndex(int index)
lockDelegates();
_currentIndex = index;
_currentWaypointChanged = true;
_didLoadFP = true;
unlockDelegates();
}
@ -764,6 +765,16 @@ void FlightPlan::saveToProperties(SGPropertyNode* d) const
} // of waypoint iteration
}
static bool anyWaypointsWithFlag(FlightPlan* plan, WayptFlag flag)
{
bool r = false;
plan->forEachLeg([&r, flag](FlightPlan::Leg* l) {
if (l->waypoint()->flags() && flag) {
r = true;
}
});
}
bool FlightPlan::load(const SGPath& path)
{
if (!path.exists()) {
@ -787,8 +798,13 @@ bool FlightPlan::load(const SGPath& path)
// a load, since we assume the flight-plan had it specified already
// especially, the XML might have a SID/STAR embedded, which we don't
// want to lose
_arrivalChanged = false;
_departureChanged = false;
// however, we do want to run the normal delegate if no procedure was
// defined. We'll use the presence of waypoints tagged to decide
const bool hasArrival = anyWaypointsWithFlag(this, WPT_ARRIVAL);
const bool hasDeparture = anyWaypointsWithFlag(this, WPT_DEPARTURE);
_arrivalChanged = !hasArrival;
_departureChanged = !hasDeparture;
Status = true;
} else if (loadPlainTextFormat(path)) { // simple textual list of waypoints
_arrivalChanged = true;
@ -1696,6 +1712,13 @@ void FlightPlan::unlockDelegates()
return;
}
if (_didLoadFP) {
_didLoadFP = false;
for (auto d : _delegates) {
d->loaded();
}
}
if (_departureChanged) {
_departureChanged = false;
for (auto d : _delegates) {
@ -2115,4 +2138,9 @@ int FlightPlan::cruiseAltitudeFt() const
return _cruiseAltitudeFt;
}
void FlightPlan::forEachLeg(const LegVisitor& lv)
{
std::for_each(_legs.begin(), _legs.end(), lv);
}
} // of namespace flightgear

View file

@ -24,6 +24,8 @@
#ifndef FG_FLIGHTPLAN_HXX
#define FG_FLIGHTPLAN_HXX
#include <functional>
#include <Navaids/route.hxx>
#include <Airports/airport.hxx>
@ -186,6 +188,8 @@ public:
virtual void currentWaypointChanged() { }
virtual void endOfFlightPlan() { }
virtual void loaded() { }
protected:
Delegate();
@ -373,6 +377,9 @@ public:
void addDelegate(Delegate* d);
void removeDelegate(Delegate* d);
using LegVisitor = std::function<void(Leg*)>;
void forEachLeg(const LegVisitor& lv);
private:
friend class Leg;
@ -384,11 +391,12 @@ private:
void notifyCleared();
unsigned int _delegateLock = 0;
bool _arrivalChanged,
_departureChanged,
_waypointsChanged,
_currentWaypointChanged,
_cruiseDataChanged;
bool _arrivalChanged = false,
_departureChanged = false,
_waypointsChanged = false,
_currentWaypointChanged = false,
_cruiseDataChanged = false;
bool _didLoadFP = false;
void saveToProperties(SGPropertyNode* d) const;

View file

@ -2426,6 +2426,11 @@ public:
{
callDelegateMethod("sequence");
}
void loaded() override
{
callDelegateMethod("loaded");
}
private:
void callDelegateMethod(const char* method)

View file

@ -599,7 +599,7 @@ void RouteManagerTests::loadGPX()
}
// The same test as above, but for a file exported from the route manager or online
void RouteManagerTests::loadFgfp()
void RouteManagerTests::loadFGFP()
{
auto rm = globals->get_subsystem<FGRouteMgr>();

View file

@ -41,7 +41,7 @@ class RouteManagerTests : public CppUnit::TestFixture
CPPUNIT_TEST(testSequenceDiscontinuityAndResume);
CPPUNIT_TEST(testHiddenWaypoints);
CPPUNIT_TEST(loadGPX);
CPPUNIT_TEST(loadFgfp);
CPPUNIT_TEST(loadFGFP);
CPPUNIT_TEST_SUITE_END();
@ -65,7 +65,7 @@ public:
void testSequenceDiscontinuityAndResume();
void testHiddenWaypoints();
void loadGPX();
void loadFgfp();
void loadFGFP();
private:
GPS* m_gps = nullptr;
};