Skip to content

Instantly share code, notes, and snippets.

@sixsixnine
Created January 25, 2012 20:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sixsixnine/1678609 to your computer and use it in GitHub Desktop.
Save sixsixnine/1678609 to your computer and use it in GitHub Desktop.
diff --git a/src/game/MoveMap.cpp b/src/game/MoveMap.cpp
index 6323125..bf1ce38 100644
--- a/src/game/MoveMap.cpp
+++ b/src/game/MoveMap.cpp
@@ -205,8 +205,12 @@ namespace MMAP
dtMeshHeader* header = (dtMeshHeader*)data;
dtTileRef tileRef = 0;
+ mmap->navMeshLock.acquire_write();
+ dtStatus stat = mmap->navMesh->addTile(data, fileHeader.size, DT_TILE_FREE_DATA, 0, &tileRef);
+ mmap->navMeshLock.release();
+
// memory allocated for data is now managed by detour, and will be deallocated when the tile is removed
- if(DT_SUCCESS == mmap->navMesh->addTile(data, fileHeader.size, DT_TILE_FREE_DATA, 0, &tileRef))
+ if(DT_SUCCESS == stat)
{
mmap->mmapLoadedTiles.insert(std::pair<uint32, dtTileRef>(packedGridPos, tileRef));
++loadedTiles;
@@ -246,8 +250,12 @@ namespace MMAP
dtTileRef tileRef = mmap->mmapLoadedTiles[packedGridPos];
+ mmap->navMeshLock.acquire_write();
+ dtStatus stat = mmap->navMesh->removeTile(tileRef, NULL, NULL);
+ mmap->navMeshLock.release();
+
// unload, and mark as non loaded
- if(DT_SUCCESS != mmap->navMesh->removeTile(tileRef, NULL, NULL))
+ if(DT_SUCCESS != stat)
{
// this is technically a memory leak
// if the grid is later reloaded, dtNavMesh::addTile will return error but no extra memory is used
@@ -281,7 +289,12 @@ namespace MMAP
{
uint32 x = (i->first >> 16);
uint32 y = (i->first & 0x0000FFFF);
- if(DT_SUCCESS != mmap->navMesh->removeTile(i->second, NULL, NULL))
+
+ mmap->navMeshLock.acquire_write();
+ dtStatus stat = mmap->navMesh->removeTile(i->second, NULL, NULL);
+ mmap->navMeshLock.release();
+
+ if(DT_SUCCESS != stat)
sLog.outError("MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, x, y);
else
{
@@ -331,6 +344,14 @@ namespace MMAP
return loadedMMaps[mapId]->navMesh;
}
+ ACE_RW_Mutex* MMapManager::GetNavMeshLock(uint32 mapId)
+ {
+ if (loadedMMaps.find(mapId) == loadedMMaps.end())
+ return NULL;
+
+ return &loadedMMaps[mapId]->navMeshLock;
+ }
+
dtNavMeshQuery const* MMapManager::GetNavMeshQuery(uint32 mapId, uint32 instanceId)
{
if (loadedMMaps.find(mapId) == loadedMMaps.end())
diff --git a/src/game/MoveMap.h b/src/game/MoveMap.h
index 58cac34..f93c88c 100644
--- a/src/game/MoveMap.h
+++ b/src/game/MoveMap.h
@@ -20,6 +20,7 @@
#define _MOVE_MAP_H
#include "Utilities/UnorderedMapSet.h"
+#include <ace/RW_Mutex.h>
#include "../../dep/recastnavigation/Detour/Include/DetourAlloc.h"
#include "../../dep/recastnavigation/Detour/Include/DetourNavMesh.h"
@@ -56,6 +57,7 @@ namespace MMAP
}
dtNavMesh* navMesh;
+ ACE_RW_Mutex navMeshLock;
// we have to use single dtNavMeshQuery for every instance, since those are not thread safe
NavMeshQuerySet navMeshQueries; // instanceId to query
@@ -81,6 +83,7 @@ namespace MMAP
// the returned [dtNavMeshQuery const*] is NOT threadsafe
dtNavMeshQuery const* GetNavMeshQuery(uint32 mapId, uint32 instanceId);
dtNavMesh const* GetNavMesh(uint32 mapId);
+ ACE_RW_Mutex* GetNavMeshLock(uint32 mapId);
uint32 getLoadedTilesCount() const { return loadedTiles; }
uint32 getLoadedMapsCount() const { return loadedMMaps.size(); }
diff --git a/src/game/PathFinder.cpp b/src/game/PathFinder.cpp
index 0735674..57f3d70 100644
--- a/src/game/PathFinder.cpp
+++ b/src/game/PathFinder.cpp
@@ -28,7 +28,7 @@
PathFinder::PathFinder(const Unit* owner) :
m_polyLength(0), m_type(PATHFIND_BLANK),
m_useStraightPath(false), m_forceDestination(false), m_pointPathLimit(MAX_POINT_PATH_LENGTH),
- m_sourceUnit(owner), m_navMesh(NULL), m_navMeshQuery(NULL)
+ m_sourceUnit(owner), m_navMesh(NULL),m_navMeshLock(NULL), m_navMeshQuery(NULL)
{
DEBUG_FILTER_LOG(LOG_FILTER_PATHFINDING, "++ PathFinder::PathInfo for %u \n", m_sourceUnit->GetGUIDLow());
@@ -37,6 +37,7 @@ PathFinder::PathFinder(const Unit* owner) :
{
MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager();
m_navMesh = mmap->GetNavMesh(mapId);
+ m_navMeshLock = mmap->GetNavMeshLock(mapId);
m_navMeshQuery = mmap->GetNavMeshQuery(mapId, m_sourceUnit->GetInstanceId());
}
@@ -90,7 +91,9 @@ bool PathFinder::calculate(float destX, float destY, float destZ, bool forceDest
else
{
// target moved, so we need to update the poly path
+ m_navMeshLock->acquire_read();
BuildPolyPath(start, dest);
+ m_navMeshLock->release();
return true;
}
}
diff --git a/src/game/PathFinder.h b/src/game/PathFinder.h
index e2c38a6..e4627ab 100644
--- a/src/game/PathFinder.h
+++ b/src/game/PathFinder.h
@@ -19,6 +19,8 @@
#ifndef MANGOS_PATH_FINDER_H
#define MANGOS_PATH_FINDER_H
+#include <ace/RW_Mutex.h>
+
#include "MoveMapSharedDefines.h"
#include "../recastnavigation/Detour/Include/DetourNavMesh.h"
#include "../recastnavigation/Detour/Include/DetourNavMeshQuery.h"
@@ -92,6 +94,7 @@ class PathFinder
const Unit* const m_sourceUnit; // the unit that is moving
const dtNavMesh* m_navMesh; // the nav mesh
+ ACE_RW_Mutex* m_navMeshLock;
const dtNavMeshQuery* m_navMeshQuery; // the nav mesh query used to find the path
dtQueryFilter m_filter; // use single filter for all movements, update it when needed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment