From 849c6ccc6eb19f758c6d4d8ea7daf2f61b56e677 Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 16 Mar 2014 16:20:03 +0000 Subject: [PATCH] GPS fixes - fix corrupted ident on Mac (libc++ issue) - don't clear scratch when activating DTO mode - use the real navaid/airport for the waypt where possible - expose active waypt name --- src/Instrumentation/gps.cxx | 68 +++++++++++++++++++++++++++++-------- src/Instrumentation/gps.hxx | 5 +-- 2 files changed, 57 insertions(+), 16 deletions(-) diff --git a/src/Instrumentation/gps.cxx b/src/Instrumentation/gps.cxx index 8e6e066bb..2e8f5bc47 100644 --- a/src/Instrumentation/gps.cxx +++ b/src/Instrumentation/gps.cxx @@ -222,14 +222,17 @@ GPS::bind() tieSGGeodReadOnly(wp0_node, _wp0_position, "longitude-deg", "latitude-deg", "altitude-ft"); tie(wp0_node, "ID", SGRawValueMethods (*this, &GPS::getWP0Ident, NULL)); - + tie(wp0_node, "name", SGRawValueMethods + (*this, &GPS::getWP0Name, NULL)); tie(_currentWayptNode, "valid", SGRawValueMethods (*this, &GPS::getWP1IValid, NULL)); tie(_currentWayptNode, "ID", SGRawValueMethods (*this, &GPS::getWP1Ident, NULL)); - + tie(_currentWayptNode, "name", SGRawValueMethods + (*this, &GPS::getWP1Name, NULL)); + tie(_currentWayptNode, "distance-nm", SGRawValueMethods (*this, &GPS::getWP1Distance, NULL)); tie(_currentWayptNode, "bearing-true-deg", SGRawValueMethods @@ -922,16 +925,25 @@ double GPS::getCDIDeflection() const const char* GPS::getWP0Ident() const { - if (!_dataValid || (_mode != "leg") || (!_prevWaypt)) { + if (!_dataValid || (_mode != "leg") || !_prevWaypt) { return ""; } - return _prevWaypt->ident().c_str(); +// work around std::string::c_str() storage lifetime with libc++ +// real fix is to allow tie-ing with std::string instead of char* + static char identBuf[8]; + strncpy(identBuf, _prevWaypt->ident().c_str(), 8); + + return identBuf; } const char* GPS::getWP0Name() const { - return ""; + if (!_dataValid || !_prevWaypt || !_prevWaypt->source()) { + return ""; + } + + return _prevWaypt->source()->name().c_str(); } bool GPS::getWP1IValid() const @@ -941,16 +953,25 @@ bool GPS::getWP1IValid() const const char* GPS::getWP1Ident() const { - if ((!_dataValid)||(!_currentWaypt)) { + if (!_dataValid || !_currentWaypt) { return ""; } - return _currentWaypt->ident().c_str(); +// work around std::string::c_str() storage lifetime with libc++ +// real fix is to allow tie-ing with std::string instead of char* + static char identBuf[8]; + strncpy(identBuf, _currentWaypt->ident().c_str(), 8); + + return identBuf; } const char* GPS::getWP1Name() const { - return ""; + if (!_dataValid || !_currentWaypt || !_currentWaypt->source()) { + return ""; + } + + return _currentWaypt->source()->name().c_str(); } double GPS::getWP1Distance() const @@ -1157,6 +1178,16 @@ bool GPS::isScratchPositionValid() const return true; } +FGPositionedRef GPS::positionedFromScratch() const +{ + if (!isScratchPositionValid()) { + return NULL; + } + + std::string ident(_scratchNode->getStringValue("ident")); + return FGPositioned::findClosestWithIdent(ident, _scratchPos); +} + void GPS::directTo() { if (!isScratchPositionValid()) { @@ -1165,22 +1196,31 @@ void GPS::directTo() _prevWaypt = NULL; _wp0_position = _indicated_pos; - _currentWaypt = new BasicWaypt(_scratchPos, _scratchNode->getStringValue("ident"), NULL); - _mode = "dto"; - clearScratch(); + + FGPositionedRef pos = positionedFromScratch(); + if (pos) { + _currentWaypt = new NavaidWaypoint(pos, NULL); + } else { + _currentWaypt = new BasicWaypt(_scratchPos, _scratchNode->getStringValue("ident"), NULL); + } + + _mode = "dto"; wp1Changed(); } void GPS::selectOBSMode(flightgear::Waypt* waypt) { - if (!waypt) { - // initialise from scratch - if (isScratchPositionValid()) { + if (!waypt && isScratchPositionValid()) { + FGPositionedRef pos = positionedFromScratch(); + if (pos) { + waypt = new NavaidWaypoint(pos, NULL); + } else { waypt = new BasicWaypt(_scratchPos, _scratchNode->getStringValue("ident"), NULL); } } _mode = "obs"; + _prevWaypt = NULL; _wp0_position = _indicated_pos; _currentWaypt = waypt; wp1Changed(); diff --git a/src/Instrumentation/gps.hxx b/src/Instrumentation/gps.hxx index a142330ce..100d236b6 100644 --- a/src/Instrumentation/gps.hxx +++ b/src/Instrumentation/gps.hxx @@ -206,7 +206,8 @@ private: /** Predicate, determine if the lon/lat position in the scratch is * valid or not. */ bool isScratchPositionValid() const; - + FGPositionedRef positionedFromScratch() const; + #if FG_210_COMPAT void setScratchFromPositioned(FGPositioned* aPos, int aIndex); void setScratchFromCachedSearchResult(); @@ -350,7 +351,7 @@ private: * the instrument manager creates a default instance of us, * if no explicit GPS is specific in the aircraft's instruments.xml file. * This allows default route-following to work with the generic autopilot. - * This flat is set in that case, to inform us we're a 'fake' installation, + * This flag is set in that case, to inform us we're a 'fake' installation, * and not to worry about electrical power or similar. */ bool _defaultGPSMode; -- 2.39.5