diff --git a/scwx-qt/source/scwx/qt/gl/draw/geo_lines.cpp b/scwx-qt/source/scwx/qt/gl/draw/geo_lines.cpp index b18e68eb..aa4d2ccb 100644 --- a/scwx-qt/source/scwx/qt/gl/draw/geo_lines.cpp +++ b/scwx-qt/source/scwx/qt/gl/draw/geo_lines.cpp @@ -50,6 +50,7 @@ struct GeoLineDrawItem : types::EventHandler units::angle::degrees angle_ {}; std::string hoverText_ {}; GeoLines::HoverCallback hoverCallback_ {nullptr}; + size_t lineIndex_ {0}; }; class GeoLines::Impl @@ -87,10 +88,10 @@ public: void UpdateBuffers(); void UpdateModifiedLineBuffers(); void UpdateSingleBuffer(const std::shared_ptr& di, - std::size_t lineIndex, std::vector& linesBuffer, - std::vector& integerBuffer, - std::vector& hoverLines); + std::vector& integerBuffer, + std::unordered_map, + LineHoverEntry>& hoverLines); std::shared_ptr context_; @@ -112,8 +113,10 @@ public: std::vector newLinesBuffer_ {}; std::vector newIntegerBuffer_ {}; - std::vector currentHoverLines_ {}; - std::vector newHoverLines_ {}; + std::unordered_map, LineHoverEntry> + currentHoverLines_ {}; + std::unordered_map, LineHoverEntry> + newHoverLines_ {}; std::shared_ptr shaderProgram_; GLint uMVPMatrixLocation_; @@ -323,7 +326,9 @@ void GeoLines::StartLines() std::shared_ptr GeoLines::AddLine() { - return p->newLineList_.emplace_back(std::make_shared()); + auto& di = p->newLineList_.emplace_back(std::make_shared()); + di->lineIndex_ = p->newLineList_.size() - 1; + return di; } void GeoLines::SetLineLocation(const std::shared_ptr& di, @@ -470,7 +475,7 @@ void GeoLines::Impl::UpdateBuffers() // Update line buffer UpdateSingleBuffer( - di, i, newLinesBuffer_, newIntegerBuffer_, newHoverLines_); + di, newLinesBuffer_, newIntegerBuffer_, newHoverLines_); } // All lines have been updated @@ -488,23 +493,15 @@ void GeoLines::Impl::UpdateModifiedLineBuffers() // Update buffers for modified lines for (auto& di : dirtyLines_) { - // Find modified line in the current list - auto it = - std::find(currentLineList_.cbegin(), currentLineList_.cend(), di); - - // Ignore invalid lines - if (it == currentLineList_.cend()) + // Check if modified line is in the current list + if (di->lineIndex_ >= currentLineList_.size() || + currentLineList_[di->lineIndex_] != di) { continue; } - auto lineIndex = std::distance(currentLineList_.cbegin(), it); - - UpdateSingleBuffer(di, - lineIndex, - currentLinesBuffer_, - currentIntegerBuffer_, - currentHoverLines_); + UpdateSingleBuffer( + di, currentLinesBuffer_, currentIntegerBuffer_, currentHoverLines_); } // Clear list of modified lines @@ -517,10 +514,10 @@ void GeoLines::Impl::UpdateModifiedLineBuffers() void GeoLines::Impl::UpdateSingleBuffer( const std::shared_ptr& di, - std::size_t lineIndex, std::vector& lineBuffer, std::vector& integerBuffer, - std::vector& hoverLines) + std::unordered_map, LineHoverEntry>& + hoverLines) { // Threshold value units::length::nautical_miles threshold = di->threshold_; @@ -588,10 +585,10 @@ void GeoLines::Impl::UpdateSingleBuffer( // Buffer position data auto lineBufferPosition = lineBuffer.end(); - auto lineBufferOffset = lineIndex * kLineBufferLength_; + auto lineBufferOffset = di->lineIndex_ * kLineBufferLength_; auto integerBufferPosition = integerBuffer.end(); - auto integerBufferOffset = lineIndex * kIntegerBufferLength_; + auto integerBufferOffset = di->lineIndex_ * kIntegerBufferLength_; if (lineBufferOffset < lineBuffer.size()) { @@ -620,9 +617,7 @@ void GeoLines::Impl::UpdateSingleBuffer( std::copy(integerData.begin(), integerData.end(), integerBufferPosition); } - auto hoverIt = std::find_if(hoverLines.begin(), - hoverLines.end(), - [&di](auto& entry) { return entry.di_ == di; }); + auto hoverIt = hoverLines.find(di); if (di->visible_ && (!di->hoverText_.empty() || di->hoverCallback_ != nullptr || di->event_ != nullptr)) @@ -644,17 +639,23 @@ void GeoLines::Impl::UpdateSingleBuffer( if (hoverIt == hoverLines.end()) { - hoverLines.emplace_back( - LineHoverEntry {di, sc1, sc2, otl, otr, obl, obr}); + hoverLines.emplace(di, + LineHoverEntry {.di_ = di, + .p1_ = sc1, + .p2_ = sc2, + .otl_ = otl, + .otr_ = otr, + .obl_ = obl, + .obr_ = obr}); } else { - hoverIt->p1_ = sc1; - hoverIt->p2_ = sc2; - hoverIt->otl_ = otl; - hoverIt->otr_ = otr; - hoverIt->obl_ = obl; - hoverIt->obr_ = obr; + hoverIt->second.p1_ = sc1; + hoverIt->second.p2_ = sc2; + hoverIt->second.otl_ = otl; + hoverIt->second.otr_ = otr; + hoverIt->second.obl_ = obl; + hoverIt->second.obr_ = obr; } } else if (hoverIt != hoverLines.end()) @@ -726,10 +727,12 @@ bool GeoLines::RunMousePicking( // For each pickable line auto it = std::find_if( std::execution::par_unseq, - p->currentHoverLines_.rbegin(), - p->currentHoverLines_.rend(), - [&mapDistance, &selectedTime, &mapMatrix, &mouseCoords](const auto& line) + p->currentHoverLines_.cbegin(), + p->currentHoverLines_.cend(), + [&mapDistance, &selectedTime, &mapMatrix, &mouseCoords]( + const auto& lineIt) { + const auto& line = lineIt.second; if (( // Placefile is thresholded mapDistance > units::length::meters {0.0} && @@ -785,24 +788,24 @@ bool GeoLines::RunMousePicking( return util::maplibre::IsPointInPolygon({tl, bl, br, tr}, mouseCoords); }); - if (it != p->currentHoverLines_.crend()) + if (it != p->currentHoverLines_.cend()) { itemPicked = true; - if (!it->di_->hoverText_.empty()) + if (!it->second.di_->hoverText_.empty()) { // Show tooltip - util::tooltip::Show(it->di_->hoverText_, mouseGlobalPos); + util::tooltip::Show(it->second.di_->hoverText_, mouseGlobalPos); } - else if (it->di_->hoverCallback_ != nullptr) + else if (it->second.di_->hoverCallback_ != nullptr) { - it->di_->hoverCallback_(it->di_, mouseGlobalPos); + it->second.di_->hoverCallback_(it->second.di_, mouseGlobalPos); } - if (it->di_->event_ != nullptr) + if (it->second.di_->event_ != nullptr) { // Register event handler - eventHandler = it->di_; + eventHandler = it->second.di_; } } diff --git a/scwx-qt/source/scwx/qt/gl/draw/geo_lines.hpp b/scwx-qt/source/scwx/qt/gl/draw/geo_lines.hpp index b7b792d0..d6727110 100644 --- a/scwx-qt/source/scwx/qt/gl/draw/geo_lines.hpp +++ b/scwx-qt/source/scwx/qt/gl/draw/geo_lines.hpp @@ -19,9 +19,8 @@ struct GeoLineDrawItem; class GeoLines : public DrawItem { public: - typedef std::function&, - const QPointF&)> - HoverCallback; + using HoverCallback = std::function&, const QPointF&)>; explicit GeoLines(std::shared_ptr context); ~GeoLines(); diff --git a/scwx-qt/source/scwx/qt/map/alert_layer.cpp b/scwx-qt/source/scwx/qt/map/alert_layer.cpp index b05084c9..c88f6220 100644 --- a/scwx-qt/source/scwx/qt/map/alert_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/alert_layer.cpp @@ -159,8 +159,9 @@ public: void ConnectSignals(); void HandleGeoLinesEvent(std::weak_ptr& di, QEvent* ev); - void HandleGeoLinesHover(std::shared_ptr& di, - const QPointF& mouseGlobalPos); + void + HandleGeoLinesHover(const std::shared_ptr& di, + const QPointF& mouseGlobalPos); void ScheduleRefresh(); LineData& GetLineData(const std::shared_ptr& segment, @@ -720,8 +721,8 @@ void AlertLayer::Impl::HandleGeoLinesEvent( } void AlertLayer::Impl::HandleGeoLinesHover( - std::shared_ptr& di, - const QPointF& mouseGlobalPos) + const std::shared_ptr& di, + const QPointF& mouseGlobalPos) { if (di != lastHoverDi_) {