AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
MMAP::MMapMgr Class Reference

#include "MMapMgr.h"

Public Member Functions

 MMapMgr ()=default
 
 ~MMapMgr ()
 
void InitializeThreadUnsafe (const std::vector< uint32 > &mapIds)
 
bool loadMap (uint32 mapId, int32 x, int32 y)
 
bool unloadMap (uint32 mapId, int32 x, int32 y)
 
bool unloadMap (uint32 mapId)
 
bool unloadMapInstance (uint32 mapId, uint32 instanceId)
 
dtNavMeshQuery const * GetNavMeshQuery (uint32 mapId, uint32 instanceId)
 
dtNavMesh const * GetNavMesh (uint32 mapId)
 
uint32 getLoadedTilesCount () const
 
uint32 getLoadedMapsCount () const
 

Private Member Functions

bool loadMapData (uint32 mapId)
 
uint32 packTileID (int32 x, int32 y)
 
MMapDataSet::const_iterator GetMMapData (uint32 mapId) const
 

Private Attributes

MMapDataSet loadedMMaps
 
uint32 loadedTiles {0}
 
bool thread_safe_environment {true}
 

Detailed Description

Constructor & Destructor Documentation

◆ MMapMgr()

MMAP::MMapMgr::MMapMgr ( )
default

◆ ~MMapMgr()

MMAP::MMapMgr::~MMapMgr ( )
28 {
29 for (MMapDataSet::iterator i = loadedMMaps.begin(); i != loadedMMaps.end(); ++i)
30 {
31 delete i->second;
32 }
33
34 // by now we should not have maps loaded
35 // if we had, tiles in MMapData->mmapLoadedTiles, their actual data is lost!
36 }
MMapDataSet loadedMMaps
Definition MMapMgr.h:100

References loadedMMaps.

Member Function Documentation

◆ getLoadedMapsCount()

uint32 MMAP::MMapMgr::getLoadedMapsCount ( ) const
inline
93{ return loadedMMaps.size(); }

References loadedMMaps.

Referenced by mmaps_commandscript::HandleMmapStatsCommand().

◆ getLoadedTilesCount()

uint32 MMAP::MMapMgr::getLoadedTilesCount ( ) const
inline
92{ return loadedTiles; }
uint32 loadedTiles
Definition MMapMgr.h:101

References loadedTiles.

Referenced by mmaps_commandscript::HandleMmapStatsCommand().

◆ GetMMapData()

MMapDataSet::const_iterator MMAP::MMapMgr::GetMMapData ( uint32  mapId) const
private
50 {
51 // return the iterator if found or end() if not found/NULL
52 MMapDataSet::const_iterator itr = loadedMMaps.find(mapId);
53 if (itr != loadedMMaps.cend() && !itr->second)
54 {
55 itr = loadedMMaps.cend();
56 }
57
58 return itr;
59 }

References loadedMMaps.

Referenced by GetNavMesh(), GetNavMeshQuery(), unloadMap(), and unloadMapInstance().

◆ GetNavMesh()

dtNavMesh const * MMAP::MMapMgr::GetNavMesh ( uint32  mapId)
304 {
305 MMapDataSet::const_iterator itr = GetMMapData(mapId);
306 if (itr == loadedMMaps.end())
307 {
308 return nullptr;
309 }
310
311 return itr->second->navMesh;
312 }
MMapDataSet::const_iterator GetMMapData(uint32 mapId) const
Definition MMapMgr.cpp:49

References GetMMapData(), and loadedMMaps.

Referenced by misc_commandscript::HandleGPSCommand(), mmaps_commandscript::HandleMmapLoadedTilesCommand(), mmaps_commandscript::HandleMmapLocCommand(), mmaps_commandscript::HandleMmapStatsCommand(), and PathGenerator::PathGenerator().

◆ GetNavMeshQuery()

dtNavMeshQuery const * MMAP::MMapMgr::GetNavMeshQuery ( uint32  mapId,
uint32  instanceId 
)
315 {
316 MMapDataSet::const_iterator itr = GetMMapData(mapId);
317 if (itr == loadedMMaps.end())
318 {
319 return nullptr;
320 }
321
322 MMapData* mmap = itr->second;
323 if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
324 {
325 // check again after acquiring mutex
326 if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
327 {
328 // allocate mesh query
329 dtNavMeshQuery* query = dtAllocNavMeshQuery();
330 ASSERT(query);
331
332 if (dtStatusFailed(query->init(mmap->navMesh, 1024)))
333 {
334 dtFreeNavMeshQuery(query);
335 LOG_ERROR("maps", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId {:03} instanceId {}", mapId, instanceId);
336 return nullptr;
337 }
338
339 LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId {:03} instanceId {}", mapId, instanceId);
340 mmap->navMeshQueries.insert(std::pair<uint32, dtNavMeshQuery*>(instanceId, query));
341 }
342 }
343
344 return mmap->navMeshQueries[instanceId];
345 }
#define ASSERT
Definition Errors.h:68
#define LOG_ERROR(filterType__,...)
Definition Log.h:158
#define LOG_DEBUG(filterType__,...)
Definition Log.h:170

References ASSERT, GetMMapData(), loadedMMaps, LOG_DEBUG, LOG_ERROR, MMAP::MMapData::navMesh, and MMAP::MMapData::navMeshQueries.

Referenced by mmaps_commandscript::HandleMmapLoadedTilesCommand(), mmaps_commandscript::HandleMmapLocCommand(), and PathGenerator::PathGenerator().

◆ InitializeThreadUnsafe()

void MMAP::MMapMgr::InitializeThreadUnsafe ( const std::vector< uint32 > &  mapIds)
39 {
40 // the caller must pass the list of all mapIds that will be used in the VMapMgr2 lifetime
41 for (const uint32& mapId : mapIds)
42 {
43 loadedMMaps.emplace(mapId, nullptr);
44 }
45
47 }
std::uint32_t uint32
Definition Define.h:107
bool thread_safe_environment
Definition MMapMgr.h:102

References loadedMMaps, and thread_safe_environment.

Referenced by World::SetInitialWorldSettings().

◆ loadMap()

bool MMAP::MMapMgr::loadMap ( uint32  mapId,
int32  x,
int32  y 
)
126 {
127 // make sure the mmap is loaded and ready to load tiles
128 if (!loadMapData(mapId))
129 {
130 return false;
131 }
132
133 // get this mmap data
134 MMapData* mmap = loadedMMaps[mapId];
135 ASSERT(mmap->navMesh);
136
137 // check if we already have this tile loaded
138 uint32 packedGridPos = packTileID(x, y);
139 if (mmap->loadedTileRefs.find(packedGridPos) != mmap->loadedTileRefs.end())
140 {
141 LOG_ERROR("maps", "MMAP:loadMap: Asked to load already loaded navmesh tile. {:03}{:02}{:02}.mmtile", mapId, x, y);
142 return false;
143 }
144
145 // load this tile :: mmaps/MMMXXYY.mmtile
146 std::string fileName = Acore::StringFormat(TILE_FILE_NAME_FORMAT, sConfigMgr->GetOption<std::string>("DataDir", "."), mapId, x, y);
147 FILE* file = fopen(fileName.c_str(), "rb");
148 if (!file)
149 {
150 LOG_DEBUG("maps", "MMAP:loadMap: Could not open mmtile file '{}'", fileName);
151 return false;
152 }
153
154 // read header
155 MmapTileHeader fileHeader;
156 if (fread(&fileHeader, sizeof(MmapTileHeader), 1, file) != 1 || fileHeader.mmapMagic != MMAP_MAGIC)
157 {
158 LOG_ERROR("maps", "MMAP:loadMap: Bad header in mmap {:03}{:02}{:02}.mmtile", mapId, x, y);
159 fclose(file);
160 return false;
161 }
162
163 if (fileHeader.mmapVersion != MMAP_VERSION)
164 {
165 LOG_ERROR("maps", "MMAP:loadMap: {:03}{:02}{:02}.mmtile was built with generator v{}, expected v{}",
166 mapId, x, y, fileHeader.mmapVersion, MMAP_VERSION);
167 fclose(file);
168 return false;
169 }
170
171 unsigned char* data = (unsigned char*)dtAlloc(fileHeader.size, DT_ALLOC_PERM);
172 ASSERT(data);
173
174 std::size_t result = fread(data, fileHeader.size, 1, file);
175 if (!result)
176 {
177 LOG_ERROR("maps", "MMAP:loadMap: Bad header or data in mmap {:03}{:02}{:02}.mmtile", mapId, x, y);
178 fclose(file);
179 return false;
180 }
181
182 fclose(file);
183
184 dtTileRef tileRef = 0;
185
186 // memory allocated for data is now managed by detour, and will be deallocated when the tile is removed
187 if (dtStatusSucceed(mmap->navMesh->addTile(data, fileHeader.size, DT_TILE_FREE_DATA, 0, &tileRef)))
188 {
189 mmap->loadedTileRefs.insert(std::pair<uint32, dtTileRef>(packedGridPos, tileRef));
190 ++loadedTiles;
191 dtMeshHeader* header = (dtMeshHeader*)data;
192 LOG_DEBUG("maps", "MMAP:loadMap: Loaded mmtile {:03}[{:02},{:02}] into {:03}[{:02},{:02}]", mapId, x, y, mapId, header->x, header->y);
193 return true;
194 }
195
196 LOG_ERROR("maps", "MMAP:loadMap: Could not load {:03}{:02}{:02}.mmtile into navmesh", mapId, x, y);
197 dtFree(data);
198 return false;
199 }
#define MMAP_VERSION
Definition MapDefines.h:29
#define MMAP_MAGIC
Definition MapDefines.h:28
bool loadMapData(uint32 mapId)
Definition MMapMgr.cpp:61
uint32 packTileID(int32 x, int32 y)
Definition MMapMgr.cpp:120
#define sConfigMgr
Definition Config.h:93
std::string StringFormat(FormatString< Args... > fmt, Args &&... args)
Default AC string format function.
Definition StringFormat.h:34
static char const *const TILE_FILE_NAME_FORMAT
Definition MMapMgr.h:43
Definition MapDefines.h:65
uint32 mmapVersion
Definition MapDefines.h:68
uint32 size
Definition MapDefines.h:69
uint32 mmapMagic
Definition MapDefines.h:66

References ASSERT, loadedMMaps, MMAP::MMapData::loadedTileRefs, loadedTiles, loadMapData(), LOG_DEBUG, LOG_ERROR, MMAP_MAGIC, MMAP_VERSION, MmapTileHeader::mmapMagic, MmapTileHeader::mmapVersion, MMAP::MMapData::navMesh, packTileID(), sConfigMgr, MmapTileHeader::size, Acore::StringFormat(), and MMAP::TILE_FILE_NAME_FORMAT.

Referenced by GridTerrainLoader::LoadMMap().

◆ loadMapData()

bool MMAP::MMapMgr::loadMapData ( uint32  mapId)
private
62 {
63 // we already have this map loaded?
64 MMapDataSet::iterator itr = loadedMMaps.find(mapId);
65 if (itr != loadedMMaps.end())
66 {
67 if (itr->second)
68 {
69 return true;
70 }
71 }
72 else
73 {
75 {
76 itr = loadedMMaps.insert(MMapDataSet::value_type(mapId, nullptr)).first;
77 }
78 else
79 {
80 ABORT("Invalid mapId {} passed to MMapMgr after startup in thread unsafe environment", mapId);
81 }
82 }
83
84 // load and init dtNavMesh - read parameters from file
85 std::string fileName = Acore::StringFormat(MAP_FILE_NAME_FORMAT, sConfigMgr->GetOption<std::string>("DataDir", "."), mapId);
86
87 FILE* file = fopen(fileName.c_str(), "rb");
88 if (!file)
89 {
90 LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not open mmap file '{}'", fileName);
91 return false;
92 }
93
94 dtNavMeshParams params;
95 uint32 count = uint32(fread(&params, sizeof(dtNavMeshParams), 1, file));
96 fclose(file);
97 if (count != 1)
98 {
99 LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not read params from file '{}'", fileName);
100 return false;
101 }
102
103 dtNavMesh* mesh = dtAllocNavMesh();
104 ASSERT(mesh);
105 if (DT_SUCCESS != mesh->init(&params))
106 {
107 dtFreeNavMesh(mesh);
108 LOG_ERROR("maps", "MMAP:loadMapData: Failed to initialize dtNavMesh for mmap {:03} from file {}", mapId, fileName);
109 return false;
110 }
111
112 LOG_DEBUG("maps", "MMAP:loadMapData: Loaded {:03}.mmap", mapId);
113
114 // store inside our map list
115 MMapData* mmap_data = new MMapData(mesh);
116 itr->second = mmap_data;
117 return true;
118 }
#define ABORT
Definition Errors.h:76
static char const *const MAP_FILE_NAME_FORMAT
Definition MMapMgr.h:42

References ABORT, ASSERT, loadedMMaps, LOG_DEBUG, LOG_ERROR, MMAP::MAP_FILE_NAME_FORMAT, sConfigMgr, Acore::StringFormat(), and thread_safe_environment.

Referenced by loadMap().

◆ packTileID()

uint32 MMAP::MMapMgr::packTileID ( int32  x,
int32  y 
)
private
121 {
122 return uint32(x << 16 | y);
123 }

Referenced by loadMap(), and unloadMap().

◆ unloadMap() [1/2]

bool MMAP::MMapMgr::unloadMap ( uint32  mapId)
242 {
243 MMapDataSet::iterator itr = loadedMMaps.find(mapId);
244 if (itr == loadedMMaps.end() || !itr->second)
245 {
246 // file may not exist, therefore not loaded
247 LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map {:03}", mapId);
248 return false;
249 }
250
251 // unload all tiles from given map
252 MMapData* mmap = itr->second;
253 for (auto& i : mmap->loadedTileRefs)
254 {
255 uint32 x = (i.first >> 16);
256 uint32 y = (i.first & 0x0000FFFF);
257
258 if (dtStatusFailed(mmap->navMesh->removeTile(i.second, nullptr, nullptr)))
259 {
260 LOG_ERROR("maps", "MMAP:unloadMap: Could not unload {:03}{:02}{:02}.mmtile from navmesh", mapId, x, y);
261 }
262 else
263 {
264 --loadedTiles;
265 LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile {:03}[{:02},{:02}] from {:03}", mapId, x, y, mapId);
266 }
267 }
268
269 delete mmap;
270 itr->second = nullptr;
271 LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded {:03}.mmap", mapId);
272
273 return true;
274 }

References loadedMMaps, MMAP::MMapData::loadedTileRefs, loadedTiles, LOG_DEBUG, LOG_ERROR, and MMAP::MMapData::navMesh.

◆ unloadMap() [2/2]

bool MMAP::MMapMgr::unloadMap ( uint32  mapId,
int32  x,
int32  y 
)
202 {
203 // check if we have this map loaded
204 MMapDataSet::const_iterator itr = GetMMapData(mapId);
205 if (itr == loadedMMaps.end())
206 {
207 // file may not exist, therefore not loaded
208 LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map. {:03}{:02}{:02}.mmtile", mapId, x, y);
209 return false;
210 }
211
212 MMapData* mmap = itr->second;
213
214 // check if we have this tile loaded
215 uint32 packedGridPos = packTileID(x, y);
216 if (mmap->loadedTileRefs.find(packedGridPos) == mmap->loadedTileRefs.end())
217 {
218 // file may not exist, therefore not loaded
219 LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh tile. {:03}{:02}{:02}.mmtile", mapId, x, y);
220 return false;
221 }
222
223 dtTileRef tileRef = mmap->loadedTileRefs[packedGridPos];
224
225 // unload, and mark as non loaded
226 if (dtStatusFailed(mmap->navMesh->removeTile(tileRef, nullptr, nullptr)))
227 {
228 // this is technically a memory leak
229 // if the grid is later reloaded, dtNavMesh::addTile will return error but no extra memory is used
230 // we cannot recover from this error - assert out
231 LOG_ERROR("maps", "MMAP:unloadMap: Could not unload {:03}{:02}{:02}.mmtile from navmesh", mapId, x, y);
232 ABORT();
233 }
234
235 mmap->loadedTileRefs.erase(packedGridPos);
236 --loadedTiles;
237 LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile {:03}[{:02},{:02}] from {:03}", mapId, x, y, mapId);
238 return true;
239 }

References ABORT, GetMMapData(), loadedMMaps, MMAP::MMapData::loadedTileRefs, loadedTiles, LOG_DEBUG, LOG_ERROR, MMAP::MMapData::navMesh, and packTileID().

Referenced by GridTerrainUnloader::UnloadTerrain().

◆ unloadMapInstance()

bool MMAP::MMapMgr::unloadMapInstance ( uint32  mapId,
uint32  instanceId 
)
277 {
278 // check if we have this map loaded
279 MMapDataSet::const_iterator itr = GetMMapData(mapId);
280 if (itr == loadedMMaps.end())
281 {
282 // file may not exist, therefore not loaded
283 LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded navmesh map {:03}", mapId);
284 return false;
285 }
286
287 MMapData* mmap = itr->second;
288 if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
289 {
290 LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId {:03} instanceId {}", mapId, instanceId);
291 return false;
292 }
293
294 dtNavMeshQuery* query = mmap->navMeshQueries[instanceId];
295
296 dtFreeNavMeshQuery(query);
297 mmap->navMeshQueries.erase(instanceId);
298 LOG_DEBUG("maps", "MMAP:unloadMapInstance: Unloaded mapId {:03} instanceId {}", mapId, instanceId);
299
300 return true;
301 }

References GetMMapData(), loadedMMaps, LOG_DEBUG, and MMAP::MMapData::navMeshQueries.

Referenced by Map::~Map().

Member Data Documentation

◆ loadedMMaps

◆ loadedTiles

uint32 MMAP::MMapMgr::loadedTiles {0}
private
101{0};

Referenced by getLoadedTilesCount(), loadMap(), unloadMap(), and unloadMap().

◆ thread_safe_environment

bool MMAP::MMapMgr::thread_safe_environment {true}
private
102{true};

Referenced by InitializeThreadUnsafe(), and loadMapData().


The documentation for this class was generated from the following files: