diff options
author | Shauren <shauren.trinity@gmail.com> | 2024-02-13 23:49:51 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2024-02-13 23:49:51 +0100 |
commit | 16f555f79ef2fdebd18204bc90383ad7761343a5 (patch) | |
tree | d1928466a7aa06ee093d6ac8d6190f88be484fb0 | |
parent | ca1560f043df275d9241055adbf61a393666a533 (diff) |
Core/MMAPs: Sprinkle master branch thread safety on mmap loading code
-rw-r--r-- | src/common/Collision/Management/MMapManager.cpp | 73 | ||||
-rw-r--r-- | src/common/Collision/Management/MMapManager.h | 5 | ||||
-rw-r--r-- | src/server/game/Maps/Map.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Movement/PathGenerator.cpp | 2 |
4 files changed, 49 insertions, 35 deletions
diff --git a/src/common/Collision/Management/MMapManager.cpp b/src/common/Collision/Management/MMapManager.cpp index 5ed38644fce..d16bfddc4cc 100644 --- a/src/common/Collision/Management/MMapManager.cpp +++ b/src/common/Collision/Management/MMapManager.cpp @@ -18,13 +18,12 @@ #include "MMapManager.h" #include "Errors.h" #include "Log.h" -#include "Config.h" #include "MapDefines.h" namespace MMAP { - constexpr char MAP_FILE_NAME_FORMAT[] = "{}/mmaps/{:03}.mmap"; - constexpr char TILE_FILE_NAME_FORMAT[] = "{}/mmaps/{:03}{:02}{:02}.mmtile"; + constexpr char MAP_FILE_NAME_FORMAT[] = "{}mmaps/{:03}.mmap"; + constexpr char TILE_FILE_NAME_FORMAT[] = "{}mmaps/{:03}{:02}{:02}.mmtile"; // ######################## MMapManager ######################## MMapManager::~MMapManager() @@ -55,7 +54,7 @@ namespace MMAP return itr; } - bool MMapManager::loadMapData(uint32 mapId) + bool MMapManager::loadMapData(std::string const& basePath, uint32 mapId) { // we already have this map loaded? MMapDataSet::iterator itr = loadedMMaps.find(mapId); @@ -73,7 +72,7 @@ namespace MMAP } // load and init dtNavMesh - read parameters from file - std::string fileName = Trinity::StringFormat(MAP_FILE_NAME_FORMAT, sConfigMgr->GetStringDefault("DataDir", "."), mapId); + std::string fileName = Trinity::StringFormat(MAP_FILE_NAME_FORMAT, basePath, mapId); FILE* file = fopen(fileName.c_str(), "rb"); if (!file) { @@ -113,10 +112,10 @@ namespace MMAP return uint32(x << 16 | y); } - bool MMapManager::loadMap(const std::string& /*basePath*/, uint32 mapId, int32 x, int32 y) + bool MMapManager::loadMap(std::string const& basePath, uint32 mapId, int32 x, int32 y) { // make sure the mmap is loaded and ready to load tiles - if (!loadMapData(mapId)) + if (!loadMapData(basePath, mapId)) return false; // get this mmap data @@ -129,7 +128,7 @@ namespace MMAP return false; // load this tile :: mmaps/MMMXXYY.mmtile - std::string fileName = Trinity::StringFormat(TILE_FILE_NAME_FORMAT, sConfigMgr->GetStringDefault("DataDir", "."), mapId, x, y); + std::string fileName = Trinity::StringFormat(TILE_FILE_NAME_FORMAT, basePath, mapId, x, y); FILE* file = fopen(fileName.c_str(), "rb"); if (!file) { @@ -197,6 +196,32 @@ namespace MMAP } } + bool MMapManager::loadMapInstance(std::string const& basePath, uint32 mapId, uint32 instanceId) + { + if (!loadMapData(basePath, mapId)) + return false; + + MMapData* mmap = loadedMMaps[mapId]; + auto [queryItr, inserted] = mmap->navMeshQueries.try_emplace(instanceId, nullptr); + if (!inserted) + return true; + + // allocate mesh query + dtNavMeshQuery* query = dtAllocNavMeshQuery(); + ASSERT(query); + if (dtStatusFailed(query->init(mmap->navMesh, 1024))) + { + dtFreeNavMeshQuery(query); + mmap->navMeshQueries.erase(queryItr); + TC_LOG_ERROR("maps", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId {:03} instanceId {}", mapId, instanceId); + return false; + } + + TC_LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId {:03} instanceId {}", mapId, instanceId); + queryItr->second = query; + return true; + } + bool MMapManager::unloadMap(uint32 mapId, int32 x, int32 y) { // check if we have this map loaded @@ -285,16 +310,15 @@ namespace MMAP } MMapData* mmap = itr->second; - if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end()) + auto queryItr = mmap->navMeshQueries.find(instanceId); + if (queryItr == mmap->navMeshQueries.end()) { TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId {:03} instanceId {}", mapId, instanceId); return false; } - dtNavMeshQuery* query = mmap->navMeshQueries[instanceId]; - - dtFreeNavMeshQuery(query); - mmap->navMeshQueries.erase(instanceId); + dtFreeNavMeshQuery(queryItr->second); + mmap->navMeshQueries.erase(queryItr); TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Unloaded mapId {:03} instanceId {}", mapId, instanceId); return true; @@ -311,27 +335,14 @@ namespace MMAP dtNavMeshQuery const* MMapManager::GetNavMeshQuery(uint32 mapId, uint32 instanceId) { - MMapDataSet::const_iterator itr = GetMMapData(mapId); + auto itr = GetMMapData(mapId); if (itr == loadedMMaps.end()) return nullptr; - MMapData* mmap = itr->second; - if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end()) - { - // allocate mesh query - dtNavMeshQuery* query = dtAllocNavMeshQuery(); - ASSERT(query); - if (dtStatusFailed(query->init(mmap->navMesh, 1024))) - { - dtFreeNavMeshQuery(query); - TC_LOG_ERROR("maps", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId {:03} instanceId {}", mapId, instanceId); - return nullptr; - } - - TC_LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId {:03} instanceId {}", mapId, instanceId); - mmap->navMeshQueries.insert(std::pair<uint32, dtNavMeshQuery*>(instanceId, query)); - } + auto queryItr = itr->second->navMeshQueries.find(instanceId); + if (queryItr == itr->second->navMeshQueries.end()) + return nullptr; - return mmap->navMeshQueries[instanceId]; + return queryItr->second; } } diff --git a/src/common/Collision/Management/MMapManager.h b/src/common/Collision/Management/MMapManager.h index bb787604ec0..29b9f69ffb0 100644 --- a/src/common/Collision/Management/MMapManager.h +++ b/src/common/Collision/Management/MMapManager.h @@ -62,7 +62,8 @@ namespace MMAP ~MMapManager(); void InitializeThreadUnsafe(const std::vector<uint32>& mapIds); - bool loadMap(const std::string& basePath, uint32 mapId, int32 x, int32 y); + bool loadMap(std::string const& basePath, uint32 mapId, int32 x, int32 y); + bool loadMapInstance(std::string const& basePath, uint32 mapId, uint32 instanceId); bool unloadMap(uint32 mapId, int32 x, int32 y); bool unloadMap(uint32 mapId); bool unloadMapInstance(uint32 mapId, uint32 instanceId); @@ -74,7 +75,7 @@ namespace MMAP uint32 getLoadedTilesCount() const { return loadedTiles; } uint32 getLoadedMapsCount() const { return uint32(loadedMMaps.size()); } private: - bool loadMapData(uint32 mapId); + bool loadMapData(std::string const& basePath, uint32 mapId); uint32 packTileID(int32 x, int32 y); MMapDataSet::const_iterator GetMMapData(uint32 mapId) const; diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 10d3f1df348..9072158689b 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -174,7 +174,7 @@ void Map::LoadMMap(int gx, int gy) if (!DisableMgr::IsPathfindingEnabled(GetId())) return; - bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gx, gy); + bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap(sWorld->GetDataPath(), GetId(), gx, gy); if (mmapLoadResult) TC_LOG_DEBUG("mmaps.tiles", "MMAP loaded name:{}, id:{}, x:{}, y:{} (mmap rep.: x:{}, y:{})", GetMapName(), GetId(), gx, gy, gx, gy); @@ -303,6 +303,8 @@ i_scriptLock(false), _respawnTimes(std::make_unique<RespawnListContainer>()), _r _weatherUpdateTimer.SetInterval(time_t(1 * IN_MILLISECONDS)); + MMAP::MMapFactory::createOrGetMMapManager()->loadMapInstance(sWorld->GetDataPath(), GetId(), GetInstanceId()); + sScriptMgr->OnCreateMap(this); } diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 1dd5364a390..08de2f4e12c 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -41,8 +41,8 @@ PathGenerator::PathGenerator(WorldObject const* owner) : if (DisableMgr::IsPathfindingEnabled(mapId)) { MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager(); - _navMesh = mmap->GetNavMesh(mapId); _navMeshQuery = mmap->GetNavMeshQuery(mapId, _source->GetInstanceId()); + _navMesh = _navMeshQuery ? _navMeshQuery->getAttachedNavMesh() : mmap->GetNavMesh(mapId); } CreateFilter(); |