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; WaypointData *node;
uint32 path_id; uint32 path_id;
TimeTrackerSmall i_nextMoveTime; TimeTrackerSmall i_nextMoveTime;
WaypointPath *waypoints; WaypointPath const* waypoints;
bool repeating, StopedByPlayer; bool repeating, StopedByPlayer;
}; };
@@ -21,19 +21,24 @@
#include "WaypointManager.h" #include "WaypointManager.h"
#include "MapManager.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(); uint32 oldMSTime = getMSTime();
@@ -41,30 +46,24 @@ void WaypointStore::Load()
if (!result) if (!result)
{ {
sLog->outErrorDb(">> Loaded 0 waypoints. DB table `waypoint_data` is empty!"); sLog->outErrorDb(">> Loaded 0 waypoints. DB table `waypoint_data` is empty!");
sLog->outString(); sLog->outString();
return; return;
} }
uint32 count = 0; uint32 count = 0;
Field *fields;
uint32 last_id = 0;
WaypointPath* path_data = NULL;
do do
{ {
fields = result->Fetch(); Field* fields = result->Fetch();
uint32 id = fields[0].GetUInt32(); WaypointData* wp = new WaypointData();
count++;
WaypointData *wp = new WaypointData;
if (last_id != id) uint32 pathId = fields[0].GetUInt32();
path_data = new WaypointPath; WaypointPath& path = _waypointStore[pathId];
float x, y, z; float x = fields[2].GetFloat();
x = fields[2].GetFloat(); float y = fields[3].GetFloat();
y = fields[3].GetFloat(); float z = fields[4].GetFloat();
z = fields[4].GetFloat();
Trinity::NormalizeMapCoord(x); Trinity::NormalizeMapCoord(x);
Trinity::NormalizeMapCoord(y); Trinity::NormalizeMapCoord(y);
@@ -78,46 +77,40 @@ void WaypointStore::Load()
wp->event_id = fields[7].GetUInt32(); wp->event_id = fields[7].GetUInt32();
wp->event_chance = fields[8].GetUInt8(); wp->event_chance = fields[8].GetUInt8();
path_data->push_back(wp); path.push_back(wp);
++count;
if (id != last_id)
waypoint_map[id] = path_data;
last_id = id;
} }
while (result->NextRow()) ; while (result->NextRow());
sLog->outString(">> Loaded %u waypoints in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); sLog->outString(">> Loaded %u waypoints in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
sLog->outString(); sLog->outString();
} }
void WaypointStore::UpdatePath(uint32 id) void WaypointMgr::ReloadPath(uint32 id)
{ {
if (waypoint_map.find(id)!= waypoint_map.end()) WaypointPathContainer::iterator itr = _waypointStore.find(id);
waypoint_map[id]->clear(); if (itr != _waypointStore.end())
{
for (WaypointPath::const_iterator it = itr->second.begin(); it != itr->second.end(); ++it)
delete *it;
QueryResult result; _waypointStore.erase(itr);
}
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);
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) if (!result)
return; return;
WaypointPath* path_data; WaypointPath& path = _waypointStore[id];
path_data = new WaypointPath;
Field *fields;
do do
{ {
fields = result->Fetch(); Field* fields = result->Fetch();
WaypointData *wp = new WaypointData();
WaypointData *wp = new WaypointData; float x = fields[1].GetFloat();
float y = fields[2].GetFloat();
float x, y, z; float z = fields[3].GetFloat();
x = fields[1].GetFloat();
y = fields[2].GetFloat();
z = fields[3].GetFloat();
Trinity::NormalizeMapCoord(x); Trinity::NormalizeMapCoord(x);
Trinity::NormalizeMapCoord(y); Trinity::NormalizeMapCoord(y);
@@ -131,11 +124,8 @@ void WaypointStore::UpdatePath(uint32 id)
wp->event_id = fields[6].GetUInt32(); wp->event_id = fields[6].GetUInt32();
wp->event_chance = fields[7].GetUInt8(); wp->event_chance = fields[7].GetUInt8();
path_data->push_back(wp); path.push_back(wp);
} }
while (result->NextRow()); while (result->NextRow());
waypoint_map[id] = path_data;
} }
@@ -34,33 +34,38 @@ struct WaypointData
}; };
typedef std::vector<WaypointData*> WaypointPath; typedef std::vector<WaypointData*> WaypointPath;
typedef UNORDERED_MAP<uint32, WaypointPath> WaypointPathContainer;
class WaypointStore class WaypointMgr
{ {
private : friend class ACE_Singleton<WaypointMgr, ACE_Null_Mutex>;
uint32 records;
UNORDERED_MAP<uint32, WaypointPath*> waypoint_map;
public: public:
// Null Mutex is OK because WaypointMgr is initialized in the World thread before World is initialized // Attempts to reload a single path from database
static WaypointStore* instance() { return ACE_Singleton<WaypointStore, ACE_Null_Mutex>::instance(); } void ReloadPath(uint32 id);
~WaypointStore() { Free(); } // Loads all paths from database, should only run on startup
void UpdatePath(uint32 id);
void Load(); 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()) WaypointPathContainer::const_iterator itr = _waypointStore.find(id);
return waypoint_map[id]; if (itr != _waypointStore.end())
else return 0; 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 #endif
+1 -1
View File
@@ -194,7 +194,7 @@ public:
return false; return false;
handler->PSendSysMessage("%s%s|r|cff00ffff%u|r", "|cff00ff00", "Loading Path: ", id); handler->PSendSysMessage("%s%s|r|cff00ffff%u|r", "|cff00ff00", "Loading Path: ", id);
sWaypointMgr->UpdatePath(id); sWaypointMgr->ReloadPath(id);
return true; return true;
} }
static bool HandleWpUnLoadCommand(ChatHandler* handler, const char* /*args*/) static bool HandleWpUnLoadCommand(ChatHandler* handler, const char* /*args*/)