# UNDF: UNDF-2026-000000957 --- a/source/simulation2/components/CCmpRangeManager.cpp +++ b/source/simulation2/components/CCmpRangeManager.cpp @@ -1,6 +1,8 @@ // CWE-407: CCmpRangeManager m_ModifiedEntities uses std::vector with std::find // for dedup. RequestVisibilityUpdate is called per-entity, and GetLosVisibility // scans the vector per-entity per-player. With E entities and M modified, // this is O(E*M) per frame. Fix: use std::unordered_set for O(1) membership test. +#include // --- Declaration change --- @@ -409,7 +411,7 @@ - std::vector m_ModifiedEntities; + std::unordered_set m_ModifiedEntities; // --- Serialization: convert set to vector for serialization --- @@ -488,7 +490,10 @@ - Serializer(serialize, "modified entities", m_ModifiedEntities); + // Serialize as vector for backward compatibility + std::vector modifiedVec(m_ModifiedEntities.begin(), m_ModifiedEntities.end()); + Serializer(serialize, "modified entities", modifiedVec); + // On deserialize, rebuild set from vector + if (!serialize) + m_ModifiedEntities = std::unordered_set(modifiedVec.begin(), modifiedVec.end()); // --- GetLosVisibility: O(1) lookup instead of O(M) --- @@ -1777,7 +1782,7 @@ - if (std::find(m_ModifiedEntities.begin(), m_ModifiedEntities.end(), entId) != m_ModifiedEntities.end()) + if (m_ModifiedEntities.count(entId)) return ComputeLosVisibility(ent, player); // --- UpdateVisibilityData: iterate set, pop via iterator --- @@ -1877,8 +1882,11 @@ while (!m_ModifiedEntities.empty()) { - entity_id_t ent = m_ModifiedEntities.back(); - m_ModifiedEntities.pop_back(); + auto it = m_ModifiedEntities.begin(); + entity_id_t ent = *it; + m_ModifiedEntities.erase(it); // --- RequestVisibilityUpdate: O(1) insert instead of O(M) find --- @@ -1891,8 +1899,7 @@ - if (std::find(m_ModifiedEntities.begin(), m_ModifiedEntities.end(), ent) == m_ModifiedEntities.end()) - m_ModifiedEntities.push_back(ent); + m_ModifiedEntities.insert(ent); }