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(); lockDelegates();
_currentIndex = index; _currentIndex = index;
_currentWaypointChanged = true; _currentWaypointChanged = true;
_didLoadFP = true;
unlockDelegates(); unlockDelegates();
} }
@ -764,6 +765,16 @@ void FlightPlan::saveToProperties(SGPropertyNode* d) const
} // of waypoint iteration } // 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) bool FlightPlan::load(const SGPath& path)
{ {
if (!path.exists()) { 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 // 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 // especially, the XML might have a SID/STAR embedded, which we don't
// want to lose // 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; Status = true;
} else if (loadPlainTextFormat(path)) { // simple textual list of waypoints } else if (loadPlainTextFormat(path)) { // simple textual list of waypoints
_arrivalChanged = true; _arrivalChanged = true;
@ -1696,6 +1712,13 @@ void FlightPlan::unlockDelegates()
return; return;
} }
if (_didLoadFP) {
_didLoadFP = false;
for (auto d : _delegates) {
d->loaded();
}
}
if (_departureChanged) { if (_departureChanged) {
_departureChanged = false; _departureChanged = false;
for (auto d : _delegates) { for (auto d : _delegates) {
@ -2115,4 +2138,9 @@ int FlightPlan::cruiseAltitudeFt() const
return _cruiseAltitudeFt; return _cruiseAltitudeFt;
} }
void FlightPlan::forEachLeg(const LegVisitor& lv)
{
std::for_each(_legs.begin(), _legs.end(), lv);
}
} // of namespace flightgear } // of namespace flightgear

View file

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

View file

@ -2426,6 +2426,11 @@ public:
{ {
callDelegateMethod("sequence"); callDelegateMethod("sequence");
} }
void loaded() override
{
callDelegateMethod("loaded");
}
private: private:
void callDelegateMethod(const char* method) 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 // 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>(); auto rm = globals->get_subsystem<FGRouteMgr>();

View file

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