* fixed many gui-related possible crashes

* the DrawObject system should be stable enough now to do more serious things with it.
* added some object drawing code (cute cubes) - thx shlainn!!
This commit is contained in:
false_genesis 2008-03-31 16:57:28 +00:00
parent d7ea5fe553
commit aa63fc56f4
7 changed files with 120 additions and 8 deletions

View File

@ -1011,9 +1011,11 @@ DefReturnResult DefScriptPackage::SCGui(CmdSet &Set)
logerror("SCGui: failed"); logerror("SCGui: failed");
return false; return false;
} }
while(!ins->GetGUI() && !ins->GetGUI()->IsInitialized()) while(!ins->GetGUI() || !ins->GetGUI()->IsInitialized())
ins->GetRunnable()->sleep(1); ins->GetRunnable()->sleep(1);
ZThread::FastMutex mut;
mut.acquire();
// TODO: not sure if this piece of code will work as intended, needs some testing // TODO: not sure if this piece of code will work as intended, needs some testing
if(ins->GetWSession() && ins->GetWSession()->InWorld()) if(ins->GetWSession() && ins->GetWSession()->InWorld())
{ {
@ -1022,6 +1024,7 @@ DefReturnResult DefScriptPackage::SCGui(CmdSet &Set)
} }
else else
ins->GetGUI()->SetSceneState(SCENESTATE_GUISTART); ins->GetGUI()->SetSceneState(SCENESTATE_GUISTART);
mut.release();
return true; return true;
} }

View File

@ -10,12 +10,18 @@ DrawObjMgr::DrawObjMgr()
DrawObjMgr::~DrawObjMgr() DrawObjMgr::~DrawObjMgr()
{ {
DEBUG( logdebug("~DrawObjMgr(), deleting %u DrawObjects...", _storage.size() ) ); Clear();
}
void DrawObjMgr::Clear(void)
{
DEBUG( logdebug("DrawObjMgr::Clear(), deleting %u DrawObjects...", _storage.size() ) );
for(DrawObjStorage::iterator i = _storage.begin(); i != _storage.end(); i++) for(DrawObjStorage::iterator i = _storage.begin(); i != _storage.end(); i++)
{ {
DEBUG( logdebug("del for guid "I64FMT, i->first) ); DEBUG( logdebug("del for guid "I64FMT, i->first) );
delete i->second; // this can be done safely, since the object ptrs are not accessed delete i->second; // this can be done safely, since the object ptrs are not accessed
} }
_storage.clear();
while(_add.size()) while(_add.size())
{ {
@ -33,6 +39,15 @@ void DrawObjMgr::Delete(uint64 guid)
_del.add(guid); _del.add(guid);
} }
void DrawObjMgr::UnlinkAll(void)
{
DEBUG( logdebug("DrawObjMgr::UnlinkAll(), %u DrawObjects...", _storage.size() ) );
for(DrawObjStorage::iterator i = _storage.begin(); i != _storage.end(); i++)
{
i->second->Unlink();
}
}
void DrawObjMgr::Update(void) void DrawObjMgr::Update(void)
{ {
ZThread::FastMutex mut; ZThread::FastMutex mut;

View File

@ -14,8 +14,10 @@ public:
~DrawObjMgr(); ~DrawObjMgr();
void Add(uint64,DrawObject*); void Add(uint64,DrawObject*);
void Delete(uint64); void Delete(uint64);
void Clear(void);
void Update(void); // Threadsafe! delete code must be called from here! void Update(void); // Threadsafe! delete code must be called from here!
uint32 StorageSize(void) { return _storage.size(); } uint32 StorageSize(void) { return _storage.size(); }
void UnlinkAll(void);
private: private:
DrawObjStorage _storage; DrawObjStorage _storage;

View File

@ -2,20 +2,103 @@
#include "PseuGUI.h" #include "PseuGUI.h"
#include "DrawObject.h" #include "DrawObject.h"
#include "PseuWoW.h" #include "PseuWoW.h"
#include "Object.h"
DrawObject::DrawObject(irr::scene::ISceneManager *smgr, Object *obj) DrawObject::DrawObject(irr::IrrlichtDevice *device, Object *obj)
{ {
_smgr = smgr; _initialized = false;
Unlink();
_smgr = device->getSceneManager();
_guienv = device->getGUIEnvironment();
_obj = obj; _obj = obj;
DEBUG( logdebug("create DrawObject() this=%X obj=%X smgr=%X",this,_obj,_smgr) ); DEBUG( logdebug("create DrawObject() this=%X obj=%X name='%s' smgr=%X",this,_obj,_obj->GetName().c_str(),_smgr) );
} }
DrawObject::~DrawObject() DrawObject::~DrawObject()
{ {
DEBUG( logdebug("~DrawObject() this=%X obj=%X smgr=%X",this,_obj,_smgr) ); DEBUG( logdebug("~DrawObject() this=0x%X obj=0x%X smgr=%X",this,_obj,_smgr) );
if(cube)
{
text->remove();
cube->remove();
}
}
void DrawObject::Unlink(void)
{
cube = NULL;
text = NULL;
}
void DrawObject::_Init(void)
{
if(!cube && _obj->IsWorldObject()) // only world objects have coords and can be drawn
{
cube = _smgr->addCubeSceneNode(10);
cube->setName("CUBE");
//cube->setPosition(irr::core::vector3di(100,100,100));
cube->setRotation(irr::core::vector3df(0,0,0));
if(_obj->IsPlayer())
{
cube->getMaterial(0).DiffuseColor.set(255,255,0,0);
}
else if(_obj->IsCreature())
{
cube->getMaterial(0).DiffuseColor.set(255,0,255,0);
}
text=_smgr->addTextSceneNode(_guienv->getBuiltInFont(), L"TestText" , irr::video::SColor(255,255,255,255),cube, irr::core::vector3df(0,5,0));
}
DEBUG(logdebug("initialize DrawObject 0x%X obj: 0x%X "I64FMT,this,_obj,_obj->GetGUID()))
_initialized = true;
} }
void DrawObject::Draw(void) void DrawObject::Draw(void)
{ {
if(!_initialized)
_Init();
//printf("DRAW() for pObj 0x%X name '%s' guid "I64FMT"\n", _obj, _obj->GetName().c_str(), _obj->GetGUID());
if(cube)
{
WorldPosition pos = ((WorldObject*)_obj)->GetPosition();
// TODO: these formulas are horribly wrong! FIXME ASAP!
// they work best for ".tele dunmorogh"
float dx=pos.x * -5.0f - 26830.0f;
float dy=pos.z;
float dz=pos.y * -3.5f - 566.0f;
cube->setPosition(irr::core::vector3df(dx,dy,dz));
if(_obj->IsPlayer())
{
cube->getMaterial(0).DiffuseColor.set(255,255,0,0);
text->setTextColor(irr::video::SColor(255,255,0,0));
} }
else if(_obj->IsCreature())
{
cube->getMaterial(0).DiffuseColor.set(255,0,0,255);
text->setTextColor(irr::video::SColor(255,0,0,255));
}
float s = _obj->GetFloatValue(OBJECT_FIELD_SCALE_X);
if(s <= 0)
s = 1;
cube->setScale(irr::core::vector3df(s,s,s));
//cube->setRotation(irr::core::vector3df(0,RAD_TO_DEG(((WorldObject*)_obj)->GetO()),0));
irr::core::stringw tmp = L"";
if(_obj->GetName().empty())
{
tmp += L"unk<";
tmp += _obj->GetTypeId();
tmp += L">";
}
else
{
tmp += _obj->GetName().c_str();
}
text->setText(tmp.c_str());
}
}

View File

@ -9,14 +9,20 @@ class Object;
class DrawObject class DrawObject
{ {
public: public:
DrawObject(irr::scene::ISceneManager*, Object*); DrawObject(irr::IrrlichtDevice *device, Object*);
~DrawObject(); ~DrawObject();
void Draw(void); // call only in threadsafe environment!! (ensure the obj ptr is still valid!) void Draw(void); // call only in threadsafe environment!! (ensure the obj ptr is still valid!)
void Unlink(void);
// additionally, we dont use a GetObject() func - that would fuck things up if the object was already deleted. // additionally, we dont use a GetObject() func - that would fuck things up if the object was already deleted.
private: private:
void _Init(void);
Object *_obj; Object *_obj;
bool _initialized : 1;
irr::scene::ISceneManager *_smgr; irr::scene::ISceneManager *_smgr;
irr::gui::IGUIEnvironment* _guienv;
irr::scene::ISceneNode* cube;
irr::scene::ITextSceneNode *text;
}; };

View File

@ -48,6 +48,7 @@ PseuGUI::PseuGUI()
PseuGUI::~PseuGUI() PseuGUI::~PseuGUI()
{ {
domgr.Clear();
this->Cancel(); this->Cancel();
_instance->DeleteGUI(); // this makes the instance set its gui ptr to NULL _instance->DeleteGUI(); // this makes the instance set its gui ptr to NULL
logdebug("PseuGUI::~PseuGUI()"); logdebug("PseuGUI::~PseuGUI()");
@ -213,6 +214,8 @@ void PseuGUI::Run(void)
} }
} }
domgr.UnlinkAll(); // At this point the irr::device is probably closed and deleted already, which means it deleted
// all SceneNodes and everything. the ptrs are still stored in the DrawObjects, means they need to be unlinked now not to cause a crash.
DEBUG(logdebug("PseuGUI::Run() finished")); DEBUG(logdebug("PseuGUI::Run() finished"));
Cancel(); // already got shut down somehow, we can now safely cancel and drop the device Cancel(); // already got shut down somehow, we can now safely cancel and drop the device
} }

View File

@ -74,7 +74,7 @@ public:
void UseShadows(bool); void UseShadows(bool);
void Cancel(void); void Cancel(void);
void Shutdown(void); void Shutdown(void);
inline bool IsInitialized(void) { return _initialized; } inline bool IsInitialized(void) { return _initialized && _device; }
inline bool MustDie(void) { return _mustdie; } inline bool MustDie(void) { return _mustdie; }