From 171e6adf19b0bb96a317f60315a9efba9732b905 Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 4 Jan 2022 22:18:43 +0100 Subject: [PATCH] Tools/mmaps_generator: Made loading vmaps by mmaps_generator threadsafe --- src/tools/mmaps_generator/MapBuilder.cpp | 12 +++--- src/tools/mmaps_generator/PathCommon.h | 20 +++++++++ src/tools/mmaps_generator/PathGenerator.cpp | 45 +++++++++++++------- src/tools/mmaps_generator/TerrainBuilder.cpp | 8 ++-- 4 files changed, 61 insertions(+), 24 deletions(-) diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index ea27cbca759..6fc14a5d925 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -22,8 +22,6 @@ #include "PathCommon.h" #include "IntermediateValues.h" #include "StringFormat.h" -#include "VMapFactory.h" -#include "VMapManager2.h" #include #include #include @@ -451,9 +449,13 @@ namespace MMAP void MapBuilder::buildNavMesh(uint32 mapID, dtNavMesh* &navMesh) { // if map has a parent we use that to generate dtNavMeshParams - worldserver will load all missing tiles from that map - int32 navMeshParamsMapId = static_cast(VMapFactory::createOrGetVMapManager())->getParentMapId(mapID); - if (navMeshParamsMapId == -1) - navMeshParamsMapId = mapID; + int32 navMeshParamsMapId = mapID; + int32 parentMapId = sMapStore[mapID].ParentMapID; + while (parentMapId != -1) + { + navMeshParamsMapId = parentMapId; + parentMapId = sMapStore[parentMapId].ParentMapID; + } std::set* tiles = getTileList(navMeshParamsMapId); diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h index c6bb17a847f..03dd5b7e25d 100644 --- a/src/tools/mmaps_generator/PathCommon.h +++ b/src/tools/mmaps_generator/PathCommon.h @@ -31,6 +31,11 @@ #include #endif +namespace VMAP +{ + class VMapManager2; +} + namespace MMAP { inline bool matchWildcardFilter(char const* filter, char const* str) @@ -118,6 +123,21 @@ namespace MMAP return LISTFILE_OK; } + + struct MapEntry + { + uint8 MapType = 0; + int8 InstanceType = 0; + int16 ParentMapID = -1; + int32 Flags = 0; + }; + + extern std::unordered_map sMapStore; + + namespace VMapFactory + { + std::unique_ptr CreateVMapManager(); + } } #endif diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 78d5145f11e..03853c5c4ea 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -21,18 +21,38 @@ #include "MapBuilder.h" #include "Timer.h" #include "Util.h" -#include "VMapFactory.h" #include "VMapManager2.h" #include #include -using namespace MMAP; - namespace { std::unordered_map _liquidTypes; + std::unordered_map> _mapDataForVmapInitialization; } +namespace MMAP +{ + std::unordered_map sMapStore; + + namespace VMapFactory + { + std::unique_ptr CreateVMapManager() + { + std::unique_ptr vmgr = std::make_unique(); + vmgr->InitializeThreadUnsafe(_mapDataForVmapInitialization); + vmgr->GetLiquidFlagsPtr = [](uint32 liquidId) -> uint32 + { + auto itr = _liquidTypes.find(liquidId); + return itr != _liquidTypes.end() ? (1 << itr->second) : 0; + }; + return vmgr; + } + } +} + +using namespace MMAP; + bool checkDirectories(bool debugOutput, std::vector& dbcLocales) { if (getDirContents(dbcLocales, "dbc") == LISTFILE_DIRECTORY_NOT_FOUND || dbcLocales.empty()) @@ -310,6 +330,12 @@ std::unordered_map> LoadMap(std::string const& local int16 parentMapId = int16(record.getUInt(19)); if (parentMapId != -1) mapData[parentMapId].push_back(record.getUInt(0)); + + MapEntry& map = sMapStore[record.getUInt(0)]; + map.MapType = record.getUInt8(4); + map.InstanceType = record.getUInt8(2); + map.ParentMapID = parentMapId; + map.Flags = record.getInt(3); } } @@ -363,16 +389,7 @@ int main(int argc, char** argv) if (_liquidTypes.empty()) return silent ? -5 : finish("Failed to load LiquidType.dbc", -5); - std::unordered_map> mapData = LoadMap(dbcLocales[0]); - if (mapData.empty()) - return silent ? -4 : finish("Failed to load Map.dbc", -4); - - static_cast(VMAP::VMapFactory::createOrGetVMapManager())->InitializeThreadUnsafe(mapData); - static_cast(VMAP::VMapFactory::createOrGetVMapManager())->GetLiquidFlagsPtr = [](uint32 liquidId) -> uint32 - { - auto itr = _liquidTypes.find(liquidId); - return itr != _liquidTypes.end() ? (1 << itr->second) : 0; - }; + _mapDataForVmapInitialization = LoadMap(dbcLocales[0]); MapBuilder builder(maxAngle, maxAngleNotSteep, skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, debugOutput, bigBaseUnit, mapnum, offMeshInputPath); @@ -387,8 +404,6 @@ int main(int argc, char** argv) else builder.buildAllMaps(threads); - VMAP::VMapFactory::clear(); - if (!silent) printf("Finished. MMAPS were built in %s\n", secsToTimeString(GetMSTimeDiffToNow(start) / 1000).c_str()); return 0; diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index 598e9d35a9a..059fbaf2fd2 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -20,7 +20,6 @@ #include "MapDefines.h" #include "MapTree.h" #include "ModelInstance.h" -#include "VMapFactory.h" #include "VMapManager2.h" #include @@ -138,11 +137,12 @@ namespace MMAP FILE* mapFile = fopen(mapFileName, "rb"); if (!mapFile) { - int32 parentMapId = static_cast(VMapFactory::createOrGetVMapManager())->getParentMapId(mapID); - if (parentMapId != -1) + int32 parentMapId = sMapStore[mapID].ParentMapID; + while (!mapFile && parentMapId != -1) { sprintf(mapFileName, "maps/%03u%02u%02u.map", parentMapId, tileY, tileX); mapFile = fopen(mapFileName, "rb"); + parentMapId = sMapStore[parentMapId].ParentMapID; } } @@ -639,7 +639,7 @@ namespace MMAP /**************************************************************************/ bool TerrainBuilder::loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) { - VMapManager2* vmapManager = static_cast(VMapFactory::createOrGetVMapManager()); + std::unique_ptr vmapManager = VMapFactory::CreateVMapManager(); int result = vmapManager->loadSingleMap(mapID, "vmaps", tileX, tileY); bool retval = false;