From 39d93ea17c9229e12a9647c6302abb150821130b Mon Sep 17 00:00:00 2001 From: Itms Date: Wed, 15 Jul 2015 16:46:59 +0000 Subject: [PATCH] Change the handling of modified entities in the visibility update. The game has to deal with situations such as: the visibility of an entity changes, a mirage is created for it -> the mirage visibility is updated -> the entity visibility is updated back. All of this process now happens in the same turn, and all updates are guaranteed to be performed. This fixes a source of serialization errors and rejoin OOSes. Fixes #3107 This was SVN commit r16857. --- .../components/CCmpRangeManager.cpp | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/source/simulation2/components/CCmpRangeManager.cpp b/source/simulation2/components/CCmpRangeManager.cpp index 1977d8db9a..77c34afe35 100644 --- a/source/simulation2/components/CCmpRangeManager.cpp +++ b/source/simulation2/components/CCmpRangeManager.cpp @@ -1601,7 +1601,10 @@ public: void UpdateVisibilityData() { PROFILE("UpdateVisibilityData"); - + + if (m_GlobalVisibilityUpdate) + m_ModifiedEntities.clear(); + for (i32 n = 0; n < m_LosTilesPerSide * m_LosTilesPerSide; ++n) { for (player_id_t player = 1; player < MAX_LOS_PLAYER_ID + 1; ++player) @@ -1616,16 +1619,20 @@ public: } std::fill(m_GlobalPlayerVisibilityUpdate.begin(), m_GlobalPlayerVisibilityUpdate.end(), 0); - - // Don't bother updating modified entities if the update was global - if (!m_GlobalVisibilityUpdate) - { - for (auto& ent : m_ModifiedEntities) - UpdateVisibility(ent); - } - - m_ModifiedEntities.clear(); m_GlobalVisibilityUpdate = false; + + // Calling UpdateVisibility can modify m_ModifiedEntities, so be careful + // Infinite loops could be triggered by feedback between entities and their mirages + int check = 0; + while (!m_ModifiedEntities.empty()) + { + ++check; + ENSURE(check < 1000 && "Possible infinite loop in UpdateVisibilityData"); + + entity_id_t ent = m_ModifiedEntities.back(); + m_ModifiedEntities.pop_back(); + UpdateVisibility(ent); + } } virtual void RequestVisibilityUpdate(entity_id_t ent) @@ -1653,7 +1660,7 @@ public: } void UpdateVisibility(entity_id_t ent) - { + { for (player_id_t player = 1; player < MAX_LOS_PLAYER_ID + 1; ++player) UpdateVisibility(ent, player); }