Core/WaypointMgr: Fixed crashes when loading data with waypoint_data.id=0 and fixed memory leaks in .wp reload command

This commit is contained in:
Shauren
2011-05-24 23:13:47 +02:00
parent d9390bdd09
commit cb608283b2
4 changed files with 64 additions and 69 deletions
@@ -85,7 +85,7 @@ class WaypointMovementGenerator
WaypointData *node;
uint32 path_id;
TimeTrackerSmall i_nextMoveTime;
WaypointPath *waypoints;
WaypointPath const* waypoints;
bool repeating, StopedByPlayer;
};
@@ -21,19 +21,24 @@
#include "WaypointManager.h"
#include "MapManager.h"
void WaypointStore::Free()
WaypointMgr::WaypointMgr()
{
for (UNORDERED_MAP<uint32, WaypointPath*>::const_iterator itr = waypoint_map.begin(); itr != waypoint_map.end(); ++itr)
{
for (WaypointPath::const_iterator it = itr->second->begin(); it != itr->second->end(); ++it)
delete *it;
itr->second->clear();
delete itr->second;
}
waypoint_map.clear();
}
void WaypointStore::Load()
WaypointMgr::~WaypointMgr()
{
for (WaypointPathContainer::iterator itr = _waypointStore.begin(); itr != _waypointStore.end(); ++itr)
{
for (WaypointPath::const_iterator it = itr->second.begin(); it != itr->second.end(); ++it)
delete *it;
itr->second.clear();
}
_waypointStore.clear();
}
void WaypointMgr::Load()
{
uint32 oldMSTime = getMSTime();
@@ -47,24 +52,18 @@ void WaypointStore::Load()
}
uint32 count = 0;
Field *fields;
uint32 last_id = 0;
WaypointPath* path_data = NULL;
do
{
fields = result->Fetch();
uint32 id = fields[0].GetUInt32();
count++;
WaypointData *wp = new WaypointData;
Field* fields = result->Fetch();
WaypointData* wp = new WaypointData();
if (last_id != id)
path_data = new WaypointPath;
uint32 pathId = fields[0].GetUInt32();
WaypointPath& path = _waypointStore[pathId];
float x, y, z;
x = fields[2].GetFloat();
y = fields[3].GetFloat();
z = fields[4].GetFloat();
float x = fields[2].GetFloat();
float y = fields[3].GetFloat();
float z = fields[4].GetFloat();
Trinity::NormalizeMapCoord(x);
Trinity::NormalizeMapCoord(y);
@@ -78,46 +77,40 @@ void WaypointStore::Load()
wp->event_id = fields[7].GetUInt32();
wp->event_chance = fields[8].GetUInt8();
path_data->push_back(wp);
if (id != last_id)
waypoint_map[id] = path_data;
last_id = id;
path.push_back(wp);
++count;
}
while (result->NextRow()) ;
while (result->NextRow());
sLog->outString(">> Loaded %u waypoints in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
sLog->outString();
}
void WaypointStore::UpdatePath(uint32 id)
void WaypointMgr::ReloadPath(uint32 id)
{
if (waypoint_map.find(id)!= waypoint_map.end())
waypoint_map[id]->clear();
WaypointPathContainer::iterator itr = _waypointStore.find(id);
if (itr != _waypointStore.end())
{
for (WaypointPath::const_iterator it = itr->second.begin(); it != itr->second.end(); ++it)
delete *it;
QueryResult result;
result = WorldDatabase.PQuery("SELECT point, position_x, position_y, position_z, move_flag, delay, action, action_chance FROM waypoint_data WHERE id = %u ORDER BY point", id);
_waypointStore.erase(itr);
}
QueryResult result = WorldDatabase.PQuery("SELECT point, position_x, position_y, position_z, move_flag, delay, action, action_chance FROM waypoint_data WHERE id = %u ORDER BY point", id);
if (!result)
return;
WaypointPath* path_data;
path_data = new WaypointPath;
Field *fields;
WaypointPath& path = _waypointStore[id];
do
{
fields = result->Fetch();
Field* fields = result->Fetch();
WaypointData *wp = new WaypointData();
WaypointData *wp = new WaypointData;
float x, y, z;
x = fields[1].GetFloat();
y = fields[2].GetFloat();
z = fields[3].GetFloat();
float x = fields[1].GetFloat();
float y = fields[2].GetFloat();
float z = fields[3].GetFloat();
Trinity::NormalizeMapCoord(x);
Trinity::NormalizeMapCoord(y);
@@ -131,11 +124,8 @@ void WaypointStore::UpdatePath(uint32 id)
wp->event_id = fields[6].GetUInt32();
wp->event_chance = fields[7].GetUInt8();
path_data->push_back(wp);
path.push_back(wp);
}
while (result->NextRow());
waypoint_map[id] = path_data;
}
@@ -34,33 +34,38 @@ struct WaypointData
};
typedef std::vector<WaypointData*> WaypointPath;
typedef UNORDERED_MAP<uint32, WaypointPath> WaypointPathContainer;
class WaypointStore
class WaypointMgr
{
private :
uint32 records;
UNORDERED_MAP<uint32, WaypointPath*> waypoint_map;
friend class ACE_Singleton<WaypointMgr, ACE_Null_Mutex>;
public:
// Null Mutex is OK because WaypointMgr is initialized in the World thread before World is initialized
static WaypointStore* instance() { return ACE_Singleton<WaypointStore, ACE_Null_Mutex>::instance(); }
// Attempts to reload a single path from database
void ReloadPath(uint32 id);
~WaypointStore() { Free(); }
void UpdatePath(uint32 id);
// Loads all paths from database, should only run on startup
void Load();
void Free();
WaypointPath* GetPath(uint32 id)
// Returns the path from a given id
WaypointPath const* GetPath(uint32 id) const
{
if (waypoint_map.find(id) != waypoint_map.end())
return waypoint_map[id];
else return 0;
WaypointPathContainer::const_iterator itr = _waypointStore.find(id);
if (itr != _waypointStore.end())
return &itr->second;
return NULL;
}
inline uint32 GetRecordsCount() const { return records; }
private:
// Only allow instantiation from ACE_Singleton
WaypointMgr();
~WaypointMgr();
WaypointPathContainer _waypointStore;
};
#define sWaypointMgr WaypointStore::instance()
#define sWaypointMgr ACE_Singleton<WaypointMgr, ACE_Null_Mutex>::instance()
#endif
+1 -1
View File
@@ -194,7 +194,7 @@ public:
return false;
handler->PSendSysMessage("%s%s|r|cff00ffff%u|r", "|cff00ff00", "Loading Path: ", id);
sWaypointMgr->UpdatePath(id);
sWaypointMgr->ReloadPath(id);
return true;
}
static bool HandleWpUnLoadCommand(ChatHandler* handler, const char* /*args*/)