mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-27 15:46:24 +00:00
feat(Core/Common): delete lib game-interface inherited (#5333)
Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com>
This commit is contained in:
@@ -35,4 +35,4 @@ namespace MMAP
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -18,7 +18,6 @@ This is the minimum interface to the VMapMamager.
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
|
||||
enum VMAP_LOAD_RESULT
|
||||
{
|
||||
VMAP_LOAD_RESULT_ERROR,
|
||||
@@ -83,6 +82,6 @@ namespace VMAP
|
||||
virtual bool getAreaInfo(unsigned int pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const = 0;
|
||||
virtual bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float& level, float& floor, uint32& type) const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
|
||||
#include "MMapFactory.h"
|
||||
#include "World.h"
|
||||
#include <set>
|
||||
|
||||
namespace MMAP
|
||||
@@ -23,12 +22,6 @@ namespace MMAP
|
||||
return g_MMapManager;
|
||||
}
|
||||
|
||||
bool MMapFactory::IsPathfindingEnabled(const Map* map)
|
||||
{
|
||||
if (!map) return false;
|
||||
return !forbiddenMaps[map->GetId()] && (sWorld->getBoolConfig(CONFIG_ENABLE_MMAPS) ? true : map->IsBattlegroundOrArena());
|
||||
}
|
||||
|
||||
void MMapFactory::InitializeDisabledMaps()
|
||||
{
|
||||
memset(&forbiddenMaps, 0, sizeof(forbiddenMaps));
|
||||
@@ -46,4 +39,4 @@ namespace MMAP
|
||||
g_MMapManager = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,7 @@
|
||||
#include "MMapManager.h"
|
||||
#include "DetourAlloc.h"
|
||||
#include "DetourNavMesh.h"
|
||||
#include "Navigation/DetourExtended.h"
|
||||
#include "Map.h"
|
||||
#include "DetourExtended.h"
|
||||
#include <unordered_map>
|
||||
|
||||
namespace MMAP
|
||||
@@ -31,7 +30,6 @@ namespace MMAP
|
||||
public:
|
||||
static MMapManager* createOrGetMMapManager();
|
||||
static void clear();
|
||||
static bool IsPathfindingEnabled(const Map* map);
|
||||
static void InitializeDisabledMaps();
|
||||
static bool forbiddenMaps[1000];
|
||||
};
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*/
|
||||
|
||||
#include "Config.h"
|
||||
#include "MapManager.h"
|
||||
#include "MMapManager.h"
|
||||
#include "Config.h"
|
||||
#include "Errors.h"
|
||||
#include "MapDefines.h"
|
||||
#include "Log.h"
|
||||
#include "StringFormat.h"
|
||||
|
||||
@@ -25,11 +26,41 @@ namespace MMAP
|
||||
// if we had, tiles in MMapData->mmapLoadedTiles, their actual data is lost!
|
||||
}
|
||||
|
||||
void MMapManager::InitializeThreadUnsafe(const std::vector<uint32>& mapIds)
|
||||
{
|
||||
// the caller must pass the list of all mapIds that will be used in the VMapManager2 lifetime
|
||||
for (const uint32& mapId : mapIds)
|
||||
loadedMMaps.emplace(mapId, nullptr);
|
||||
|
||||
thread_safe_environment = false;
|
||||
}
|
||||
|
||||
MMapDataSet::const_iterator MMapManager::GetMMapData(uint32 mapId) const
|
||||
{
|
||||
// return the iterator if found or end() if not found/NULL
|
||||
MMapDataSet::const_iterator itr = loadedMMaps.find(mapId);
|
||||
if (itr != loadedMMaps.cend() && !itr->second)
|
||||
itr = loadedMMaps.cend();
|
||||
|
||||
return itr;
|
||||
}
|
||||
|
||||
bool MMapManager::loadMapData(uint32 mapId)
|
||||
{
|
||||
// we already have this map loaded?
|
||||
if (loadedMMaps.find(mapId) != loadedMMaps.end())
|
||||
return true;
|
||||
MMapDataSet::iterator itr = loadedMMaps.find(mapId);
|
||||
if (itr != loadedMMaps.end())
|
||||
{
|
||||
if (itr->second)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (thread_safe_environment)
|
||||
itr = loadedMMaps.insert(MMapDataSet::value_type(mapId, nullptr)).first;
|
||||
else
|
||||
ASSERT(false, "Invalid mapId %u passed to MMapManager after startup in thread unsafe environment", mapId);
|
||||
}
|
||||
|
||||
// load and init dtNavMesh - read parameters from file
|
||||
std::string fileName = acore::StringFormat(MAP_FILE_NAME_FORMAT, sConfigMgr->GetOption<std::string>("DataDir", ".").c_str(), mapId);
|
||||
@@ -37,18 +68,16 @@ namespace MMAP
|
||||
FILE* file = fopen(fileName.c_str(), "rb");
|
||||
if (!file)
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not open mmap file '%s'", fileName.c_str());
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
dtNavMeshParams params;
|
||||
int count = fread(¶ms, sizeof(dtNavMeshParams), 1, file);
|
||||
uint32 count = uint32(fread(¶ms, sizeof(dtNavMeshParams), 1, file));
|
||||
fclose(file);
|
||||
if (count != 1)
|
||||
{
|
||||
;//TC_LOG_DEBUG(LOG_FILTER_MAPS, "MMAP:loadMapData: Error: Could not read params from file '%s'", fileName);
|
||||
LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not read params from file '%s'", fileName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -61,15 +90,11 @@ namespace MMAP
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
LOG_DEBUG("server", "MMAP:loadMapData: Loaded %03i.mmap", mapId);
|
||||
#endif
|
||||
LOG_DEBUG("maps", "MMAP:loadMapData: Loaded %03i.mmap", mapId);
|
||||
|
||||
// store inside our map list
|
||||
MMapData* mmap_data = new MMapData(mesh);
|
||||
mmap_data->mmapLoadedTiles.clear();
|
||||
|
||||
loadedMMaps.insert(std::pair<uint32, MMapData*>(mapId, mmap_data));
|
||||
itr->second = mmap_data;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -78,22 +103,8 @@ namespace MMAP
|
||||
return uint32(x << 16 | y);
|
||||
}
|
||||
|
||||
std::shared_mutex& MMapManager::GetMMapLock(uint32 mapId)
|
||||
{
|
||||
Map* map = sMapMgr->FindBaseMap(mapId);
|
||||
if (!map)
|
||||
{
|
||||
LOG_INFO("misc", "ZOMG! MoveMaps: BaseMap not found!");
|
||||
return this->MMapLock;
|
||||
}
|
||||
|
||||
return map->GetMMapLock();
|
||||
}
|
||||
|
||||
bool MMapManager::loadMap(uint32 mapId, int32 x, int32 y)
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> guard(MMapManagerLock);
|
||||
|
||||
// make sure the mmap is loaded and ready to load tiles
|
||||
if (!loadMapData(mapId))
|
||||
return false;
|
||||
@@ -104,7 +115,7 @@ namespace MMAP
|
||||
|
||||
// check if we already have this tile loaded
|
||||
uint32 packedGridPos = packTileID(x, y);
|
||||
if (mmap->mmapLoadedTiles.find(packedGridPos) != mmap->mmapLoadedTiles.end())
|
||||
if (mmap->loadedTileRefs.find(packedGridPos) != mmap->loadedTileRefs.end())
|
||||
{
|
||||
LOG_ERROR("server", "MMAP:loadMap: Asked to load already loaded navmesh tile. %03u%02i%02i.mmtile", mapId, x, y);
|
||||
return false;
|
||||
@@ -151,26 +162,18 @@ namespace MMAP
|
||||
|
||||
dtTileRef tileRef = 0;
|
||||
|
||||
dtStatus stat;
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> guard(GetMMapLock(mapId));
|
||||
stat = mmap->navMesh->addTile(data, fileHeader.size, DT_TILE_FREE_DATA, 0, &tileRef);
|
||||
}
|
||||
|
||||
// memory allocated for data is now managed by detour, and will be deallocated when the tile is removed
|
||||
if (stat == DT_SUCCESS)
|
||||
if (dtStatusSucceed(mmap->navMesh->addTile(data, fileHeader.size, DT_TILE_FREE_DATA, 0, &tileRef)))
|
||||
{
|
||||
mmap->mmapLoadedTiles.insert(std::pair<uint32, dtTileRef>(packedGridPos, tileRef));
|
||||
mmap->loadedTileRefs.insert(std::pair<uint32, dtTileRef>(packedGridPos, tileRef));
|
||||
++loadedTiles;
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
dtMeshHeader* header = (dtMeshHeader*)data;
|
||||
LOG_DEBUG("server", "MMAP:loadMap: Loaded mmtile %03i[%02i,%02i] into %03i[%02i,%02i]", mapId, x, y, mapId, header->x, header->y);
|
||||
#endif
|
||||
LOG_DEBUG("maps", "MMAP:loadMap: Loaded mmtile %03i[%02i,%02i] into %03i[%02i,%02i]", mapId, x, y, mapId, header->x, header->y);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("server", "MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, x, y);
|
||||
LOG_ERROR("maps", "MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, x, y);
|
||||
dtFree(data);
|
||||
return false;
|
||||
}
|
||||
@@ -180,10 +183,9 @@ namespace MMAP
|
||||
|
||||
bool MMapManager::unloadMap(uint32 mapId, int32 x, int32 y)
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> guard(MMapManagerLock);
|
||||
|
||||
// check if we have this map loaded
|
||||
if (loadedMMaps.find(mapId) == loadedMMaps.end())
|
||||
MMapDataSet::const_iterator itr = GetMMapData(mapId);
|
||||
if (itr == loadedMMaps.end())
|
||||
{
|
||||
// file may not exist, therefore not loaded
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
@@ -192,11 +194,11 @@ namespace MMAP
|
||||
return false;
|
||||
}
|
||||
|
||||
MMapData* mmap = loadedMMaps[mapId];
|
||||
MMapData* mmap = itr->second;
|
||||
|
||||
// check if we have this tile loaded
|
||||
uint32 packedGridPos = packTileID(x, y);
|
||||
if (mmap->mmapLoadedTiles.find(packedGridPos) == mmap->mmapLoadedTiles.end())
|
||||
if (mmap->loadedTileRefs.find(packedGridPos) == mmap->loadedTileRefs.end())
|
||||
{
|
||||
// file may not exist, therefore not loaded
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
@@ -205,16 +207,10 @@ namespace MMAP
|
||||
return false;
|
||||
}
|
||||
|
||||
dtTileRef tileRef = mmap->mmapLoadedTiles[packedGridPos];
|
||||
|
||||
dtStatus status;
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> guard(GetMMapLock(mapId));
|
||||
status = mmap->navMesh->removeTile(tileRef, nullptr, nullptr);
|
||||
}
|
||||
dtTileRef tileRef = mmap->loadedTileRefs[packedGridPos];
|
||||
|
||||
// unload, and mark as non loaded
|
||||
if (status != DT_SUCCESS)
|
||||
if (dtStatusFailed(mmap->navMesh->removeTile(tileRef, nullptr, nullptr)))
|
||||
{
|
||||
// this is technically a memory leak
|
||||
// if the grid is later reloaded, dtNavMesh::addTile will return error but no extra memory is used
|
||||
@@ -224,11 +220,9 @@ namespace MMAP
|
||||
}
|
||||
else
|
||||
{
|
||||
mmap->mmapLoadedTiles.erase(packedGridPos);
|
||||
mmap->loadedTileRefs.erase(packedGridPos);
|
||||
--loadedTiles;
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
LOG_DEBUG("server", "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, x, y, mapId);
|
||||
#endif
|
||||
LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, x, y, mapId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -237,70 +231,52 @@ namespace MMAP
|
||||
|
||||
bool MMapManager::unloadMap(uint32 mapId)
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> guard(MMapManagerLock);
|
||||
|
||||
if (loadedMMaps.find(mapId) == loadedMMaps.end())
|
||||
MMapDataSet::iterator itr = loadedMMaps.find(mapId);
|
||||
if (itr == loadedMMaps.end() || !itr->second)
|
||||
{
|
||||
// file may not exist, therefore not loaded
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map %03u", mapId);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// unload all tiles from given map
|
||||
MMapData* mmap = loadedMMaps[mapId];
|
||||
for (MMapTileSet::iterator i = mmap->mmapLoadedTiles.begin(); i != mmap->mmapLoadedTiles.end(); ++i)
|
||||
MMapData* mmap = itr->second;
|
||||
for (auto i : mmap->loadedTileRefs)
|
||||
{
|
||||
uint32 x = (i->first >> 16);
|
||||
uint32 y = (i->first & 0x0000FFFF);
|
||||
uint32 x = (i.first >> 16);
|
||||
uint32 y = (i.first & 0x0000FFFF);
|
||||
|
||||
dtStatus status;
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> guard(GetMMapLock(mapId));
|
||||
status = mmap->navMesh->removeTile(i->second, nullptr, nullptr);
|
||||
}
|
||||
|
||||
if (status != DT_SUCCESS)
|
||||
if (dtStatusFailed(mmap->navMesh->removeTile(i.second, nullptr, nullptr)))
|
||||
LOG_ERROR("server", "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, x, y);
|
||||
else
|
||||
{
|
||||
--loadedTiles;
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
LOG_DEBUG("server", "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, x, y, mapId);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
delete mmap;
|
||||
loadedMMaps.erase(mapId);
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
LOG_DEBUG("server", "MMAP:unloadMap: Unloaded %03i.mmap", mapId);
|
||||
#endif
|
||||
itr->second = nullptr;
|
||||
LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded %03i.mmap", mapId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MMapManager::unloadMapInstance(uint32 mapId, uint32 instanceId)
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> guard(MMapManagerLock);
|
||||
|
||||
// check if we have this map loaded
|
||||
if (loadedMMaps.find(mapId) == loadedMMaps.end())
|
||||
MMapDataSet::const_iterator itr = GetMMapData(mapId);
|
||||
if (itr == loadedMMaps.end())
|
||||
{
|
||||
// file may not exist, therefore not loaded
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded navmesh map %03u", mapId);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
MMapData* mmap = loadedMMaps[mapId];
|
||||
MMapData* mmap = itr->second;
|
||||
if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId %03u instanceId %u", mapId, instanceId);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -308,47 +284,44 @@ namespace MMAP
|
||||
|
||||
dtFreeNavMeshQuery(query);
|
||||
mmap->navMeshQueries.erase(instanceId);
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
LOG_DEBUG("server", "MMAP:unloadMapInstance: Unloaded mapId %03u instanceId %u", mapId, instanceId);
|
||||
#endif
|
||||
LOG_DEBUG("maps", "MMAP:unloadMapInstance: Unloaded mapId %03u instanceId %u", mapId, instanceId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
dtNavMesh const* MMapManager::GetNavMesh(uint32 mapId)
|
||||
{
|
||||
if (loadedMMaps.find(mapId) == loadedMMaps.end())
|
||||
MMapDataSet::const_iterator itr = GetMMapData(mapId);
|
||||
if (itr == loadedMMaps.end())
|
||||
return nullptr;
|
||||
|
||||
return loadedMMaps[mapId]->navMesh;
|
||||
return itr->second->navMesh;
|
||||
}
|
||||
|
||||
dtNavMeshQuery const* MMapManager::GetNavMeshQuery(uint32 mapId, uint32 instanceId)
|
||||
{
|
||||
if (loadedMMaps.find(mapId) == loadedMMaps.end())
|
||||
MMapDataSet::const_iterator itr = GetMMapData(mapId);
|
||||
if (itr == loadedMMaps.end())
|
||||
return nullptr;
|
||||
|
||||
MMapData* mmap = loadedMMaps[mapId];
|
||||
MMapData* mmap = itr->second;
|
||||
if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
|
||||
{
|
||||
// pussywizard: different instances of the same map shouldn't access this simultaneously
|
||||
std::unique_lock<std::shared_mutex> guard(GetMMapLock(mapId));
|
||||
// check again after acquiring mutex
|
||||
if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
|
||||
{
|
||||
// allocate mesh query
|
||||
dtNavMeshQuery* query = dtAllocNavMeshQuery();
|
||||
ASSERT(query);
|
||||
if (DT_SUCCESS != query->init(mmap->navMesh, 1024))
|
||||
|
||||
if (dtStatusFailed(query->init(mmap->navMesh, 1024)))
|
||||
{
|
||||
dtFreeNavMeshQuery(query);
|
||||
LOG_ERROR("server", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
LOG_DEBUG("server", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
|
||||
#endif
|
||||
LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
|
||||
mmap->navMeshQueries.insert(std::pair<uint32, dtNavMeshQuery*>(instanceId, query));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@ namespace MMAP
|
||||
// dummy struct to hold map's mmap data
|
||||
struct MMapData
|
||||
{
|
||||
MMapData(dtNavMesh* mesh) : navMesh(mesh) {}
|
||||
MMapData(dtNavMesh* mesh) : navMesh(mesh) { }
|
||||
|
||||
~MMapData()
|
||||
{
|
||||
for (NavMeshQuerySet::iterator i = navMeshQueries.begin(); i != navMeshQueries.end(); ++i)
|
||||
@@ -44,11 +45,10 @@ namespace MMAP
|
||||
dtFreeNavMesh(navMesh);
|
||||
}
|
||||
|
||||
dtNavMesh* navMesh;
|
||||
|
||||
// we have to use single dtNavMeshQuery for every instance, since those are not thread safe
|
||||
NavMeshQuerySet navMeshQueries; // instanceId to query
|
||||
MMapTileSet mmapLoadedTiles; // maps [map grid coords] to [dtTile]
|
||||
NavMeshQuerySet navMeshQueries; // instanceId to query
|
||||
dtNavMesh* navMesh;
|
||||
MMapTileSet loadedTileRefs; // maps [map grid coords] to [dtTile]
|
||||
};
|
||||
|
||||
typedef std::unordered_map<uint32, MMapData*> MMapDataSet;
|
||||
@@ -58,9 +58,10 @@ namespace MMAP
|
||||
class MMapManager
|
||||
{
|
||||
public:
|
||||
MMapManager() : loadedTiles(0) {}
|
||||
MMapManager() : loadedTiles(0), thread_safe_environment(true) { }
|
||||
~MMapManager();
|
||||
|
||||
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);
|
||||
@@ -73,18 +74,14 @@ namespace MMAP
|
||||
uint32 getLoadedTilesCount() const { return loadedTiles; }
|
||||
uint32 getLoadedMapsCount() const { return loadedMMaps.size(); }
|
||||
|
||||
std::shared_mutex& GetMMapLock(uint32 mapId);
|
||||
std::shared_mutex& GetMMapGeneralLock() { return MMapLock; } // pussywizard: in case a per-map mutex can't be found, should never happen
|
||||
std::shared_mutex& GetManagerLock() { return MMapManagerLock; }
|
||||
private:
|
||||
bool loadMapData(uint32 mapId);
|
||||
uint32 packTileID(int32 x, int32 y);
|
||||
MMapDataSet::const_iterator GetMMapData(uint32 mapId) const;
|
||||
|
||||
MMapDataSet loadedMMaps;
|
||||
uint32 loadedTiles;
|
||||
|
||||
std::shared_mutex MMapManagerLock;
|
||||
std::shared_mutex MMapLock; // pussywizard: in case a per-map mutex can't be found, should never happen
|
||||
bool thread_safe_environment;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -9,14 +9,15 @@
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
IVMapManager* gVMapManager = nullptr;
|
||||
VMapManager2* gVMapManager = nullptr;
|
||||
|
||||
//===============================================
|
||||
// just return the instance
|
||||
IVMapManager* VMapFactory::createOrGetVMapManager()
|
||||
VMapManager2* VMapFactory::createOrGetVMapManager()
|
||||
{
|
||||
if (gVMapManager == 0)
|
||||
gVMapManager = new VMapManager2(); // should be taken from config ... Please change if you like :-)
|
||||
if (!gVMapManager)
|
||||
gVMapManager = new VMapManager2();
|
||||
|
||||
return gVMapManager;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,20 +9,16 @@
|
||||
|
||||
#include "IVMapManager.h"
|
||||
|
||||
/**
|
||||
This is the access point to the VMapManager.
|
||||
*/
|
||||
|
||||
// This is the access point to the VMapManager.
|
||||
namespace VMAP
|
||||
{
|
||||
//===========================================================
|
||||
class VMapManager2;
|
||||
|
||||
class VMapFactory
|
||||
{
|
||||
public:
|
||||
static IVMapManager* createOrGetVMapManager();
|
||||
static VMapManager2* createOrGetVMapManager();
|
||||
static void clear();
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -15,21 +15,19 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include "VMapManager2.h"
|
||||
#include "MapTree.h"
|
||||
#include "ModelInstance.h"
|
||||
#include "WorldModel.h"
|
||||
#include <G3D/Vector3.h>
|
||||
#include <ace/Null_Mutex.h>
|
||||
#include "DisableMgr.h"
|
||||
#include "DBCStores.h"
|
||||
#include "MapDefines.h"
|
||||
#include "Log.h"
|
||||
#include "VMapDefinitions.h"
|
||||
#include "GridDefines.h"
|
||||
#include "Errors.h"
|
||||
#include <G3D/Vector3.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
using G3D::Vector3;
|
||||
|
||||
@@ -38,20 +36,32 @@ namespace VMAP
|
||||
VMapManager2::VMapManager2()
|
||||
{
|
||||
GetLiquidFlagsPtr = &GetLiquidFlagsDummy;
|
||||
IsVMAPDisabledForPtr = &IsVMAPDisabledForDummy;
|
||||
thread_safe_environment = true;
|
||||
}
|
||||
|
||||
VMapManager2::~VMapManager2(void)
|
||||
VMapManager2::~VMapManager2()
|
||||
{
|
||||
for (InstanceTreeMap::iterator i = iInstanceMapTrees.begin(); i != iInstanceMapTrees.end(); ++i)
|
||||
{
|
||||
delete i->second;
|
||||
}
|
||||
|
||||
for (ModelFileMap::iterator i = iLoadedModelFiles.begin(); i != iLoadedModelFiles.end(); ++i)
|
||||
{
|
||||
delete i->second.getModel();
|
||||
}
|
||||
}
|
||||
|
||||
void VMapManager2::InitializeThreadUnsafe(const std::vector<uint32>& mapIds)
|
||||
{
|
||||
// the caller must pass the list of all mapIds that will be used in the VMapManager2 lifetime
|
||||
for (const uint32& mapId : mapIds)
|
||||
iInstanceMapTrees.emplace(mapId, nullptr);
|
||||
|
||||
thread_safe_environment = false;
|
||||
}
|
||||
|
||||
Vector3 VMapManager2::convertPositionToInternalRep(float x, float y, float z) const
|
||||
{
|
||||
Vector3 pos;
|
||||
@@ -63,6 +73,16 @@ namespace VMAP
|
||||
return pos;
|
||||
}
|
||||
|
||||
InstanceTreeMap::const_iterator VMapManager2::GetMapTree(uint32 mapId) const
|
||||
{
|
||||
// return the iterator if found or end() if not found/NULL
|
||||
InstanceTreeMap::const_iterator itr = iInstanceMapTrees.find(mapId);
|
||||
if (itr != iInstanceMapTrees.cend() && !itr->second)
|
||||
itr = iInstanceMapTrees.cend();
|
||||
|
||||
return itr;
|
||||
}
|
||||
|
||||
// move to MapTree too?
|
||||
std::string VMapManager2::getMapFileName(unsigned int mapId)
|
||||
{
|
||||
@@ -92,6 +112,15 @@ namespace VMAP
|
||||
{
|
||||
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
|
||||
if (instanceTree == iInstanceMapTrees.end())
|
||||
{
|
||||
if (thread_safe_environment)
|
||||
instanceTree = iInstanceMapTrees.insert(InstanceTreeMap::value_type(mapId, nullptr)).first;
|
||||
else
|
||||
ASSERT(false, "Invalid mapId %u tile [%u, %u] passed to VMapManager2 after startup in thread unsafe environment",
|
||||
mapId, tileX, tileY);
|
||||
}
|
||||
|
||||
if (!instanceTree->second)
|
||||
{
|
||||
std::string mapFileName = getMapFileName(mapId);
|
||||
StaticMapTree* newTree = new StaticMapTree(mapId, basePath);
|
||||
@@ -100,7 +129,7 @@ namespace VMAP
|
||||
delete newTree;
|
||||
return false;
|
||||
}
|
||||
instanceTree = iInstanceMapTrees.insert(InstanceTreeMap::value_type(mapId, newTree)).first;
|
||||
instanceTree->second = newTree;
|
||||
}
|
||||
|
||||
return instanceTree->second->LoadMapTile(tileX, tileY, this);
|
||||
@@ -109,13 +138,13 @@ namespace VMAP
|
||||
void VMapManager2::unloadMap(unsigned int mapId)
|
||||
{
|
||||
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
|
||||
if (instanceTree != iInstanceMapTrees.end())
|
||||
if (instanceTree != iInstanceMapTrees.end() && instanceTree->second)
|
||||
{
|
||||
instanceTree->second->UnloadMap(this);
|
||||
if (instanceTree->second->numLoadedTiles() == 0)
|
||||
{
|
||||
delete instanceTree->second;
|
||||
iInstanceMapTrees.erase(mapId);
|
||||
instanceTree->second = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,25 +152,25 @@ namespace VMAP
|
||||
void VMapManager2::unloadMap(unsigned int mapId, int x, int y)
|
||||
{
|
||||
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
|
||||
if (instanceTree != iInstanceMapTrees.end())
|
||||
if (instanceTree != iInstanceMapTrees.end() && instanceTree->second)
|
||||
{
|
||||
instanceTree->second->UnloadMapTile(x, y, this);
|
||||
if (instanceTree->second->numLoadedTiles() == 0)
|
||||
{
|
||||
delete instanceTree->second;
|
||||
iInstanceMapTrees.erase(mapId);
|
||||
instanceTree->second = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool VMapManager2::isInLineOfSight(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2)
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_VMAP_CHECKS)
|
||||
if (!isLineOfSightCalcEnabled() || DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, nullptr, VMAP_DISABLE_LOS))
|
||||
#if defined(ENABLE_VMAP_CHECKS)
|
||||
if (!isLineOfSightCalcEnabled() || IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LOS))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
|
||||
InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId);
|
||||
if (instanceTree != iInstanceMapTrees.end())
|
||||
{
|
||||
Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1);
|
||||
@@ -161,11 +190,11 @@ namespace VMAP
|
||||
*/
|
||||
bool VMapManager2::getObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist)
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_VMAP_CHECKS)
|
||||
if (isLineOfSightCalcEnabled() && !DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, nullptr, VMAP_DISABLE_LOS))
|
||||
#if defined(ENABLE_VMAP_CHECKS)
|
||||
if (isLineOfSightCalcEnabled() && !IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LOS))
|
||||
#endif
|
||||
{
|
||||
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
|
||||
InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId);
|
||||
if (instanceTree != iInstanceMapTrees.end())
|
||||
{
|
||||
Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1);
|
||||
@@ -193,11 +222,11 @@ namespace VMAP
|
||||
|
||||
float VMapManager2::getHeight(unsigned int mapId, float x, float y, float z, float maxSearchDist)
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_VMAP_CHECKS)
|
||||
if (isHeightCalcEnabled() && !DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, nullptr, VMAP_DISABLE_HEIGHT))
|
||||
#if defined(ENABLE_VMAP_CHECKS)
|
||||
if (isHeightCalcEnabled() && !IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_HEIGHT))
|
||||
#endif
|
||||
{
|
||||
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
|
||||
InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId);
|
||||
if (instanceTree != iInstanceMapTrees.end())
|
||||
{
|
||||
Vector3 pos = convertPositionToInternalRep(x, y, z);
|
||||
@@ -214,11 +243,11 @@ namespace VMAP
|
||||
|
||||
bool VMapManager2::getAreaInfo(unsigned int mapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_VMAP_CHECKS)
|
||||
if (!DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, nullptr, VMAP_DISABLE_AREAFLAG))
|
||||
#if defined(ENABLE_VMAP_CHECKS)
|
||||
if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_AREAFLAG))
|
||||
#endif
|
||||
{
|
||||
InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(mapId);
|
||||
InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId);
|
||||
if (instanceTree != iInstanceMapTrees.end())
|
||||
{
|
||||
Vector3 pos = convertPositionToInternalRep(x, y, z);
|
||||
@@ -234,11 +263,11 @@ namespace VMAP
|
||||
|
||||
bool VMapManager2::GetLiquidLevel(uint32 mapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type) const
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_VMAP_CHECKS)
|
||||
if (!DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, nullptr, VMAP_DISABLE_LIQUIDSTATUS))
|
||||
#if defined(ENABLE_VMAP_CHECKS)
|
||||
if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LIQUIDSTATUS))
|
||||
#endif
|
||||
{
|
||||
InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(mapId);
|
||||
InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId);
|
||||
if (instanceTree != iInstanceMapTrees.end())
|
||||
{
|
||||
LocationInfo info;
|
||||
@@ -262,7 +291,7 @@ namespace VMAP
|
||||
WorldModel* VMapManager2::acquireModelInstance(const std::string& basepath, const std::string& filename)
|
||||
{
|
||||
//! Critical section, thread safe access to iLoadedModelFiles
|
||||
std::lock_guard<std::mutex> guard(LoadedModelFilesLock);
|
||||
std::lock_guard<std::mutex> lock(LoadedModelFilesLock);
|
||||
|
||||
ModelFileMap::iterator model = iLoadedModelFiles.find(filename);
|
||||
if (model == iLoadedModelFiles.end())
|
||||
@@ -274,20 +303,19 @@ namespace VMAP
|
||||
delete worldmodel;
|
||||
return nullptr;
|
||||
}
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
LOG_DEBUG("maps", "VMapManager2: loading file '%s%s'", basepath.c_str(), filename.c_str());
|
||||
#endif
|
||||
model = iLoadedModelFiles.insert(std::pair<std::string, ManagedModel>(filename, ManagedModel())).first;
|
||||
model->second.setModel(worldmodel);
|
||||
}
|
||||
//model->second.incRefCount();
|
||||
|
||||
return model->second.getModel();
|
||||
}
|
||||
|
||||
void VMapManager2::releaseModelInstance(const std::string& filename)
|
||||
{
|
||||
//! Critical section, thread safe access to iLoadedModelFiles
|
||||
std::lock_guard<std::mutex> guard(LoadedModelFilesLock);
|
||||
std::lock_guard<std::mutex> lock(LoadedModelFilesLock);
|
||||
|
||||
ModelFileMap::iterator model = iLoadedModelFiles.find(filename);
|
||||
if (model == iLoadedModelFiles.end())
|
||||
{
|
||||
@@ -296,9 +324,7 @@ namespace VMAP
|
||||
}
|
||||
if (model->second.decRefCount() == 0)
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
LOG_DEBUG("maps", "VMapManager2: unloading file '%s'", filename.c_str());
|
||||
#endif
|
||||
delete model->second.getModel();
|
||||
iLoadedModelFiles.erase(model);
|
||||
}
|
||||
@@ -309,4 +335,9 @@ namespace VMAP
|
||||
return StaticMapTree::CanLoadMap(std::string(basePath), mapId, x, y);
|
||||
}
|
||||
|
||||
void VMapManager2::getInstanceMapTree(InstanceTreeMap& instanceMapTree)
|
||||
{
|
||||
instanceMapTree = iInstanceMapTrees;
|
||||
}
|
||||
|
||||
} // namespace VMAP
|
||||
|
||||
@@ -19,9 +19,10 @@
|
||||
#define _VMAPMANAGER2_H
|
||||
|
||||
#include "IVMapManager.h"
|
||||
#include "Define.h"
|
||||
#include "Common.h"
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
//===========================================================
|
||||
|
||||
@@ -65,12 +66,22 @@ namespace VMAP
|
||||
typedef std::unordered_map<uint32, StaticMapTree*> InstanceTreeMap;
|
||||
typedef std::unordered_map<std::string, ManagedModel> ModelFileMap;
|
||||
|
||||
enum DisableTypes
|
||||
{
|
||||
VMAP_DISABLE_AREAFLAG = 0x1,
|
||||
VMAP_DISABLE_HEIGHT = 0x2,
|
||||
VMAP_DISABLE_LOS = 0x4,
|
||||
VMAP_DISABLE_LIQUIDSTATUS = 0x8
|
||||
};
|
||||
|
||||
class VMapManager2 : public IVMapManager
|
||||
{
|
||||
protected:
|
||||
// Tree to check collision
|
||||
ModelFileMap iLoadedModelFiles;
|
||||
InstanceTreeMap iInstanceMapTrees;
|
||||
bool thread_safe_environment;
|
||||
|
||||
// Mutex for iLoadedModelFiles
|
||||
std::mutex LoadedModelFilesLock;
|
||||
|
||||
@@ -78,6 +89,9 @@ namespace VMAP
|
||||
/* void _unloadMap(uint32 pMapId, uint32 x, uint32 y); */
|
||||
|
||||
static uint32 GetLiquidFlagsDummy(uint32) { return 0; }
|
||||
static bool IsVMAPDisabledForDummy(uint32 /*entry*/, uint8 /*flags*/) { return false; }
|
||||
|
||||
InstanceTreeMap::const_iterator GetMapTree(uint32 mapId) const;
|
||||
|
||||
public:
|
||||
// public for debug
|
||||
@@ -87,6 +101,8 @@ namespace VMAP
|
||||
VMapManager2();
|
||||
~VMapManager2() override;
|
||||
|
||||
void InitializeThreadUnsafe(const std::vector<uint32>& mapIds);
|
||||
|
||||
int loadMap(const char* pBasePath, unsigned int mapId, int x, int y) override;
|
||||
|
||||
void unloadMap(unsigned int mapId, int x, int y) override;
|
||||
@@ -113,12 +129,14 @@ namespace VMAP
|
||||
return getMapFileName(mapId);
|
||||
}
|
||||
bool existsMap(const char* basePath, unsigned int mapId, int x, int y) override;
|
||||
public:
|
||||
void getInstanceMapTree(InstanceTreeMap& instanceMapTree);
|
||||
|
||||
typedef uint32(*GetLiquidFlagsFn)(uint32 liquidType);
|
||||
GetLiquidFlagsFn GetLiquidFlagsPtr;
|
||||
|
||||
typedef bool(*IsVMAPDisabledForFn)(uint32 entry, uint8 flags);
|
||||
IsVMAPDisabledForFn IsVMAPDisabledForPtr;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user