doxygen: prevent GPL license block from being parsed as doxygen comment.
[blender.git] / source / gameengine / GameLogic / SCA_PropertySensor.cpp
index c78283d..0a0362e 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * Property sensor
  *
  * $Id$
@@ -17,7 +17,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
  * All rights reserved.
@@ -29,6 +29,8 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
+#include <stddef.h>
+
 #include <iostream>
 #include "SCA_PropertySensor.h"
 #include "Operator2Expr.h"
 #include "StringValue.h"
 #include "SCA_EventManager.h"
 #include "SCA_LogicManager.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "BoolValue.h"
+#include "FloatValue.h"
+#include <stdio.h>
 
 SCA_PropertySensor::SCA_PropertySensor(SCA_EventManager* eventmgr,
                                                                         SCA_IObject* gameobj,
                                                                         const STR_String& propname,
                                                                         const STR_String& propval,
                                                                         const STR_String& propmaxval,
-                                                                        KX_PROPSENSOR_TYPE checktype,
-                                                                        PyTypeObject* T )
-       : SCA_ISensor(gameobj,eventmgr,T),
+                                                                        KX_PROPSENSOR_TYPE checktype)
+       : SCA_ISensor(gameobj,eventmgr),
          m_checktype(checktype),
          m_checkpropval(propval),
          m_checkpropmaxval(propmaxval),
@@ -152,7 +152,7 @@ SCA_PropertySensor::~SCA_PropertySensor()
 
 
 
-bool SCA_PropertySensor::Evaluate(CValue* event)
+bool SCA_PropertySensor::Evaluate()
 {
        bool result = CheckPropertyCondition();
        bool reset = m_reset && m_level;
@@ -182,17 +182,30 @@ bool      SCA_PropertySensor::CheckPropertyCondition()
                        CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
                        if (!orgprop->IsError())
                        {
-                               STR_String testprop = orgprop->GetText();
+                               const STR_String& testprop = orgprop->GetText();
                                // Force strings to upper case, to avoid confusion in
                                // bool tests. It's stupid the prop's identity is lost
                                // on the way here...
-                               if ((testprop == "TRUE") || (testprop == "FALSE")) {
-                                       STR_String checkprop = m_checkpropval;
-                                       checkprop.Upper();
-                                       result = (testprop == checkprop);
-                               } else {
-                                       result = (orgprop->GetText() == m_checkpropval);
+                               if ((&testprop == &CBoolValue::sTrueString) || (&testprop == &CBoolValue::sFalseString)) {
+                                       m_checkpropval.Upper();
                                }
+                               result = (testprop == m_checkpropval);
+                               
+                               /* Patch: floating point values cant use strings usefully since you can have "0.0" == "0.0000"
+                                * this could be made into a generic Value class function for comparing values with a string.
+                                */
+                               if(result==false && dynamic_cast<CFloatValue *>(orgprop) != NULL) {
+                                       float f;
+                                       
+                                       if(EOF == sscanf(m_checkpropval.ReadPtr(), "%f", &f))
+                                       {
+                                               //error
+                                       } 
+                                       else {
+                                               result = (f == ((CFloatValue *)orgprop)->GetFloat());
+                                       }
+                               }
+                               /* end patch */
                        }
                        orgprop->Release();
 
@@ -232,8 +245,8 @@ bool        SCA_PropertySensor::CheckPropertyCondition()
                                        CValue* vallie = m_range_expr->Calculate();
                                        if (vallie)
                                        {
-                                               STR_String errtext = vallie->GetText();
-                                               if (errtext == "TRUE")
+                                               const STR_String& errtext = vallie->GetText();
+                                               if (&errtext == &CBoolValue::sTrueString)
                                                {
                                                        result = true;
                                                } else
@@ -293,26 +306,47 @@ CValue* SCA_PropertySensor::FindIdentifier(const STR_String& identifiername)
        return  GetParent()->FindIdentifier(identifiername);
 }
 
+#ifdef WITH_PYTHON
+
+/* ------------------------------------------------------------------------- */
+/* Python functions                                                          */
+/* ------------------------------------------------------------------------- */
+
 int SCA_PropertySensor::validValueForProperty(void *self, const PyAttributeDef*)
 {
-       bool result = true;
+       /*  If someone actually do type checking please make sure the 'max' and 'min'
+               are checked as well (currently they are calling the PrecalculateRangeExpression
+               function directly       */
+
        /*  There is no type checking at this moment, unfortunately...           */
-       return result;
+       return 0;
 }
 
-/* ------------------------------------------------------------------------- */
-/* Python functions                                                          */
-/* ------------------------------------------------------------------------- */
+int SCA_PropertySensor::validValueForIntervalProperty(void *self, const PyAttributeDef*)
+{
+       SCA_PropertySensor*     sensor = reinterpret_cast<SCA_PropertySensor*>(self);
+
+       if (sensor->m_checktype==KX_PROPSENSOR_INTERVAL)
+       {
+               sensor->PrecalculateRangeExpression();
+       }
+       return 0;
+}
+
+int SCA_PropertySensor::modeChange(void *self, const PyAttributeDef* attrdef)
+{
+       SCA_PropertySensor*     sensor = reinterpret_cast<SCA_PropertySensor*>(self);
+
+       if (sensor->m_checktype==KX_PROPSENSOR_INTERVAL)
+       {
+               sensor->PrecalculateRangeExpression();
+       }
+       return 0;
+}
 
 /* Integration hooks ------------------------------------------------------- */
 PyTypeObject SCA_PropertySensor::Type = {
-#if (PY_VERSION_HEX >= 0x02060000)
        PyVarObject_HEAD_INIT(NULL, 0)
-#else
-       /* python 2.5 and below */
-       PyObject_HEAD_INIT( NULL )  /* required py macro */
-       0,                          /* ob_size */
-#endif
        "SCA_PropertySensor",
        sizeof(PyObjectPlus_Proxy),
        0,
@@ -322,158 +356,30 @@ PyTypeObject SCA_PropertySensor::Type = {
        0,
        0,
        py_base_repr,
-       0,0,0,0,0,0,
-       py_base_getattro,
-       py_base_setattro,
        0,0,0,0,0,0,0,0,0,
-       Methods
-};
-
-PyParentObject SCA_PropertySensor::Parents[] = {
-       &SCA_PropertySensor::Type,
+       Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+       0,0,0,0,0,0,0,
+       Methods,
+       0,
+       0,
        &SCA_ISensor::Type,
-       &SCA_ILogicBrick::Type,
-       &CValue::Type,
-       NULL
+       0,0,0,0,0,0,
+       py_base_new
 };
 
 PyMethodDef SCA_PropertySensor::Methods[] = {
-       //Deprecated functions ------>
-       {"getType", (PyCFunction) SCA_PropertySensor::sPyGetType, METH_NOARGS, (PY_METHODCHAR)GetType_doc},
-       {"setType", (PyCFunction) SCA_PropertySensor::sPySetType, METH_VARARGS, (PY_METHODCHAR)SetType_doc},
-       {"getProperty", (PyCFunction) SCA_PropertySensor::sPyGetProperty, METH_NOARGS, (PY_METHODCHAR)GetProperty_doc},
-       {"setProperty", (PyCFunction) SCA_PropertySensor::sPySetProperty, METH_VARARGS, (PY_METHODCHAR)SetProperty_doc},
-       {"getValue", (PyCFunction) SCA_PropertySensor::sPyGetValue, METH_NOARGS, (PY_METHODCHAR)GetValue_doc},
-       {"setValue", (PyCFunction) SCA_PropertySensor::sPySetValue, METH_VARARGS, (PY_METHODCHAR)SetValue_doc},
-       //<----- Deprecated
        {NULL,NULL} //Sentinel
 };
 
 PyAttributeDef SCA_PropertySensor::Attributes[] = {
-       KX_PYATTRIBUTE_INT_RW("type",KX_PROPSENSOR_NODEF,KX_PROPSENSOR_MAX-1,false,SCA_PropertySensor,m_checktype),
-       KX_PYATTRIBUTE_STRING_RW_CHECK("property",0,100,false,SCA_PropertySensor,m_checkpropname,CheckProperty),
+       KX_PYATTRIBUTE_INT_RW_CHECK("mode",KX_PROPSENSOR_NODEF,KX_PROPSENSOR_MAX-1,false,SCA_PropertySensor,m_checktype,modeChange),
+       KX_PYATTRIBUTE_STRING_RW_CHECK("propName",0,100,false,SCA_PropertySensor,m_checkpropname,CheckProperty),
        KX_PYATTRIBUTE_STRING_RW_CHECK("value",0,100,false,SCA_PropertySensor,m_checkpropval,validValueForProperty),
+       KX_PYATTRIBUTE_STRING_RW_CHECK("min",0,100,false,SCA_PropertySensor,m_checkpropval,validValueForIntervalProperty),
+       KX_PYATTRIBUTE_STRING_RW_CHECK("max",0,100,false,SCA_PropertySensor,m_checkpropmaxval,validValueForIntervalProperty),
        { NULL }        //Sentinel
 };
 
-
-PyObject* SCA_PropertySensor::py_getattro(PyObject *attr) {
-       py_getattro_up(SCA_ISensor);
-}
-
-PyObject* SCA_PropertySensor::py_getattro_dict() {
-       py_getattro_dict_up(SCA_ISensor);
-}
-
-int SCA_PropertySensor::py_setattro(PyObject *attr, PyObject *value) {
-       py_setattro_up(SCA_ISensor);
-}
-
-/* 1. getType */
-const char SCA_PropertySensor::GetType_doc[] = 
-"getType()\n"
-"\tReturns the type of check this sensor performs.\n";
-PyObject* SCA_PropertySensor::PyGetType()
-{
-       ShowDeprecationWarning("getType()", "the type property");
-       return PyInt_FromLong(m_checktype);
-}
-
-/* 2. setType */
-const char SCA_PropertySensor::SetType_doc[] = 
-"setType(type)\n"
-"\t- type: KX_PROPSENSOR_EQUAL, KX_PROPSENSOR_NOTEQUAL,\n"
-"\t        KX_PROPSENSOR_INTERVAL, KX_PROPSENSOR_CHANGED,\n"
-"\t        or KX_PROPSENSOR_EXPRESSION.\n"
-"\tSet the type of check to perform.\n";
-PyObject* SCA_PropertySensor::PySetType(PyObject* args) 
-{
-       ShowDeprecationWarning("setType()", "the type property");
-       int typeArg;
-       
-       if (!PyArg_ParseTuple(args, "i:setType", &typeArg)) {
-               return NULL;
-       }
-       
-       if ( (typeArg > KX_PROPSENSOR_NODEF) 
-                && (typeArg < KX_PROPSENSOR_MAX) ) {
-               m_checktype =  typeArg;
-       }
-       
-       Py_RETURN_NONE;
-}
-
-/* 3. getProperty */
-const char SCA_PropertySensor::GetProperty_doc[] = 
-"getProperty()\n"
-"\tReturn the property with which the sensor operates.\n";
-PyObject* SCA_PropertySensor::PyGetProperty() 
-{
-       ShowDeprecationWarning("getProperty()", "the 'property' property");
-       return PyString_FromString(m_checkpropname);
-}
-
-/* 4. setProperty */
-const char SCA_PropertySensor::SetProperty_doc[] = 
-"setProperty(name)\n"
-"\t- name: string\n"
-"\tSets the property with which to operate. If there is no property\n"
-"\tof this name, the call is ignored.\n";
-PyObject* SCA_PropertySensor::PySetProperty(PyObject* args) 
-{
-       ShowDeprecationWarning("setProperty()", "the 'property' property");
-       /* We should query whether the name exists. Or should we create a prop   */
-       /* on the fly?                                                           */
-       char *propNameArg = NULL;
-
-       if (!PyArg_ParseTuple(args, "s:setProperty", &propNameArg)) {
-               return NULL;
-       }
-
-       CValue *prop = FindIdentifier(STR_String(propNameArg));
-       if (!prop->IsError()) {
-               m_checkpropname = propNameArg;
-       } else {
-               ; /* error: bad property name */
-       }
-       prop->Release();
-       Py_RETURN_NONE;
-}
-
-/* 5. getValue */
-const char SCA_PropertySensor::GetValue_doc[] = 
-"getValue()\n"
-"\tReturns the value with which the sensor operates.\n";
-PyObject* SCA_PropertySensor::PyGetValue() 
-{
-       ShowDeprecationWarning("getValue()", "the value property");
-       return PyString_FromString(m_checkpropval);
-}
-
-/* 6. setValue */
-const char SCA_PropertySensor::SetValue_doc[] = 
-"setValue(value)\n"
-"\t- value: string\n"
-"\tSet the value with which the sensor operates. If the value\n"
-"\tis not compatible with the type of the property, the subsequent\n"
-"\t action is ignored.\n";
-PyObject* SCA_PropertySensor::PySetValue(PyObject* args) 
-{
-       ShowDeprecationWarning("setValue()", "the value property");
-       /* Here, we need to check whether the value is 'valid' for this property.*/
-       /* We know that the property exists, or is NULL.                         */
-       char *propValArg = NULL;
-
-       if(!PyArg_ParseTuple(args, "s:setValue", &propValArg)) {
-               return NULL;
-       }
-       STR_String oldval = m_checkpropval;
-       m_checkpropval = propValArg;
-       if (validValueForProperty(m_proxy, NULL)) {
-               m_checkpropval = oldval;
-               return NULL;
-       }       
-       Py_RETURN_NONE;
-}
+#endif // WITH_PYTHON
 
 /* eof */