[Client] Fix infinite loop in CellController

Previously, using CellController::getCellStore() to get an unloaded CellStore would make its references get loaded in the process, with the CellStore's loadRefs() then running updateMergedRefs(), which in turn – before getting as far as setting the CellStore's state to State_Loaded – would call CellController::hasLocalAuthority() on its accompanying ESM::Cell, which would then run CellController::isActiveWorldCell(), which would then run CellController::getCellStore() to get the CellStore again, which – still being marked as unloaded – would run the whole loop again... and again.
This commit is contained in:
David Cernat 2019-09-23 21:18:38 +03:00
parent d4df2948dd
commit 339428872e
4 changed files with 17 additions and 10 deletions

View File

@ -589,7 +589,7 @@ namespace MWBase
Make it possible to check whether a cell is active Make it possible to check whether a cell is active
*/ */
virtual bool isCellActive(MWWorld::CellStore* cell) = 0; virtual bool isCellActive(const ESM::Cell& cell) = 0;
/* /*
End of tes3mp addition End of tes3mp addition
*/ */

View File

@ -35,7 +35,7 @@ void CellController::updateLocal(bool forceUpdate)
{ {
mwmp::Cell *mpCell = it->second; mwmp::Cell *mpCell = it->second;
if (!MWBase::Environment::get().getWorld()->isCellActive(mpCell->getCellStore())) if (!MWBase::Environment::get().getWorld()->isCellActive(*mpCell->getCellStore()->getCell()))
{ {
mpCell->uninitializeLocalActors(); mpCell->uninitializeLocalActors();
mpCell->uninitializeDedicatedActors(); mpCell->uninitializeDedicatedActors();
@ -323,11 +323,7 @@ bool CellController::isInitializedCell(const ESM::Cell& cell)
bool CellController::isActiveWorldCell(const ESM::Cell& cell) bool CellController::isActiveWorldCell(const ESM::Cell& cell)
{ {
MWWorld::CellStore *cellStore = getCellStore(cell); return MWBase::Environment::get().getWorld()->isCellActive(cell);
if (!cellStore) return false;
return MWBase::Environment::get().getWorld()->isCellActive(cellStore);
} }
Cell *CellController::getCell(const ESM::Cell& cell) Cell *CellController::getCell(const ESM::Cell& cell)

View File

@ -2905,9 +2905,20 @@ namespace MWWorld
Make it possible to check whether a cell is active Make it possible to check whether a cell is active
*/ */
bool World::isCellActive(MWWorld::CellStore* cell) bool World::isCellActive(const ESM::Cell& cell)
{ {
return mWorldScene->isCellActive(*cell); const Scene::CellStoreCollection& activeCells = mWorldScene->getActiveCells();
mwmp::CellController *cellController = mwmp::Main::get().getCellController();
for (auto it = activeCells.begin(); it != activeCells.end(); ++it)
{
if (cellController->isSameCell(cell, *(*it)->getCell()))
{
return true;
}
}
return false;
} }
/* /*
End of tes3mp addition End of tes3mp addition

View File

@ -697,7 +697,7 @@ namespace MWWorld
Make it possible to check whether a cell is active Make it possible to check whether a cell is active
*/ */
bool isCellActive(MWWorld::CellStore* cell) override; bool isCellActive(const ESM::Cell& cell) override;
/* /*
End of tes3mp addition End of tes3mp addition
*/ */