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
This commit is contained in:
@@ -46,6 +46,15 @@ public:
|
||||
SCA_IActuator(SCA_IObject* gameobj,
|
||||
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
|
||||
|
||||
@@ -62,6 +62,10 @@ SCA_IObject::~SCA_IObject()
|
||||
((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 @@ void SCA_IObject::AddActuator(SCA_IActuator* act)
|
||||
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 @@ void SCA_IObject::ReParentLogic()
|
||||
newactuator->SetActive(false);
|
||||
oldactuators[act++] = newactuator;
|
||||
}
|
||||
// a new object cannot be client of any actuator
|
||||
m_registeredActuators.clear();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ protected:
|
||||
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 @@ public:
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user