Synchronize map updates with traffic manager

Signed-off-by: mvglasow <michael -at- vonglasow.com>
This commit is contained in:
mvglasow
2025-08-28 21:10:42 +03:00
parent d46c0fec76
commit ef806cf18a
3 changed files with 60 additions and 48 deletions

View File

@@ -443,13 +443,13 @@ void Framework::OnCountryFileDownloaded(storage::CountryId const &,
m2::RectD rect = mercator::Bounds::FullRect(); m2::RectD rect = mercator::Bounds::FullRect();
if (localFile && localFile->OnDisk(MapFileType::Map)) if (localFile && localFile->OnDisk(MapFileType::Map))
{ m_trafficManager.RunSynchronized([this, localFile, &rect](){
auto const res = RegisterMap(*localFile); auto const res = RegisterMap(*localFile);
MwmSet::MwmId const & id = res.first; MwmSet::MwmId const & id = res.first;
if (id.IsAlive()) if (id.IsAlive())
rect = id.GetInfo()->m_bordersRect; rect = id.GetInfo()->m_bordersRect;
m_trafficManager.Invalidate(id); m_trafficManager.Invalidate(id);
} });
m_transitManager.Invalidate(); m_transitManager.Invalidate();
m_isolinesManager.Invalidate(); m_isolinesManager.Invalidate();

View File

@@ -301,53 +301,49 @@ void TrafficManager::Invalidate(MwmSet::MwmId const & mwmId)
auto const mwmRect = mwmId.GetInfo()->m_bordersRect; // m2::RectD auto const mwmRect = mwmId.GetInfo()->m_bordersRect; // m2::RectD
traffxml::TraffFeed invalidated; traffxml::TraffFeed invalidated;
for (auto it = m_messageCache.begin(); it != m_messageCache.end(); )
{ {
std::lock_guard<std::mutex> lock(m_mutex); if (!it->second.m_location)
for (auto it = m_messageCache.begin(); it != m_messageCache.end(); )
{ {
if (!it->second.m_location) it++;
{ continue;
it++;
continue;
}
bool isInvalid = false;
// invalidate if decoded location uses a previous version of the MWM
for (auto const & [decodedMwmId, coloring] : it->second.m_decoded)
if (decodedMwmId.GetInfo()->GetCountryName() == mwmId.GetInfo()->GetCountryName())
isInvalid = true;
// invalidate if bounding rect of reference points intersects with bounding rect of MWM
if (!isInvalid)
{
m2::RectD locationRect;
for (auto const & point : {it->second.m_location.value().m_from,
it->second.m_location.value().m_via,
it->second.m_location.value().m_at,
it->second.m_location.value().m_to})
if (point)
locationRect.Add(mercator::FromLatLon(point.value().m_coordinates));
isInvalid = locationRect.IsIntersect(mwmRect);
}
if (isInvalid)
{
traffxml::TraffMessage message(it->second);
message.m_decoded.clear();
invalidated.push_back(message);
it = m_messageCache.erase(it);
}
else
++it;
} }
if (!invalidated.empty()) bool isInvalid = false;
// invalidate if decoded location uses a previous version of the MWM
for (auto const & [decodedMwmId, coloring] : it->second.m_decoded)
if (decodedMwmId.GetInfo()->GetCountryName() == mwmId.GetInfo()->GetCountryName())
isInvalid = true;
// invalidate if bounding rect of reference points intersects with bounding rect of MWM
if (!isInvalid)
{ {
m_feedQueue.insert(m_feedQueue.begin(), invalidated); m2::RectD locationRect;
m_condition.notify_one(); for (auto const & point : {it->second.m_location.value().m_from,
it->second.m_location.value().m_via,
it->second.m_location.value().m_at,
it->second.m_location.value().m_to})
if (point)
locationRect.Add(mercator::FromLatLon(point.value().m_coordinates));
isInvalid = locationRect.IsIntersect(mwmRect);
} }
if (isInvalid)
{
traffxml::TraffMessage message(it->second);
message.m_decoded.clear();
invalidated.push_back(message);
it = m_messageCache.erase(it);
}
else
++it;
}
if (!invalidated.empty())
{
m_feedQueue.insert(m_feedQueue.begin(), invalidated);
m_condition.notify_one();
} }
} }

View File

@@ -224,6 +224,9 @@ public:
* for these locations are discarded and decoded again, ensuring they are based on the new MWM. * for these locations are discarded and decoded again, ensuring they are based on the new MWM.
* The TraFF messages themselves remain unchanged. * The TraFF messages themselves remain unchanged.
* *
* This method must either be called from a lambda function passed to `RunSynchronized()`,
* or the caller must explicitly lock the private `m_mutex` prior to calling this method.
*
* @param mwmId The newly addded MWM. * @param mwmId The newly addded MWM.
*/ */
void Invalidate(MwmSet::MwmId const & mwmId); void Invalidate(MwmSet::MwmId const & mwmId);
@@ -313,6 +316,19 @@ public:
*/ */
void SetTrafficUpdateCallbackFn(TrafficUpdateCallbackFn && fn); void SetTrafficUpdateCallbackFn(TrafficUpdateCallbackFn && fn);
/**
* @brief Runs a function guarded by the traffic manager mutex.
*
* This locks `m_mutex`, then runs `f` and releases the mutex.
*
* @param f
*/
void RunSynchronized(std::function<void()> f)
{
std::lock_guard<std::mutex> lock(m_mutex);
f();
}
private: private:
/** /**