[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [14557] trunk/blender/source/gameengine: BGE bug: crash when an object being tracked-to is deleted ( bad practice anyway).

Benoit Bolsee benoit.bolsee at online.be
Sat Apr 26 22:41:26 CEST 2008


Revision: 14557
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=14557
Author:   ben2610
Date:     2008-04-26 22:41:25 +0200 (Sat, 26 Apr 2008)

Log Message:
-----------
BGE bug: crash when an object being tracked-to is deleted (bad practice anyway).  Fix by creating a generic cross reference between actuators (only TrackTo uses it at the moment) and objects so that the actuator is informed when the target object is deleted

Modified Paths:
--------------
    trunk/blender/source/gameengine/GameLogic/SCA_IActuator.h
    trunk/blender/source/gameengine/GameLogic/SCA_IObject.cpp
    trunk/blender/source/gameengine/GameLogic/SCA_IObject.h
    trunk/blender/source/gameengine/Ketsji/KX_TrackToActuator.cpp
    trunk/blender/source/gameengine/Ketsji/KX_TrackToActuator.h

Modified: trunk/blender/source/gameengine/GameLogic/SCA_IActuator.h
===================================================================
--- trunk/blender/source/gameengine/GameLogic/SCA_IActuator.h	2008-04-26 14:02:41 UTC (rev 14556)
+++ trunk/blender/source/gameengine/GameLogic/SCA_IActuator.h	2008-04-26 20:41:25 UTC (rev 14557)
@@ -47,6 +47,15 @@
 				  PyTypeObject* T =&Type); 
 
 	/**
+	 * UnlinkObject(...)
+	 * Certain actuator use gameobject pointers (like TractTo actuator)
+	 * This function can be called when an object is removed to make
+	 * sure that the actuator will not use it anymore.
+	 */
+
+	virtual bool UnlinkObject(SCA_IObject* clientobj) { return false; }
+
+	/**
 	 * Update(...)
 	 * Update the actuator based upon the events received since 
 	 * the last call to Update, the current time and deltatime the

Modified: trunk/blender/source/gameengine/GameLogic/SCA_IObject.cpp
===================================================================
--- trunk/blender/source/gameengine/GameLogic/SCA_IObject.cpp	2008-04-26 14:02:41 UTC (rev 14556)
+++ trunk/blender/source/gameengine/GameLogic/SCA_IObject.cpp	2008-04-26 20:41:25 UTC (rev 14557)
@@ -62,6 +62,10 @@
 		((CValue*)(*itc))->Release();
 	}
 	SCA_ActuatorList::iterator ita;
+	for (ita = m_registeredActuators.begin(); !(ita==m_registeredActuators.end()); ++ita)
+	{
+		(*ita)->UnlinkObject(this);
+	}
 	for (ita = m_actuators.begin(); !(ita==m_actuators.end()); ++ita)
 	{
 		((CValue*)(*ita))->Release();
@@ -118,7 +122,24 @@
 	m_actuators.push_back(act);
 }
 
+void SCA_IObject::RegisterActuator(SCA_IActuator* act)
+{
+	// don't increase ref count, it would create dead lock
+	m_registeredActuators.push_back(act);
+}
 
+void SCA_IObject::UnregisterActuator(SCA_IActuator* act)
+{
+	SCA_ActuatorList::iterator ita;
+	for (ita = m_registeredActuators.begin(); ita != m_registeredActuators.end(); ita++)
+	{
+		if ((*ita) == act) {
+			(*ita) = m_registeredActuators.back();
+			m_registeredActuators.pop_back();
+			break;
+		}
+	}
+}
 
 void SCA_IObject::SetIgnoreActivityCulling(bool b)
 {
@@ -168,6 +189,8 @@
 		newactuator->SetActive(false);
 		oldactuators[act++] = newactuator;
 	}
+	// a new object cannot be client of any actuator
+	m_registeredActuators.clear();
 		
 }
 

Modified: trunk/blender/source/gameengine/GameLogic/SCA_IObject.h
===================================================================
--- trunk/blender/source/gameengine/GameLogic/SCA_IObject.h	2008-04-26 14:02:41 UTC (rev 14556)
+++ trunk/blender/source/gameengine/GameLogic/SCA_IObject.h	2008-04-26 20:41:25 UTC (rev 14557)
@@ -55,6 +55,7 @@
 	SCA_SensorList         m_sensors;
 	SCA_ControllerList     m_controllers;
 	SCA_ActuatorList       m_actuators;
+	SCA_ActuatorList       m_registeredActuators;	// actuators that use a pointer to this object
 	static class MT_Point3 m_sDummy;
 
 	/**
@@ -79,6 +80,8 @@
 	void AddSensor(SCA_ISensor* act);
 	void AddController(SCA_IController* act);
 	void AddActuator(SCA_IActuator* act);
+	void RegisterActuator(SCA_IActuator* act);
+	void UnregisterActuator(SCA_IActuator* act);
 	
 	SCA_ISensor* FindSensor(const STR_String& sensorname);
 	SCA_IActuator* FindActuator(const STR_String& actuatorname);

Modified: trunk/blender/source/gameengine/Ketsji/KX_TrackToActuator.cpp
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_TrackToActuator.cpp	2008-04-26 14:02:41 UTC (rev 14556)
+++ trunk/blender/source/gameengine/Ketsji/KX_TrackToActuator.cpp	2008-04-26 20:41:25 UTC (rev 14557)
@@ -70,6 +70,7 @@
 	m_parentobj = 0;
 	
 	if (m_object){
+		m_object->RegisterActuator(this);
 		KX_GameObject* curobj = (KX_GameObject*) GetParent();
 
 		m_parentobj = curobj->GetParent(); // check if the object is parented 
@@ -176,12 +177,31 @@
 
 
 KX_TrackToActuator::~KX_TrackToActuator()
-{ 
-	// there's nothing to be done here, really....
+{
+	if (m_object)
+		m_object->UnregisterActuator(this);
 } /* end of destructor */
 
+void KX_TrackToActuator::ProcessReplica()
+{
+	// the replica is tracking the same object => register it
+	if (m_object)
+		m_object->RegisterActuator(this);
+	SCA_IActuator::ProcessReplica();
+}
 
 
+bool KX_TrackToActuator::UnlinkObject(SCA_IObject* clientobj)
+{
+	if (clientobj == m_object)
+	{
+		// this object is being deleted, we cannot continue to track it.
+		m_object = NULL;
+		return true;
+	}
+	return false;
+}
+
 bool KX_TrackToActuator::Update(double curtime, bool frame)
 {
 	bool result = false;	
@@ -430,8 +450,11 @@
 	PyObject* gameobj;
 	if (PyArg_ParseTuple(args, "O!", &KX_GameObject::Type, &gameobj))
 	{
+		if (m_object != NULL)
+			m_object->UnregisterActuator(this);
 		m_object = (SCA_IObject*)gameobj;
-
+		if (m_object)
+			m_object->RegisterActuator(this);
 		Py_Return;
 	}
 	PyErr_Clear();
@@ -439,8 +462,11 @@
 	char* objectname;
 	if (PyArg_ParseTuple(args, "s", &objectname))
 	{
+		if (m_object != NULL)
+			m_object->UnregisterActuator(this);
 		m_object= static_cast<SCA_IObject*>(SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(objectname)));
-		
+		if (m_object)
+			m_object->RegisterActuator(this);
 		Py_Return;
 	}
 	

Modified: trunk/blender/source/gameengine/Ketsji/KX_TrackToActuator.h
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_TrackToActuator.h	2008-04-26 14:02:41 UTC (rev 14556)
+++ trunk/blender/source/gameengine/Ketsji/KX_TrackToActuator.h	2008-04-26 20:41:25 UTC (rev 14557)
@@ -66,6 +66,8 @@
 		return replica;
 	};
 
+	virtual void ProcessReplica();
+	virtual bool UnlinkObject(SCA_IObject* clientobj);
 	virtual bool Update(double curtime, bool frame);
 
 	/* Python part */





More information about the Bf-blender-cvs mailing list