mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 08:50:05 +00:00 
			
		
		
		
	Create an NMEA position source if configured to do so
This commit is contained in:
		
							parent
							
								
									8270153957
								
							
						
					
					
						commit
						4545d87670
					
				
					 1 changed files with 124 additions and 25 deletions
				
			
		|  | @ -1,7 +1,10 @@ | ||||||
| #include <scwx/qt/manager/position_manager.hpp> | #include <scwx/qt/manager/position_manager.hpp> | ||||||
|  | #include <scwx/qt/settings/general_settings.hpp> | ||||||
|  | #include <scwx/qt/types/location_types.hpp> | ||||||
| #include <scwx/common/geographic.hpp> | #include <scwx/common/geographic.hpp> | ||||||
| #include <scwx/util/logger.hpp> | #include <scwx/util/logger.hpp> | ||||||
| 
 | 
 | ||||||
|  | #include <mutex> | ||||||
| #include <set> | #include <set> | ||||||
| 
 | 
 | ||||||
| #include <boost/uuid/random_generator.hpp> | #include <boost/uuid/random_generator.hpp> | ||||||
|  | @ -23,16 +26,111 @@ public: | ||||||
|    explicit Impl(PositionManager* self) : |    explicit Impl(PositionManager* self) : | ||||||
|        self_ {self}, trackingUuid_ {boost::uuids::random_generator()()} |        self_ {self}, trackingUuid_ {boost::uuids::random_generator()()} | ||||||
|    { |    { | ||||||
|       // TODO: macOS requires permission
 |       auto& generalSettings = settings::GeneralSettings::Instance(); | ||||||
|       geoPositionInfoSource_ = |  | ||||||
|          QGeoPositionInfoSource::createDefaultSource(self); |  | ||||||
| 
 | 
 | ||||||
|       if (geoPositionInfoSource_ != nullptr) |       logger_->debug( | ||||||
|  |          "Available sources: {}", | ||||||
|  |          QGeoPositionInfoSource::availableSources().join(", ").toStdString()); | ||||||
|  | 
 | ||||||
|  |       CreatePositionSource(); | ||||||
|  | 
 | ||||||
|  |       positioningPluginCallbackUuid_ = | ||||||
|  |          generalSettings.positioning_plugin().RegisterValueChangedCallback( | ||||||
|  |             [this](const std::string&) { CreatePositionSource(); }); | ||||||
|  |       nmeaBaudRateCallbackUuid_ = | ||||||
|  |          generalSettings.nmea_baud_rate().RegisterValueChangedCallback( | ||||||
|  |             [this](const std::int64_t&) { CreatePositionSource(); }); | ||||||
|  |       nmeaSourceCallbackUuid_ = | ||||||
|  |          generalSettings.nmea_source().RegisterValueChangedCallback( | ||||||
|  |             [this](const std::string&) { CreatePositionSource(); }); | ||||||
|  |    } | ||||||
|  |    ~Impl() | ||||||
|  |    { | ||||||
|  |       auto& generalSettings = settings::GeneralSettings::Instance(); | ||||||
|  | 
 | ||||||
|  |       generalSettings.positioning_plugin().UnregisterValueChangedCallback( | ||||||
|  |          positioningPluginCallbackUuid_); | ||||||
|  |       generalSettings.nmea_baud_rate().UnregisterValueChangedCallback( | ||||||
|  |          nmeaBaudRateCallbackUuid_); | ||||||
|  |       generalSettings.nmea_source().UnregisterValueChangedCallback( | ||||||
|  |          nmeaSourceCallbackUuid_); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    void CreatePositionSource(); | ||||||
|  | 
 | ||||||
|  |    PositionManager* self_; | ||||||
|  | 
 | ||||||
|  |    boost::uuids::uuid trackingUuid_; | ||||||
|  |    bool               trackingEnabled_ {false}; | ||||||
|  | 
 | ||||||
|  |    std::set<boost::uuids::uuid> uuids_ {}; | ||||||
|  | 
 | ||||||
|  |    std::mutex positionSourceMutex_ {}; | ||||||
|  | 
 | ||||||
|  |    QGeoPositionInfoSource* geoPositionInfoSource_ {}; | ||||||
|  |    QGeoPositionInfo        position_ {}; | ||||||
|  | 
 | ||||||
|  |    types::PositioningPlugin lastPositioningPlugin_ { | ||||||
|  |       types::PositioningPlugin::Unknown}; | ||||||
|  |    std::int64_t lastNmeaBaudRate_ {-1}; | ||||||
|  |    std::string  lastNmeaSource_ {"?"}; | ||||||
|  | 
 | ||||||
|  |    boost::uuids::uuid positioningPluginCallbackUuid_ {}; | ||||||
|  |    boost::uuids::uuid nmeaBaudRateCallbackUuid_ {}; | ||||||
|  |    boost::uuids::uuid nmeaSourceCallbackUuid_ {}; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | PositionManager::PositionManager() : p(std::make_unique<Impl>(this)) {} | ||||||
|  | PositionManager::~PositionManager() = default; | ||||||
|  | 
 | ||||||
|  | QGeoPositionInfo PositionManager::position() const | ||||||
|  | { | ||||||
|  |    return p->position_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool PositionManager::IsLocationTracked() | ||||||
|  | { | ||||||
|  |    return p->trackingEnabled_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void PositionManager::Impl::CreatePositionSource() | ||||||
|  | { | ||||||
|  |    auto& generalSettings = settings::GeneralSettings::Instance(); | ||||||
|  | 
 | ||||||
|  |    types::PositioningPlugin positioningPlugin = types::GetPositioningPlugin( | ||||||
|  |       generalSettings.positioning_plugin().GetValue()); | ||||||
|  |    std::int64_t nmeaBaudRate = generalSettings.nmea_baud_rate().GetValue(); | ||||||
|  |    std::string  nmeaSource   = generalSettings.nmea_source().GetValue(); | ||||||
|  | 
 | ||||||
|  |    if (positioningPlugin == lastPositioningPlugin_ && | ||||||
|  |        nmeaBaudRate == lastNmeaBaudRate_ && nmeaSource == lastNmeaSource_) | ||||||
|  |    { | ||||||
|  |       return; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    QGeoPositionInfoSource* positionSource = nullptr; | ||||||
|  | 
 | ||||||
|  |    // TODO: macOS requires permission
 | ||||||
|  |    if (positioningPlugin == types::PositioningPlugin::Default) | ||||||
|  |    { | ||||||
|  |       positionSource = QGeoPositionInfoSource::createDefaultSource(self_); | ||||||
|  |    } | ||||||
|  |    else if (positioningPlugin == types::PositioningPlugin::Nmea) | ||||||
|  |    { | ||||||
|  |       QVariantMap params {}; | ||||||
|  |       params["nmea.source"]   = QString::fromStdString(nmeaSource); | ||||||
|  |       params["nmea.baudrate"] = static_cast<int>(nmeaBaudRate); | ||||||
|  | 
 | ||||||
|  |       positionSource = | ||||||
|  |          QGeoPositionInfoSource::createSource("nmea", params, self_); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (positionSource != nullptr) | ||||||
|    { |    { | ||||||
|       logger_->debug("Using position source: {}", |       logger_->debug("Using position source: {}", | ||||||
|                         geoPositionInfoSource_->sourceName().toStdString()); |                      positionSource->sourceName().toStdString()); | ||||||
| 
 | 
 | ||||||
|          QObject::connect(geoPositionInfoSource_, |       QObject::connect(positionSource, | ||||||
|                        &QGeoPositionInfoSource::positionUpdated, |                        &QGeoPositionInfoSource::positionUpdated, | ||||||
|                        self_, |                        self_, | ||||||
|                        [this](const QGeoPositionInfo& info) |                        [this](const QGeoPositionInfo& info) | ||||||
|  | @ -51,37 +149,38 @@ public: | ||||||
|                           Q_EMIT self_->PositionUpdated(info); |                           Q_EMIT self_->PositionUpdated(info); | ||||||
|                        }); |                        }); | ||||||
|    } |    } | ||||||
|  |    else | ||||||
|  |    { | ||||||
|  |       logger_->error("Unable to create position source for plugin: {}", | ||||||
|  |                      types::GetPositioningPluginName(positioningPlugin)); | ||||||
|  |       return; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    ~Impl() {} |    lastPositioningPlugin_ = positioningPlugin; | ||||||
|  |    lastNmeaBaudRate_      = nmeaBaudRate; | ||||||
|  |    lastNmeaSource_        = nmeaSource; | ||||||
| 
 | 
 | ||||||
|    PositionManager* self_; |    std::unique_lock lock {positionSourceMutex_}; | ||||||
| 
 | 
 | ||||||
|    boost::uuids::uuid trackingUuid_; |    if (geoPositionInfoSource_ != nullptr) | ||||||
|    bool               trackingEnabled_ {false}; |    { | ||||||
|  |       geoPositionInfoSource_->stopUpdates(); | ||||||
|  |       delete geoPositionInfoSource_; | ||||||
|  |    } | ||||||
| 
 | 
 | ||||||
|    std::set<boost::uuids::uuid> uuids_ {}; |    geoPositionInfoSource_ = positionSource; | ||||||
| 
 | 
 | ||||||
|    QGeoPositionInfoSource* geoPositionInfoSource_ {}; |    if (!uuids_.empty()) | ||||||
|    QGeoPositionInfo        position_ {}; |    { | ||||||
| }; |       positionSource->startUpdates(); | ||||||
| 
 |    } | ||||||
| PositionManager::PositionManager() : p(std::make_unique<Impl>(this)) {} |  | ||||||
| PositionManager::~PositionManager() = default; |  | ||||||
| 
 |  | ||||||
| QGeoPositionInfo PositionManager::position() const |  | ||||||
| { |  | ||||||
|    return p->position_; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool PositionManager::IsLocationTracked() |  | ||||||
| { |  | ||||||
|    return p->trackingEnabled_; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void PositionManager::EnablePositionUpdates(boost::uuids::uuid uuid, | void PositionManager::EnablePositionUpdates(boost::uuids::uuid uuid, | ||||||
|                                             bool               enabled) |                                             bool               enabled) | ||||||
| { | { | ||||||
|  |    std::unique_lock lock {p->positionSourceMutex_}; | ||||||
|  | 
 | ||||||
|    if (p->geoPositionInfoSource_ == nullptr) |    if (p->geoPositionInfoSource_ == nullptr) | ||||||
|    { |    { | ||||||
|       return; |       return; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat