mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-04 12:39:55 +00:00
Remove and add tile in single critical section
This commit is contained in:
parent
144e1a063b
commit
84949bedb1
@ -216,23 +216,6 @@ namespace
|
|||||||
return NavMeshData(navMeshData, navMeshDataSize);
|
return NavMeshData(navMeshData, navMeshDataSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AutoIncrementRevision
|
|
||||||
{
|
|
||||||
std::atomic_size_t& mNavMeshRevision;
|
|
||||||
bool mNavMeshChanged;
|
|
||||||
|
|
||||||
AutoIncrementRevision(std::atomic_size_t& navMeshRevision)
|
|
||||||
: mNavMeshRevision(navMeshRevision)
|
|
||||||
, mNavMeshChanged(false)
|
|
||||||
{}
|
|
||||||
|
|
||||||
~AutoIncrementRevision()
|
|
||||||
{
|
|
||||||
if (mNavMeshChanged)
|
|
||||||
++mNavMeshRevision;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
UpdateNavMeshStatus makeUpdateNavMeshStatus(bool removed, bool add)
|
UpdateNavMeshStatus makeUpdateNavMeshStatus(bool removed, bool add)
|
||||||
{
|
{
|
||||||
if (removed && add)
|
if (removed && add)
|
||||||
@ -292,20 +275,17 @@ namespace DetourNavigator
|
|||||||
const auto x = changedTile.x();
|
const auto x = changedTile.x();
|
||||||
const auto y = changedTile.y();
|
const auto y = changedTile.y();
|
||||||
|
|
||||||
AutoIncrementRevision incRev(navMeshCacheItem.mNavMeshRevision);
|
const auto removeTile = [&] {
|
||||||
bool removed = false;
|
|
||||||
|
|
||||||
{
|
|
||||||
const auto locked = navMesh.lock();
|
const auto locked = navMesh.lock();
|
||||||
removed = dtStatusSucceed(locked->removeTile(locked->getTileRefAt(x, y, 0), nullptr, nullptr));
|
const auto removed = dtStatusSucceed(locked->removeTile(locked->getTileRefAt(x, y, 0), nullptr, nullptr));
|
||||||
}
|
navMeshCacheItem.mNavMeshRevision += removed;
|
||||||
|
return makeUpdateNavMeshStatus(removed, false);
|
||||||
incRev.mNavMeshChanged = removed;
|
};
|
||||||
|
|
||||||
if (!recastMesh)
|
if (!recastMesh)
|
||||||
{
|
{
|
||||||
log("ignore add tile: recastMesh is null");
|
log("ignore add tile: recastMesh is null");
|
||||||
return makeUpdateNavMeshStatus(removed, false);
|
return removeTile();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& boundsMin = recastMesh->getBoundsMin();
|
const auto& boundsMin = recastMesh->getBoundsMin();
|
||||||
@ -314,14 +294,14 @@ namespace DetourNavigator
|
|||||||
if (boundsMin == boundsMax)
|
if (boundsMin == boundsMax)
|
||||||
{
|
{
|
||||||
log("ignore add tile: recastMesh is empty");
|
log("ignore add tile: recastMesh is empty");
|
||||||
return makeUpdateNavMeshStatus(removed, false);
|
return removeTile();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto maxTiles = navMesh.lock()->getParams()->maxTiles;
|
const auto maxTiles = navMesh.lock()->getParams()->maxTiles;
|
||||||
if (!shouldAddTile(changedTile, playerTile, maxTiles))
|
if (!shouldAddTile(changedTile, playerTile, maxTiles))
|
||||||
{
|
{
|
||||||
log("ignore add tile: too far from player");
|
log("ignore add tile: too far from player");
|
||||||
return makeUpdateNavMeshStatus(removed, false);
|
return removeTile();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto tileBounds = makeTileBounds(settings, changedTile);
|
const auto tileBounds = makeTileBounds(settings, changedTile);
|
||||||
@ -334,17 +314,27 @@ namespace DetourNavigator
|
|||||||
if (!navMeshData.mValue)
|
if (!navMeshData.mValue)
|
||||||
{
|
{
|
||||||
log("ignore add tile: NavMeshData is null");
|
log("ignore add tile: NavMeshData is null");
|
||||||
return makeUpdateNavMeshStatus(removed, false);
|
return removeTile();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto status = navMesh.lock()->addTile(navMeshData.mValue.get(), navMeshData.mSize,
|
dtStatus addStatus;
|
||||||
DT_TILE_FREE_DATA, 0, 0);
|
bool removed;
|
||||||
if (dtStatusSucceed(status))
|
{
|
||||||
incRev.mNavMeshChanged = true;
|
const auto locked = navMesh.lock();
|
||||||
else
|
removed = dtStatusSucceed(locked->removeTile(locked->getTileRefAt(x, y, 0), nullptr, nullptr));
|
||||||
log("failed to add tile with status=", WriteDtStatus {status});
|
addStatus = locked->addTile(navMeshData.mValue.get(), navMeshData.mSize, DT_TILE_FREE_DATA, 0, 0);
|
||||||
navMeshData.mValue.release();
|
}
|
||||||
|
|
||||||
return makeUpdateNavMeshStatus(removed, dtStatusSucceed(status));
|
if (dtStatusSucceed(addStatus))
|
||||||
|
{
|
||||||
|
++navMeshCacheItem.mNavMeshRevision;
|
||||||
|
navMeshData.mValue.release();
|
||||||
|
return makeUpdateNavMeshStatus(removed, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log("failed to add tile with status=", WriteDtStatus {addStatus});
|
||||||
|
return makeUpdateNavMeshStatus(removed, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user