diff --git a/scwx-qt/source/scwx/qt/map/alert_layer.cpp b/scwx-qt/source/scwx/qt/map/alert_layer.cpp index 77a2332f..9188cc4c 100644 --- a/scwx-qt/source/scwx/qt/map/alert_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/alert_layer.cpp @@ -336,27 +336,28 @@ void AlertLayerHandler::HandleAlert(const types::TextEventKey& key, alertsUpdated {}; const auto& messageList = textEventManager_->message_list(key); - auto message = messageList.at(messageIndex); - if (message->uuid() != uuid) + // Find message by UUID instead of index, as the message index could have + // changed between the signal being emitted and the handler being called + auto messageIt = std::find_if(messageList.cbegin(), + messageList.cend(), + [&uuid](const auto& message) + { return uuid == message->uuid(); }); + + if (messageIt == messageList.cend()) { - // Find message by UUID instead of index, as the message index could have - // changed between the signal being emitted and the handler being called - auto it = std::find_if(messageList.cbegin(), - messageList.cend(), - [&uuid](const auto& message) - { return uuid == message->uuid(); }); - - if (it == messageList.cend()) - { - logger_->warn( - "Could not find alert uuid: {} ({})", key.ToString(), messageIndex); - return; - } - - message = *it; + logger_->warn( + "Could not find alert uuid: {} ({})", key.ToString(), messageIndex); + return; } + auto& message = *messageIt; + auto nextMessageIt = std::next(messageIt); + + // Store the current message index + messageIndex = + static_cast(std::distance(messageList.cbegin(), messageIt)); + // Determine start time for first segment std::chrono::system_clock::time_point segmentBegin {}; if (message->segment_count() > 0) @@ -364,14 +365,31 @@ void AlertLayerHandler::HandleAlert(const types::TextEventKey& key, segmentBegin = message->segment(0)->event_begin(); } + // Determine the start time for the first segment of the next message + std::optional nextMessageBegin {}; + if (nextMessageIt != messageList.cend()) + { + nextMessageBegin = + (*nextMessageIt) + ->wmo_header() + ->GetDateTime((*nextMessageIt)->segment(0)->event_begin()); + } + // Take a unique mutex before modifying segments std::unique_lock lock {alertMutex_}; - // Update any existing segments with new end time + // Update any existing earlier segments with new end time auto& segmentsForKey = segmentsByKey_[key]; for (auto& segmentRecord : segmentsForKey) { - if (segmentRecord->segmentEnd_ > segmentBegin) + // Determine if the segment is earlier than the current message + auto it = std::find( + messageList.cbegin(), messageList.cend(), segmentRecord->message_); + auto segmentIndex = + static_cast(std::distance(messageList.cbegin(), it)); + + if (segmentIndex < messageIndex && + segmentRecord->segmentEnd_ > segmentBegin) { segmentRecord->segmentEnd_ = segmentBegin; @@ -398,6 +416,14 @@ void AlertLayerHandler::HandleAlert(const types::TextEventKey& key, std::shared_ptr segmentRecord = std::make_shared(segment, key, message); + // Update segment end time to be no later than the begin time of the next + // message (if present) + if (nextMessageBegin.has_value() && + segmentRecord->segmentEnd_ > nextMessageBegin) + { + segmentRecord->segmentEnd_ = nextMessageBegin.value(); + } + segmentsForKey.push_back(segmentRecord); segmentsForType.push_back(segmentRecord);