unknown property fixed in sensor/actuators
authorBenoit Bolsee <benoit.bolsee@online.be>
Sat, 1 Mar 2008 19:05:41 +0000 (19:05 +0000)
committerBenoit Bolsee <benoit.bolsee@online.be>
Sat, 1 Mar 2008 19:05:41 +0000 (19:05 +0000)
source/gameengine/GameLogic/SCA_IObject.cpp
source/gameengine/GameLogic/SCA_ISensor.h
source/gameengine/GameLogic/SCA_PropertySensor.cpp
source/gameengine/GameLogic/SCA_PropertySensor.h
source/gameengine/GameLogic/SCA_RandomActuator.cpp
source/gameengine/Ketsji/KX_TouchSensor.cpp

index b1d210fd1c1a8bb7573c664710adeabc7cba0211..8971135ecdaee740d1ccaa0ba83d81fd82a762ee 100644 (file)
@@ -55,7 +55,9 @@ SCA_IObject::~SCA_IObject()
        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)
index 469ea3995b84001c4c34d343fa4b89ceaad67bda..8de4480cf2e41d1caa0d06d78bc1feaa4090270a 100644 (file)
@@ -97,6 +97,11 @@ public:
                                          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 09332b870c92ca8f16937b01bcdd007aacb179d4..cdd0666947e8d6e3e51cdcefa2cdeaa90f15e953 100644 (file)
@@ -66,11 +66,11 @@ SCA_PropertySensor::SCA_PropertySensor(SCA_EventManager* eventmgr,
        //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,16 +82,28 @@ SCA_PropertySensor::SCA_PropertySensor(SCA_EventManager* eventmgr,
 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()
 {
@@ -164,7 +176,7 @@ bool        SCA_PropertySensor::CheckPropertyCondition()
        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 @@ bool        SCA_PropertySensor::CheckPropertyCondition()
                                } else {
                                        result = (orgprop->GetText() == m_checkpropval);
                                }
-                               orgprop->Release();
-
                        }
+                       orgprop->Release();
 
                        if (reverse)
                                result = !result;
@@ -244,15 +255,15 @@ bool      SCA_PropertySensor::CheckPropertyCondition()
                {
                        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 @@ PyObject* SCA_PropertySensor::PySetProperty(PyObject* self, PyObject* args, PyOb
                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 0ebcacdb21a539a4d27be18f2c0ed7c203b0d154..77cc3dc8a5c165fe79195471139c71a0f9d6670c 100644 (file)
@@ -77,6 +77,7 @@ public:
                                          KX_PROPSENSOR_TYPE checktype,
                                          PyTypeObject* T=&Type );
        
+       virtual void Delete();
        virtual ~SCA_PropertySensor();
        virtual CValue* GetReplica();
        void    PrecalculateRangeExpression();
index 474ad08eee3b1e50a57b7116d185da3107c1ce08..b0e69076a3ed72308d519609bd41130b17658711 100644 (file)
@@ -61,6 +61,7 @@ SCA_RandomActuator::SCA_RandomActuator(SCA_IObject *gameobj,
          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 @@ SCA_RandomActuator::~SCA_RandomActuator()
 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 @@ PyObject* SCA_RandomActuator::PySetProperty(PyObject* self, PyObject* args, PyOb
 
        CValue* prop = GetParent()->FindIdentifier(nameArg);
 
-       if (prop) {
+       if (!prop->IsError()) {
                m_propname = nameArg;
-               prop->Release();
        } else {
                ; /* not found ... */
        }
+       prop->Release();
        
        Py_Return;
 }
index 5b013e75e4e3799729536dc3d8f8e6b54c08af29..7e3904113ab0f574010c89c78605f209459f68d0 100644 (file)
@@ -274,10 +274,10 @@ PyObject* KX_TouchSensor::PySetProperty(PyObject* self,
 
        if (!prop->IsError()) {
                m_touchedpropname = nameArg;
-               prop->Release();
        } else {
                ; /* not found ... */
        }
+       prop->Release();
        
        Py_Return;
 }
@@ -351,8 +351,8 @@ PyObject* KX_TouchSensor::PyGetHitObjectList(PyObject* self,
                                CValue* val = m_colliders->GetValue(i)->FindIdentifier(m_touchedpropname);
                                if (!val->IsError()) {
                                        newList->Add(m_colliders->GetValue(i)->AddRef());
-                                       val->Release();
                                }
+                               val->Release();
                        }
                        
                        i++;