Index: source/gameengine/GameLogic/SCA_RandomActuator.cpp =================================================================== --- source/gameengine/GameLogic/SCA_RandomActuator.cpp (r‚vision 13929) +++ source/gameengine/GameLogic/SCA_RandomActuator.cpp (copie de travail) @@ -61,6 +61,7 @@ m_parameter2(para2), m_distribution(mode) { + // m_base is never deleted, probably a memory leak! m_base = new SCA_RandomNumberGenerator(seed); m_counter = 0; enforceConstraints(); @@ -78,6 +79,7 @@ CValue* SCA_RandomActuator::GetReplica() { SCA_RandomActuator* replica = new SCA_RandomActuator(*this); + // replication just copy the m_base pointer => common random generator replica->ProcessReplica(); CValue::AddDataToReplica(replica); @@ -432,12 +434,12 @@ CValue* prop = GetParent()->FindIdentifier(nameArg); - if (prop) { + if (!prop->IsError()) { m_propname = nameArg; - prop->Release(); } else { ; /* not found ... */ } + prop->Release(); Py_Return; } Index: source/gameengine/GameLogic/SCA_ISensor.h =================================================================== --- source/gameengine/GameLogic/SCA_ISensor.h (r‚vision 13929) +++ source/gameengine/GameLogic/SCA_ISensor.h (copie de travail) @@ -97,6 +97,11 @@ bool negmode, int freq); + /** Release sensor + * For property sensor, it is used to release the pre-calculated expression + * so that self references are removed before the sensor itself is released + */ + virtual void Delete() { Release(); } /** Set inversion of pulses on or off. */ void SetInvert(bool inv); Index: source/gameengine/GameLogic/SCA_PropertySensor.h =================================================================== --- source/gameengine/GameLogic/SCA_PropertySensor.h (r‚vision 13929) +++ source/gameengine/GameLogic/SCA_PropertySensor.h (copie de travail) @@ -77,6 +77,7 @@ KX_PROPSENSOR_TYPE checktype, PyTypeObject* T=&Type ); + virtual void Delete(); virtual ~SCA_PropertySensor(); virtual CValue* GetReplica(); void PrecalculateRangeExpression(); Index: source/gameengine/GameLogic/SCA_PropertySensor.cpp =================================================================== --- source/gameengine/GameLogic/SCA_PropertySensor.cpp (r‚vision 13929) +++ source/gameengine/GameLogic/SCA_PropertySensor.cpp (copie de travail) @@ -66,11 +66,11 @@ //CValue* resultval = m_rightexpr->Calculate(); CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname); - if (orgprop) + if (!orgprop->IsError()) { m_previoustext = orgprop->GetText(); - orgprop->Release(); } + orgprop->Release(); if (m_checktype==KX_PROPSENSOR_INTERVAL) { @@ -82,17 +82,29 @@ void SCA_PropertySensor::PrecalculateRangeExpression() { CParser pars; + //The context is needed to retrieve the property at runtime but it creates + //loop of references pars.SetContext(this->AddRef()); STR_String checkstr = "(" + m_checkpropval + " <= " + m_checkpropname + ") && ( " + m_checkpropname + " <= " - + m_checkpropmaxval; + + m_checkpropmaxval + ")"; m_range_expr = pars.ProcessText(checkstr); } +// Forced deletion of precalculated range expression to break reference loop +// Use this function when you know that you won't use the sensor anymore +void SCA_PropertySensor::Delete() +{ + if (m_range_expr) + { + m_range_expr->Release(); + m_range_expr = NULL; + } + Release(); +} - CValue* SCA_PropertySensor::GetReplica() { SCA_PropertySensor* replica = new SCA_PropertySensor(*this); @@ -164,7 +176,7 @@ case KX_PROPSENSOR_EQUAL: { CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname); - if (orgprop) + if (!orgprop->IsError()) { STR_String testprop = orgprop->GetText(); // Force strings to upper case, to avoid confusion in @@ -177,9 +189,8 @@ } else { result = (orgprop->GetText() == m_checkpropval); } - orgprop->Release(); - } + orgprop->Release(); if (reverse) result = !result; @@ -244,15 +255,15 @@ { CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname); - if (orgprop) + if (!orgprop->IsError()) { if (m_previoustext != orgprop->GetText()) { m_previoustext = orgprop->GetText(); result = true; } - orgprop->Release(); } + orgprop->Release(); //cout << " \nSens:Prop:changed!"; /* need implementation here!!! */ break; @@ -388,12 +399,13 @@ return NULL; } - if (FindIdentifier(STR_String(propNameArg))) { + CValue *prop = FindIdentifier(STR_String(propNameArg)); + if (!prop->IsError()) { m_checkpropname = propNameArg; } else { ; /* error: bad property name */ } - + prop->Release(); Py_Return; } Index: source/gameengine/Ketsji/KX_TouchSensor.cpp =================================================================== --- source/gameengine/Ketsji/KX_TouchSensor.cpp (r‚vision 13929) +++ source/gameengine/Ketsji/KX_TouchSensor.cpp (copie de travail) @@ -274,10 +274,10 @@ if (!prop->IsError()) { m_touchedpropname = nameArg; - prop->Release(); } else { ; /* not found ... */ } + prop->Release(); Py_Return; } @@ -351,8 +351,8 @@ CValue* val = m_colliders->GetValue(i)->FindIdentifier(m_touchedpropname); if (!val->IsError()) { newList->Add(m_colliders->GetValue(i)->AddRef()); - val->Release(); } + val->Release(); } i++; Index: source/gameengine/GameLogic/SCA_IObject.cpp =================================================================== --- source/gameengine/GameLogic/SCA_IObject.cpp (r‚vision 13929) +++ source/gameengine/GameLogic/SCA_IObject.cpp (copie de travail) @@ -55,7 +55,9 @@ SCA_SensorList::iterator its; for (its = m_sensors.begin(); !(its == m_sensors.end()); ++its) { - ((CValue*)(*its))->Release(); + //Use Delete for sensor to ensure proper cleaning + (*its)->Delete(); + //((CValue*)(*its))->Release(); } SCA_ControllerList::iterator itc; for (itc = m_controllers.begin(); !(itc == m_controllers.end()); ++itc)