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:
parent
63fe5237c6
commit
8af20fbcab
5 changed files with 53 additions and 12 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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>();
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue