* changed the way how objects are stored. they are now no longer deleted directly, but moved into a *depleted* state. this prevents crashes with already deleted objects accessed by other threads
This commit is contained in:
parent
e0a0b7d82d
commit
d7ea5fe553
@ -1016,7 +1016,10 @@ DefReturnResult DefScriptPackage::SCGui(CmdSet &Set)
|
||||
|
||||
// TODO: not sure if this piece of code will work as intended, needs some testing
|
||||
if(ins->GetWSession() && ins->GetWSession()->InWorld())
|
||||
{
|
||||
ins->GetGUI()->SetSceneState(SCENESTATE_WORLD);
|
||||
ins->GetWSession()->objmgr.ReNotifyGUI();
|
||||
}
|
||||
else
|
||||
ins->GetGUI()->SetSceneState(SCENESTATE_GUISTART);
|
||||
|
||||
|
||||
@ -46,6 +46,7 @@ void DrawObjMgr::Update(void)
|
||||
while(_add.size())
|
||||
{
|
||||
std::pair<uint64,DrawObject*> p = _add.next();
|
||||
DEBUG(logdebug("DrawObjMgr: adding DrawObj 0x%X guid "I64FMT" to main storage",p.second,p.first));
|
||||
_storage[p.first] = p.second;
|
||||
}
|
||||
|
||||
@ -55,10 +56,16 @@ void DrawObjMgr::Update(void)
|
||||
uint64 guid = _del.next();
|
||||
if(_storage.find(guid) != _storage.end())
|
||||
{
|
||||
|
||||
DrawObject *o = _storage[guid];
|
||||
DEBUG(logdebug("DrawObjMgr: removing DrawObj 0x%X guid "I64FMT" from main storage",o,guid));
|
||||
_storage.erase(guid);
|
||||
delete o;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG(logdebug("DrawObjMgr: ERROR: removable DrawObject "I64FMT" not exising",guid));
|
||||
}
|
||||
}
|
||||
|
||||
// now draw everything
|
||||
|
||||
@ -226,7 +226,7 @@ void PseuGUI::NotifyObjectDeletion(uint64 guid)
|
||||
// called from ObjMgr::Add(Object*)
|
||||
void PseuGUI::NotifyObjectCreation(Object *o)
|
||||
{
|
||||
DrawObject *d = new DrawObject(_smgr,o);
|
||||
DrawObject *d = new DrawObject(_device,o);
|
||||
domgr.Add(o->GetGUID(),d);
|
||||
}
|
||||
|
||||
|
||||
@ -30,6 +30,16 @@ enum DriverIDs
|
||||
DIRECTX9 = 5,
|
||||
};
|
||||
|
||||
#define MOUSE_SENSIVITY 0.5f
|
||||
#define ANGLE_STEP (M_PI/180.0f)
|
||||
#define DEG_TO_RAD(x) ((x)*ANGLE_STEP)
|
||||
#define RAD_TO_DEG(x) ((x)/ANGLE_STEP)
|
||||
#define RAD_FIX(x) ( (x)>(2*M_PI) ? ((x)-(2*M_PI)) : (x) )
|
||||
#define DEG_FIX(x) ( (x)>360 ? ((x)-360) : (x) )
|
||||
|
||||
#define COORD_SCALE_VALUE_X 0.336f
|
||||
#define COORD_SCALE_VALUE_Y 0.2f
|
||||
|
||||
class PseuGUIRunnable : public ZThread::Runnable
|
||||
{
|
||||
public:
|
||||
|
||||
@ -12,18 +12,6 @@
|
||||
#include "WorldSession.h"
|
||||
#include "World.h"
|
||||
|
||||
#define MOUSE_SENSIVITY 0.5f
|
||||
#define ANGLE_STEP (M_PI/180)
|
||||
#define DEG_TO_RAD(x) ((x)*ANGLE_STEP)
|
||||
#define RAD_TO_DEG(x) ((x)/ANGLE_STEP)
|
||||
#define RAD_FIX(x) ( (x)>(2*M_PI) ? ((x)-(2*M_PI)) : (x) )
|
||||
#define DEG_FIX(x) ( (x)>360 ? ((x)-360) : (x) )
|
||||
|
||||
#define COORD_SCALE_VALUE_X 0.336f
|
||||
#define COORD_SCALE_VALUE_Y 0.2f
|
||||
|
||||
|
||||
|
||||
SceneWorld::SceneWorld(PseuGUI *g) : Scene(g)
|
||||
{
|
||||
DEBUG(logdebug("SceneWorld: Initializing..."));
|
||||
@ -360,8 +348,8 @@ void SceneWorld::SetWorldPosition(WorldPosition wp)
|
||||
cam.Z = tile->GetBaseX() - wp.y + (tsize.Height * UNITSIZE);
|
||||
float heading = RAD_TO_DEG(((M_PI*3.0f)/2.0f) - wp.o);
|
||||
float heading_diff = camera->getHeading() - heading;
|
||||
logdebug("Setting camera to x: %3f y: %3f z:%3f head: %3f", cam.X, cam.Y, cam.Z, heading);
|
||||
camera->turnLeft(heading_diff);
|
||||
//logdebug("Setting camera to x: %3f y: %3f z:%3f head: %3f", cam.X, cam.Y, cam.Z, heading);
|
||||
//camera->turnLeft(heading_diff);
|
||||
|
||||
// TODO:
|
||||
// - correct the above formulas
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#include "DynamicObject.h"
|
||||
|
||||
DynamicObject::DynamicObject()
|
||||
DynamicObject::DynamicObject() : WorldObject()
|
||||
{
|
||||
_uint32values=NULL;
|
||||
_type=TYPE_DYNAMICOBJECT;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#include "GameObject.h"
|
||||
|
||||
GameObject::GameObject()
|
||||
GameObject::GameObject() : WorldObject()
|
||||
{
|
||||
_uint32values=NULL;
|
||||
_type=TYPE_GAMEOBJECT;
|
||||
|
||||
@ -114,6 +114,7 @@ void WorldSession::_HandleItemQuerySingleResponseOpcode(WorldPacket& recvPacket)
|
||||
|
||||
Item::Item()
|
||||
{
|
||||
_depleted = false;
|
||||
_type |= TYPE_ITEM;
|
||||
_typeid = TYPEID_ITEM;
|
||||
|
||||
|
||||
@ -32,24 +32,29 @@ void ObjMgr::RemoveAll(void)
|
||||
}
|
||||
while(_obj.size())
|
||||
{
|
||||
Remove(_obj.begin()->first);
|
||||
Remove(_obj.begin()->first, true);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjMgr::Remove(uint64 guid)
|
||||
void ObjMgr::Remove(uint64 guid, bool del)
|
||||
{
|
||||
Object *o = GetObj(guid);
|
||||
Object *o = GetObj(guid, true); // here get also depleted objs and delete if necessary
|
||||
if(o)
|
||||
{
|
||||
o->_SetDepleted();
|
||||
PseuGUI *gui = _instance->GetGUI();
|
||||
if(gui)
|
||||
gui->NotifyObjectDeletion(guid); // we have a gui, which must delete linked DrawObject
|
||||
_obj.erase(guid); // now delete the obj from the mgr
|
||||
delete o; // and delete the obj itself
|
||||
if(del)
|
||||
{
|
||||
_obj.erase(guid); // now delete the obj from the mgr
|
||||
delete o; // and delete the obj itself
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_obj.erase(guid);
|
||||
_obj.erase(guid); // we can safely erase an object that does not exist
|
||||
// - if we reach this point there was a bug anyway
|
||||
logcustom(2,LRED,"ObjMgr::Remove("I64FMT") - not existing",guid);
|
||||
}
|
||||
}
|
||||
@ -58,20 +63,29 @@ void ObjMgr::Remove(uint64 guid)
|
||||
|
||||
void ObjMgr::Add(Object *o)
|
||||
{
|
||||
_obj[o->GetGUID()] = o;
|
||||
Object *ox = GetObj(o->GetGUID(),true); // if an object already exists in the mgr, store old ptr...
|
||||
_obj[o->GetGUID()] = o; // ...assign new one...
|
||||
if(ox) // and if != NULL, delete the old object (completely, from memory)
|
||||
{
|
||||
Remove(ox->GetGUID(),true);
|
||||
}
|
||||
|
||||
PseuGUI *gui = _instance->GetGUI();
|
||||
if(gui)
|
||||
gui->NotifyObjectCreation(o);
|
||||
}
|
||||
|
||||
Object *ObjMgr::GetObj(uint64 guid)
|
||||
Object *ObjMgr::GetObj(uint64 guid, bool also_depleted)
|
||||
{
|
||||
if(!guid)
|
||||
return NULL;
|
||||
for(ObjectMap::iterator i = _obj.begin(); i!=_obj.end(); i++)
|
||||
if(i->second->GetGUID() == guid)
|
||||
{
|
||||
if(i->second->_IsDepleted() && !also_depleted)
|
||||
return NULL;
|
||||
return i->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -90,6 +104,22 @@ uint32 ObjMgr::AssignNameToObj(uint32 entry, uint8 type, std::string name)
|
||||
return changed;
|
||||
}
|
||||
|
||||
void ObjMgr::ReNotifyGUI(void)
|
||||
{
|
||||
PseuGUI *gui = _instance->GetGUI();
|
||||
if(!gui)
|
||||
return;
|
||||
for(ObjectMap::iterator it = _obj.begin(); it != _obj.end(); it++)
|
||||
{
|
||||
Object *o = it->second;
|
||||
if(o->_IsDepleted())
|
||||
continue;
|
||||
gui->NotifyObjectCreation(o);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -- Item part --
|
||||
|
||||
void ObjMgr::Add(ItemProto *proto)
|
||||
|
||||
@ -49,10 +49,11 @@ public:
|
||||
|
||||
// Object functions
|
||||
void Add(Object*);
|
||||
void Remove(uint64); // remove all objects with that guid (should be only 1 object in total anyway)
|
||||
Object *GetObj(uint64 guid);
|
||||
void Remove(uint64 guid, bool del); // remove all objects with that guid (should be only 1 object in total anyway)
|
||||
Object *GetObj(uint64 guid, bool also_depleted = false);
|
||||
inline uint32 GetObjectCount(void) { return _obj.size(); }
|
||||
uint32 AssignNameToObj(uint32 entry, uint8 type, std::string name);
|
||||
void ReNotifyGUI(void);
|
||||
|
||||
private:
|
||||
ItemProtoMap _iproto;
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
|
||||
Object::Object()
|
||||
{
|
||||
_depleted = false;
|
||||
_uint32values=NULL;
|
||||
_type=TYPE_OBJECT;
|
||||
_typeid=TYPEID_OBJECT;
|
||||
@ -39,6 +40,7 @@ void Object::Create( uint64 guid )
|
||||
|
||||
WorldObject::WorldObject()
|
||||
{
|
||||
_depleted = false;
|
||||
_m = 0;
|
||||
}
|
||||
|
||||
@ -121,7 +123,7 @@ void WorldSession::_HandleDestroyObjectOpcode(WorldPacket& recvPacket)
|
||||
GetInstance()->GetScripts()->RunScript("_onobjectdelete", &Set);
|
||||
}
|
||||
|
||||
objmgr.Remove(guid);
|
||||
objmgr.Remove(guid, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -92,6 +92,8 @@ public:
|
||||
}
|
||||
|
||||
void Create(uint64 guid);
|
||||
inline bool _IsDepleted(void) { return _depleted; }
|
||||
inline void _SetDepleted(void) { _depleted = true; }
|
||||
|
||||
protected:
|
||||
Object();
|
||||
@ -106,6 +108,7 @@ protected:
|
||||
uint8 _type;
|
||||
uint8 _typeid;
|
||||
std::string _name;
|
||||
bool _depleted : 1; // true if the object was deleted from the objmgr, but not from memory
|
||||
};
|
||||
|
||||
class WorldObject : public Object
|
||||
|
||||
@ -86,7 +86,7 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket)
|
||||
if(uguid != GetGuid())
|
||||
{
|
||||
logdev("- already exists, deleting old, creating new object");
|
||||
objmgr.Remove(uguid);
|
||||
objmgr.Remove(uguid, false);
|
||||
// do not call script here, since the object does not really get deleted
|
||||
}
|
||||
else
|
||||
@ -128,6 +128,8 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket)
|
||||
}
|
||||
case TYPEID_PLAYER:
|
||||
{
|
||||
if(GetGuid() == uguid) // objmgr.Add() would cause quite some trouble if we added ourself again
|
||||
break;
|
||||
Player *player = new Player();
|
||||
player->Create(uguid);
|
||||
objmgr.Add(player);
|
||||
@ -201,7 +203,7 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket)
|
||||
GetInstance()->GetScripts()->RunScript("_onobjectdelete", &Set);
|
||||
}
|
||||
|
||||
objmgr.Remove(uguid);
|
||||
objmgr.Remove(uguid, false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -597,8 +597,8 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
|
||||
// that means even if the server sends create object with that guid, do NOT recreate it!!
|
||||
MyCharacter *my = new MyCharacter();
|
||||
my->Create(_myGUID);
|
||||
objmgr.Add(my);
|
||||
my->SetName(plr[charId]._name);
|
||||
objmgr.Add(my);
|
||||
|
||||
// TODO: initialize the world here, and load required maps.
|
||||
// must remove appropriate code from _HandleLoginVerifyWorldOpcode() then!!
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user