* fixed problems with too early deleted DrawObjects and one crash with GetSceneState() accessing just deleted _scene. both related to reconnect after connection closed.
This commit is contained in:
parent
e06eb019d0
commit
5d418facbe
@ -27,6 +27,10 @@ void DrawObjMgr::Clear(void)
|
|||||||
{
|
{
|
||||||
delete _add.next().second;
|
delete _add.next().second;
|
||||||
}
|
}
|
||||||
|
while(_del.size())
|
||||||
|
{
|
||||||
|
_del.next();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawObjMgr::Add(uint64 objguid, DrawObject *o)
|
void DrawObjMgr::Add(uint64 objguid, DrawObject *o)
|
||||||
|
|||||||
@ -246,6 +246,11 @@ void PseuGUI::NotifyObjectCreation(Object *o)
|
|||||||
domgr.Add(o->GetGUID(),d);
|
domgr.Add(o->GetGUID(),d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PseuGUI::NotifyAllObjectsDeletion(void)
|
||||||
|
{
|
||||||
|
domgr.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
void PseuGUI::SetInstance(PseuInstance* in)
|
void PseuGUI::SetInstance(PseuInstance* in)
|
||||||
{
|
{
|
||||||
_instance = in;
|
_instance = in;
|
||||||
@ -264,22 +269,26 @@ void PseuGUI::_UpdateSceneState(void)
|
|||||||
{
|
{
|
||||||
_scene->OnDelete();
|
_scene->OnDelete();
|
||||||
delete _scene;
|
delete _scene;
|
||||||
|
_scene = NULL;
|
||||||
}
|
}
|
||||||
_smgr->clear();
|
_smgr->clear();
|
||||||
_guienv->clear();
|
_guienv->clear();
|
||||||
|
|
||||||
_scenestate = _scenestate_new;
|
|
||||||
|
|
||||||
logdebug("PseuGUI: switched to SceneState %u", _scenestate);
|
|
||||||
|
|
||||||
switch (_scenestate)
|
logdebug("PseuGUI: switching to SceneState %u", _scenestate_new);
|
||||||
|
|
||||||
|
switch (_scenestate_new)
|
||||||
{
|
{
|
||||||
case SCENESTATE_GUISTART: _scene = new SceneGuiStart(this); break;
|
case SCENESTATE_GUISTART: _scene = new SceneGuiStart(this); break;
|
||||||
case SCENESTATE_LOGINSCREEN: _scene = new SceneLogin(this); break;
|
case SCENESTATE_LOGINSCREEN: _scene = new SceneLogin(this); break;
|
||||||
case SCENESTATE_WORLD: _scene = new SceneWorld(this); break;
|
case SCENESTATE_WORLD: _scene = new SceneWorld(this); break;
|
||||||
default: _scene = new Scene(this); // will draw nothing, just yield the gui
|
default: _scene = new Scene(this); // will draw nothing, just yield the gui
|
||||||
}
|
}
|
||||||
_scene->SetState(_scenestate);
|
_scene->SetState(_scenestate_new);
|
||||||
|
// current scenestate can be set safely after scene is created and ready
|
||||||
|
_scenestate = _scenestate_new;
|
||||||
|
|
||||||
|
|
||||||
logdebug("PseuGUI: scene created.");
|
logdebug("PseuGUI: scene created.");
|
||||||
}
|
}
|
||||||
@ -295,9 +304,11 @@ bool PseuGUI::SetSceneData(uint32 index, uint32 value)
|
|||||||
|
|
||||||
uint32 PseuGUI::GetSceneState(void)
|
uint32 PseuGUI::GetSceneState(void)
|
||||||
{
|
{
|
||||||
|
/* // not good, not threadsafe! (can crash)
|
||||||
if(!_scene)
|
if(!_scene)
|
||||||
return SCENESTATE_NOSCENE;
|
return SCENESTATE_NOSCENE;
|
||||||
return _scene->GetState();
|
return _scene->GetState();*/
|
||||||
|
return _scenestate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,8 @@ enum SceneState
|
|||||||
SCENESTATE_NULL = 0,
|
SCENESTATE_NULL = 0,
|
||||||
SCENESTATE_GUISTART,
|
SCENESTATE_GUISTART,
|
||||||
SCENESTATE_LOGINSCREEN,
|
SCENESTATE_LOGINSCREEN,
|
||||||
SCENESTATE_CHARACTERSELECTION,
|
SCENESTATE_REALMSELECT,
|
||||||
|
SCENESTATE_CHARSELECT,
|
||||||
SCENESTATE_LOADING,
|
SCENESTATE_LOADING,
|
||||||
SCENESTATE_WORLD,
|
SCENESTATE_WORLD,
|
||||||
SCENESTATE_NOSCENE = 0xFFFFFFFF
|
SCENESTATE_NOSCENE = 0xFFFFFFFF
|
||||||
@ -93,6 +94,7 @@ public:
|
|||||||
// interfaces to tell the gui what to draw
|
// interfaces to tell the gui what to draw
|
||||||
void NotifyObjectDeletion(uint64 guid);
|
void NotifyObjectDeletion(uint64 guid);
|
||||||
void NotifyObjectCreation(Object *o);
|
void NotifyObjectCreation(Object *o);
|
||||||
|
void NotifyAllObjectsDeletion(void);
|
||||||
|
|
||||||
// scenes
|
// scenes
|
||||||
void SetSceneState(SceneState);
|
void SetSceneState(SceneState);
|
||||||
|
|||||||
@ -261,6 +261,7 @@ void SceneWorld::OnDraw(void)
|
|||||||
void SceneWorld::OnDelete(void)
|
void SceneWorld::OnDelete(void)
|
||||||
{
|
{
|
||||||
DEBUG(logdebug("~SceneWorld()"));
|
DEBUG(logdebug("~SceneWorld()"));
|
||||||
|
gui->domgr.Clear();
|
||||||
//sky->drop();
|
//sky->drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -34,6 +34,12 @@ void ObjMgr::RemoveAll(void)
|
|||||||
{
|
{
|
||||||
Remove(_obj.begin()->first, true);
|
Remove(_obj.begin()->first, true);
|
||||||
}
|
}
|
||||||
|
if(PseuGUI *gui = _instance->GetGUI())
|
||||||
|
{
|
||||||
|
// necessary that the pending-to-delete GUIDs just stored by deleting the objects above will be cleared
|
||||||
|
// so that newly added DrawObjects with uncleared pending-to-delete GUIDs will not get deleted again immediately.
|
||||||
|
gui->NotifyAllObjectsDeletion();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjMgr::Remove(uint64 guid, bool del)
|
void ObjMgr::Remove(uint64 guid, bool del)
|
||||||
@ -42,6 +48,8 @@ void ObjMgr::Remove(uint64 guid, bool del)
|
|||||||
if(o)
|
if(o)
|
||||||
{
|
{
|
||||||
o->_SetDepleted();
|
o->_SetDepleted();
|
||||||
|
if(!del)
|
||||||
|
logdebug("ObjMgr: "I64FMT" '%s' -> depleted.",guid,o->GetName().c_str());
|
||||||
PseuGUI *gui = _instance->GetGUI();
|
PseuGUI *gui = _instance->GetGUI();
|
||||||
if(gui)
|
if(gui)
|
||||||
gui->NotifyObjectDeletion(guid); // we have a gui, which must delete linked DrawObject
|
gui->NotifyObjectDeletion(guid); // we have a gui, which must delete linked DrawObject
|
||||||
|
|||||||
@ -42,10 +42,9 @@ WorldSession::~WorldSession()
|
|||||||
{
|
{
|
||||||
if(PseuGUI *gui = GetInstance()->GetGUI())
|
if(PseuGUI *gui = GetInstance()->GetGUI())
|
||||||
{
|
{
|
||||||
if(gui->GetSceneState() == SCENESTATE_WORLD)
|
gui->SetSceneState(SCENESTATE_LOGINSCREEN); // kick back to login gui
|
||||||
gui->SetSceneState(SCENESTATE_LOGINSCREEN); // kick back to login gui
|
|
||||||
logdebug("~WorldSession(): Waiting until world GUI is deleted");
|
logdebug("~WorldSession(): Waiting until world GUI is deleted");
|
||||||
while(gui->GetSceneState() == SCENESTATE_GUISTART) // .. and wait until the world gui is really deleted
|
while(gui->GetSceneState() != SCENESTATE_LOGINSCREEN) // .. and wait until the world gui is really deleted
|
||||||
GetInstance()->Sleep(1); // (it can cause crash otherwise)
|
GetInstance()->Sleep(1); // (it can cause crash otherwise)
|
||||||
logdebug("~WorldSession(): ... world GUI deleted, continuing to close session");
|
logdebug("~WorldSession(): ... world GUI deleted, continuing to close session");
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user