* 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;
|
||||
}
|
||||
while(_del.size())
|
||||
{
|
||||
_del.next();
|
||||
}
|
||||
}
|
||||
|
||||
void DrawObjMgr::Add(uint64 objguid, DrawObject *o)
|
||||
|
||||
@ -246,6 +246,11 @@ void PseuGUI::NotifyObjectCreation(Object *o)
|
||||
domgr.Add(o->GetGUID(),d);
|
||||
}
|
||||
|
||||
void PseuGUI::NotifyAllObjectsDeletion(void)
|
||||
{
|
||||
domgr.Clear();
|
||||
}
|
||||
|
||||
void PseuGUI::SetInstance(PseuInstance* in)
|
||||
{
|
||||
_instance = in;
|
||||
@ -264,22 +269,26 @@ void PseuGUI::_UpdateSceneState(void)
|
||||
{
|
||||
_scene->OnDelete();
|
||||
delete _scene;
|
||||
_scene = NULL;
|
||||
}
|
||||
_smgr->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_LOGINSCREEN: _scene = new SceneLogin(this); break;
|
||||
case SCENESTATE_WORLD: _scene = new SceneWorld(this); break;
|
||||
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.");
|
||||
}
|
||||
@ -295,9 +304,11 @@ bool PseuGUI::SetSceneData(uint32 index, uint32 value)
|
||||
|
||||
uint32 PseuGUI::GetSceneState(void)
|
||||
{
|
||||
/* // not good, not threadsafe! (can crash)
|
||||
if(!_scene)
|
||||
return SCENESTATE_NOSCENE;
|
||||
return _scene->GetState();
|
||||
return _scene->GetState();*/
|
||||
return _scenestate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -15,7 +15,8 @@ enum SceneState
|
||||
SCENESTATE_NULL = 0,
|
||||
SCENESTATE_GUISTART,
|
||||
SCENESTATE_LOGINSCREEN,
|
||||
SCENESTATE_CHARACTERSELECTION,
|
||||
SCENESTATE_REALMSELECT,
|
||||
SCENESTATE_CHARSELECT,
|
||||
SCENESTATE_LOADING,
|
||||
SCENESTATE_WORLD,
|
||||
SCENESTATE_NOSCENE = 0xFFFFFFFF
|
||||
@ -93,6 +94,7 @@ public:
|
||||
// interfaces to tell the gui what to draw
|
||||
void NotifyObjectDeletion(uint64 guid);
|
||||
void NotifyObjectCreation(Object *o);
|
||||
void NotifyAllObjectsDeletion(void);
|
||||
|
||||
// scenes
|
||||
void SetSceneState(SceneState);
|
||||
|
||||
@ -261,6 +261,7 @@ void SceneWorld::OnDraw(void)
|
||||
void SceneWorld::OnDelete(void)
|
||||
{
|
||||
DEBUG(logdebug("~SceneWorld()"));
|
||||
gui->domgr.Clear();
|
||||
//sky->drop();
|
||||
}
|
||||
|
||||
|
||||
@ -34,6 +34,12 @@ void ObjMgr::RemoveAll(void)
|
||||
{
|
||||
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)
|
||||
@ -42,6 +48,8 @@ void ObjMgr::Remove(uint64 guid, bool del)
|
||||
if(o)
|
||||
{
|
||||
o->_SetDepleted();
|
||||
if(!del)
|
||||
logdebug("ObjMgr: "I64FMT" '%s' -> depleted.",guid,o->GetName().c_str());
|
||||
PseuGUI *gui = _instance->GetGUI();
|
||||
if(gui)
|
||||
gui->NotifyObjectDeletion(guid); // we have a gui, which must delete linked DrawObject
|
||||
|
||||
@ -42,10 +42,9 @@ WorldSession::~WorldSession()
|
||||
{
|
||||
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");
|
||||
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)
|
||||
logdebug("~WorldSession(): ... world GUI deleted, continuing to close session");
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user