Fix line repopulation on alert removal

This commit is contained in:
Dan Paulat 2025-05-05 22:49:43 -05:00
parent 4532327f50
commit 73355c9424

View file

@ -10,6 +10,7 @@
#include <chrono> #include <chrono>
#include <mutex> #include <mutex>
#include <ranges> #include <ranges>
#include <set>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
@ -116,7 +117,7 @@ signals:
void AlertAdded(const std::shared_ptr<SegmentRecord>& segmentRecord, void AlertAdded(const std::shared_ptr<SegmentRecord>& segmentRecord,
awips::Phenomenon phenomenon); awips::Phenomenon phenomenon);
void AlertUpdated(const std::shared_ptr<SegmentRecord>& segmentRecord); void AlertUpdated(const std::shared_ptr<SegmentRecord>& segmentRecord);
void AlertsRemoved(awips::Phenomenon phenomenon, bool alertActive); void AlertsRemoved(awips::Phenomenon phenomenon);
void AlertsUpdated(awips::Phenomenon phenomenon, bool alertActive); void AlertsUpdated(awips::Phenomenon phenomenon, bool alertActive);
}; };
@ -201,6 +202,7 @@ public:
boost::container::stable_vector< boost::container::stable_vector<
std::shared_ptr<gl::draw::GeoLineDrawItem>>& drawItems); std::shared_ptr<gl::draw::GeoLineDrawItem>>& drawItems);
void PopulateLines(bool alertActive); void PopulateLines(bool alertActive);
void RepopulateLines();
void UpdateLines(); void UpdateLines();
static LineData CreateLineData(const settings::LineSettings& lineSettings); static LineData CreateLineData(const settings::LineSettings& lineSettings);
@ -216,6 +218,7 @@ public:
const awips::ibw::ImpactBasedWarningInfo& ibw_; const awips::ibw::ImpactBasedWarningInfo& ibw_;
std::unique_ptr<QObject> receiver_ {std::make_unique<QObject>()}; std::unique_ptr<QObject> receiver_ {std::make_unique<QObject>()};
std::mutex receiverMutex_ {};
std::unordered_map<bool, std::shared_ptr<gl::draw::GeoLines>> geoLines_; std::unordered_map<bool, std::shared_ptr<gl::draw::GeoLines>> geoLines_;
@ -446,9 +449,7 @@ void AlertLayerHandler::HandleAlertsRemoved(
{ {
logger_->trace("HandleAlertsRemoved: {} keys", keys.size()); logger_->trace("HandleAlertsRemoved: {} keys", keys.size());
std::unordered_set<std::pair<awips::Phenomenon, bool>, std::set<awips::Phenomenon> alertsRemoved {};
AlertTypeHash<std::pair<awips::Phenomenon, bool>>>
alertsRemoved {};
// Take a unique lock before modifying segments // Take a unique lock before modifying segments
std::unique_lock lock {alertMutex_}; std::unique_lock lock {alertMutex_};
@ -481,7 +482,7 @@ void AlertLayerHandler::HandleAlertsRemoved(
} }
} }
alertsRemoved.emplace(key.phenomenon_, alertActive); alertsRemoved.emplace(key.phenomenon_);
} }
// Remove the key from segmentsByKey_ // Remove the key from segmentsByKey_
@ -495,7 +496,7 @@ void AlertLayerHandler::HandleAlertsRemoved(
// Emit signal to notify that alerts have been removed // Emit signal to notify that alerts have been removed
for (auto& alert : alertsRemoved) for (auto& alert : alertsRemoved)
{ {
Q_EMIT AlertsRemoved(alert.first, alert.second); Q_EMIT AlertsRemoved(alert);
} }
} }
@ -513,6 +514,9 @@ void AlertLayer::Impl::ConnectAlertHandlerSignals()
{ {
if (phenomenon == phenomenon_) if (phenomenon == phenomenon_)
{ {
// Only process one signal at a time
const std::unique_lock lock {receiverMutex_};
AddAlert(segmentRecord); AddAlert(segmentRecord);
} }
}); });
@ -525,25 +529,27 @@ void AlertLayer::Impl::ConnectAlertHandlerSignals()
{ {
if (segmentRecord->key_.phenomenon_ == phenomenon_) if (segmentRecord->key_.phenomenon_ == phenomenon_)
{ {
// Only process one signal at a time
const std::unique_lock lock {receiverMutex_};
UpdateAlert(segmentRecord); UpdateAlert(segmentRecord);
} }
}); });
QObject::connect( QObject::connect(&alertLayerHandler,
&alertLayerHandler, &AlertLayerHandler::AlertsRemoved,
&AlertLayerHandler::AlertsRemoved, receiver_.get(),
receiver_.get(), [this](awips::Phenomenon phenomenon)
[&alertLayerHandler, this](awips::Phenomenon phenomenon, bool alertActive) {
{ if (phenomenon == phenomenon_)
if (phenomenon == phenomenon_) {
{ // Only process one signal at a time
// Take a shared lock to prevent handling additional alerts while const std::unique_lock lock {receiverMutex_};
// populating initial lists
const std::shared_lock lock {alertLayerHandler.alertMutex_};
// Re-populate the lines if multiple alerts were removed // Re-populate the lines if multiple alerts were
PopulateLines(alertActive); // removed
} RepopulateLines();
}); }
});
} }
void AlertLayer::Impl::ConnectSignals() void AlertLayer::Impl::ConnectSignals()
@ -799,6 +805,25 @@ void AlertLayer::Impl::PopulateLines(bool alertActive)
geoLines->FinishLines(); geoLines->FinishLines();
} }
void AlertLayer::Impl::RepopulateLines()
{
auto& alertLayerHandler = AlertLayerHandler::Instance();
// Take a shared lock to prevent handling additional alerts while populating
// initial lists
const std::shared_lock alertLock {alertLayerHandler.alertMutex_};
linesBySegment_.clear();
segmentsByLine_.clear();
for (auto alertActive : {false, true})
{
PopulateLines(alertActive);
}
Q_EMIT self_->NeedsRendering();
}
void AlertLayer::Impl::UpdateLines() void AlertLayer::Impl::UpdateLines()
{ {
std::unique_lock lock {linesMutex_}; std::unique_lock lock {linesMutex_};