1
0
forked from 0ad/0ad

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.
This commit is contained in:
Nicolas Auvray 2015-07-15 16:46:59 +00:00
parent 9f1b85d562
commit 39d93ea17c

View File

@ -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);
}