From fca6a6484e402323e8c593bc9dcbb37baa84e5fc Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Wed, 22 Nov 2023 07:27:37 -0600 Subject: [PATCH] Add position manager to handle location updates --- scwx-qt/scwx-qt.cmake | 2 + .../scwx/qt/manager/position_manager.cpp | 121 ++++++++++++++++++ .../scwx/qt/manager/position_manager.hpp | 42 ++++++ 3 files changed, 165 insertions(+) create mode 100644 scwx-qt/source/scwx/qt/manager/position_manager.cpp create mode 100644 scwx-qt/source/scwx/qt/manager/position_manager.hpp diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index 0e53f5d7..0b59b326 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -76,6 +76,7 @@ set(SRC_GL_DRAW source/scwx/qt/gl/draw/draw_item.cpp source/scwx/qt/gl/draw/rectangle.cpp) set(HDR_MANAGER source/scwx/qt/manager/font_manager.hpp source/scwx/qt/manager/placefile_manager.hpp + source/scwx/qt/manager/position_manager.hpp source/scwx/qt/manager/radar_product_manager.hpp source/scwx/qt/manager/radar_product_manager_notifier.hpp source/scwx/qt/manager/resource_manager.hpp @@ -85,6 +86,7 @@ set(HDR_MANAGER source/scwx/qt/manager/font_manager.hpp source/scwx/qt/manager/update_manager.hpp) set(SRC_MANAGER source/scwx/qt/manager/font_manager.cpp source/scwx/qt/manager/placefile_manager.cpp + source/scwx/qt/manager/position_manager.cpp source/scwx/qt/manager/radar_product_manager.cpp source/scwx/qt/manager/radar_product_manager_notifier.cpp source/scwx/qt/manager/resource_manager.cpp diff --git a/scwx-qt/source/scwx/qt/manager/position_manager.cpp b/scwx-qt/source/scwx/qt/manager/position_manager.cpp new file mode 100644 index 00000000..15f3bd09 --- /dev/null +++ b/scwx-qt/source/scwx/qt/manager/position_manager.cpp @@ -0,0 +1,121 @@ +#include +#include +#include + +#include + +#include + +namespace scwx +{ +namespace qt +{ +namespace manager +{ + +static const std::string logPrefix_ = "scwx::qt::manager::position_manager"; +static const auto logger_ = scwx::util::Logger::Create(logPrefix_); + +class PositionManager::Impl +{ +public: + explicit Impl(PositionManager* self) : self_ {self} + { + // TODO: macOS requires permission + geoPositionInfoSource_ = + QGeoPositionInfoSource::createDefaultSource(self); + + if (geoPositionInfoSource_ != nullptr) + { + logger_->debug("Using position source: {}", + geoPositionInfoSource_->sourceName().toStdString()); + + QObject::connect(geoPositionInfoSource_, + &QGeoPositionInfoSource::positionUpdated, + self_, + [this](const QGeoPositionInfo& info) + { + auto coordinate = info.coordinate(); + + if (coordinate != position_.coordinate()) + { + logger_->debug("Position updated: {}, {}", + coordinate.latitude(), + coordinate.longitude()); + } + + position_ = info; + + Q_EMIT self_->PositionUpdated(info); + }); + } + } + + ~Impl() {} + + PositionManager* self_; + + std::set uuids_ {}; + + QGeoPositionInfoSource* geoPositionInfoSource_ {}; + QGeoPositionInfo position_ {}; +}; + +PositionManager::PositionManager() : p(std::make_unique(this)) {} +PositionManager::~PositionManager() = default; + +QGeoPositionInfo PositionManager::position() const +{ + return p->position_; +} + +void PositionManager::TrackLocation(boost::uuids::uuid uuid, + bool trackingEnabled) +{ + if (p->geoPositionInfoSource_ == nullptr) + { + return; + } + + if (trackingEnabled) + { + if (p->uuids_.empty()) + { + p->geoPositionInfoSource_->startUpdates(); + } + + p->uuids_.insert(uuid); + } + else + { + p->uuids_.erase(uuid); + + if (p->uuids_.empty()) + { + p->geoPositionInfoSource_->stopUpdates(); + } + } +} + +std::shared_ptr PositionManager::Instance() +{ + static std::weak_ptr positionManagerReference_ {}; + static std::mutex instanceMutex_ {}; + + std::unique_lock lock(instanceMutex_); + + std::shared_ptr positionManager = + positionManagerReference_.lock(); + + if (positionManager == nullptr) + { + positionManager = std::make_shared(); + positionManagerReference_ = positionManager; + } + + return positionManager; +} + +} // namespace manager +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/manager/position_manager.hpp b/scwx-qt/source/scwx/qt/manager/position_manager.hpp new file mode 100644 index 00000000..815b76c9 --- /dev/null +++ b/scwx-qt/source/scwx/qt/manager/position_manager.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include + +#include +#include + +class QGeoPositionInfo; + +namespace scwx +{ +namespace qt +{ +namespace manager +{ + +class PositionManager : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY_MOVE(PositionManager) + +public: + explicit PositionManager(); + ~PositionManager(); + + QGeoPositionInfo position() const; + + void TrackLocation(boost::uuids::uuid uuid, bool trackingEnabled); + + static std::shared_ptr Instance(); + +signals: + void PositionUpdated(const QGeoPositionInfo& info); + +private: + class Impl; + std::unique_ptr p; +}; + +} // namespace manager +} // namespace qt +} // namespace scwx