forked from bartvdbraak/blender
BGE fix: game object to controller links consistancy maintained regardless of order of deletion
AddObject actuator forces last created object to hang in memory even after object is removed from scene => bad link between object and physic controller that causes Blender to crash in case a python script tries to use it (bad programming anyway). This patch avoids the crash by maintaining consistent links at all time.
This commit is contained in:
parent
822e51bd2d
commit
52293831b2
@ -24,7 +24,18 @@ CcdPhysicsController(ci)
|
||||
|
||||
KX_BulletPhysicsController::~KX_BulletPhysicsController ()
|
||||
{
|
||||
|
||||
// The game object has a direct link to
|
||||
if (m_pObject)
|
||||
{
|
||||
// If we cheat in SetObject, we must also cheat here otherwise the
|
||||
// object will still things it has a physical controller
|
||||
// Note that it requires that m_pObject is reset in case the object is deleted
|
||||
// before the controller (usual case, see KX_Scene::RemoveNodeDestructObjec)
|
||||
// The non usual case is when the object is not deleted because its reference is hanging
|
||||
// in a AddObject actuator but the node is deleted. This case is covered here.
|
||||
KX_GameObject* gameobj = (KX_GameObject*) m_pObject->GetSGClientObject();
|
||||
gameobj->SetPhysicsController(NULL,false);
|
||||
}
|
||||
}
|
||||
|
||||
void KX_BulletPhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ)
|
||||
@ -58,6 +69,7 @@ void KX_BulletPhysicsController::SetObject (SG_IObject* object)
|
||||
|
||||
}
|
||||
|
||||
|
||||
void KX_BulletPhysicsController::setMargin (float collisionMargin)
|
||||
{
|
||||
CcdPhysicsController::SetMargin(collisionMargin);
|
||||
|
@ -105,7 +105,19 @@ KX_GameObject::~KX_GameObject()
|
||||
delete m_pClient_info;
|
||||
//if (m_pSGNode)
|
||||
// delete m_pSGNode;
|
||||
|
||||
if (m_pSGNode)
|
||||
{
|
||||
// must go through controllers and make sure they will not use us anymore
|
||||
// This is important for KX_BulletPhysicsControllers that unregister themselves
|
||||
// from the object when they are deleted.
|
||||
SGControllerList::iterator contit;
|
||||
SGControllerList& controllers = m_pSGNode->GetSGControllerList();
|
||||
for (contit = controllers.begin();contit!=controllers.end();++contit)
|
||||
{
|
||||
(*contit)->ClearObject();
|
||||
}
|
||||
m_pSGNode->SetSGClientObject(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -410,8 +410,15 @@ void KX_Scene::EnableZBufferClearing(bool isclearingZbuffer)
|
||||
void KX_Scene::RemoveNodeDestructObject(class SG_IObject* node,class CValue* gameobj)
|
||||
{
|
||||
KX_GameObject* orgobj = (KX_GameObject*)gameobj;
|
||||
NewRemoveObject(orgobj);
|
||||
|
||||
if (NewRemoveObject(orgobj) != 0)
|
||||
{
|
||||
// object is not yet deleted (this can happen when it hangs in an add object actuator
|
||||
// last object created reference. It's a bad situation, don't know how to fix it exactly
|
||||
// The least I can do, is remove the reference to the node in the object as the node
|
||||
// will in any case be deleted. This ensures that the object will not try to use the node
|
||||
// when it is finally deleted (see KX_GameObject destructor)
|
||||
orgobj->SetSGNode(NULL);
|
||||
}
|
||||
if (node)
|
||||
delete node;
|
||||
}
|
||||
@ -723,8 +730,9 @@ void KX_Scene::DelayedRemoveObject(class CValue* gameobj)
|
||||
|
||||
|
||||
|
||||
void KX_Scene::NewRemoveObject(class CValue* gameobj)
|
||||
int KX_Scene::NewRemoveObject(class CValue* gameobj)
|
||||
{
|
||||
int ret;
|
||||
KX_GameObject* newobj = (KX_GameObject*) gameobj;
|
||||
|
||||
//todo: look at this
|
||||
@ -768,16 +776,17 @@ void KX_Scene::NewRemoveObject(class CValue* gameobj)
|
||||
}
|
||||
|
||||
newobj->RemoveMeshes();
|
||||
ret = 1;
|
||||
if (m_objectlist->RemoveValue(newobj))
|
||||
newobj->Release();
|
||||
ret = newobj->Release();
|
||||
if (m_tempObjectList->RemoveValue(newobj))
|
||||
newobj->Release();
|
||||
ret = newobj->Release();
|
||||
if (m_parentlist->RemoveValue(newobj))
|
||||
newobj->Release();
|
||||
ret = newobj->Release();
|
||||
if (m_inactivelist->RemoveValue(newobj))
|
||||
newobj->Release();
|
||||
ret = newobj->Release();
|
||||
if (m_euthanasyobjects->RemoveValue(newobj))
|
||||
newobj->Release();
|
||||
ret = newobj->Release();
|
||||
|
||||
if (newobj == m_active_camera)
|
||||
{
|
||||
@ -787,6 +796,8 @@ void KX_Scene::NewRemoveObject(class CValue* gameobj)
|
||||
}
|
||||
if (m_sceneConverter)
|
||||
m_sceneConverter->UnregisterGameObject(newobj);
|
||||
// return value will be 0 if the object is actually deleted (all reference gone)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -306,7 +306,7 @@ public:
|
||||
|
||||
void DelayedReleaseObject(CValue* gameobj);
|
||||
|
||||
void NewRemoveObject(CValue* gameobj);
|
||||
int NewRemoveObject(CValue* gameobj);
|
||||
void ReplaceMesh(CValue* gameobj,
|
||||
void* meshobj);
|
||||
void AddShape(class btCollisionShape* shape);
|
||||
|
Loading…
Reference in New Issue
Block a user