doxygen: prevent GPL license block from being parsed as doxygen comment.
[blender.git] / source / gameengine / GameLogic / SCA_PropertySensor.cpp
index 19ee852..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),
@@ -111,7 +111,7 @@ CValue* SCA_PropertySensor::GetReplica()
 {
        SCA_PropertySensor* replica = new SCA_PropertySensor(*this);
        // m_range_expr must be recalculated on replica!
-       CValue::AddDataToReplica(replica);
+       replica->ProcessReplica();
        replica->Init();
 
        replica->m_range_expr = NULL;
@@ -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,209 +306,80 @@ CValue* SCA_PropertySensor::FindIdentifier(const STR_String& identifiername)
        return  GetParent()->FindIdentifier(identifiername);
 }
 
-bool SCA_PropertySensor::validValueForProperty(char *val, STR_String &prop)
-{
-       bool result = true;
-       /*  There is no type checking at this moment, unfortunately...           */
-       return result;
-}
+#ifdef WITH_PYTHON
 
 /* ------------------------------------------------------------------------- */
 /* Python functions                                                          */
 /* ------------------------------------------------------------------------- */
 
-/* Integration hooks ------------------------------------------------------- */
-PyTypeObject SCA_PropertySensor::Type = {
-       PyObject_HEAD_INIT(&PyType_Type)
-       0,
-       "SCA_PropertySensor",
-       sizeof(SCA_PropertySensor),
-       0,
-       PyDestructor,
-       0,
-       __getattr,
-       __setattr,
-       0, //&MyPyCompare,
-       __repr,
-       0, //&cvalue_as_number,
-       0,
-       0,
-       0,
-       0
-};
-
-PyParentObject SCA_PropertySensor::Parents[] = {
-       &SCA_PropertySensor::Type,
-       &SCA_ISensor::Type,
-       &SCA_ILogicBrick::Type,
-       &CValue::Type,
-       NULL
-};
-
-PyMethodDef SCA_PropertySensor::Methods[] = {
-       //Deprecated functions ------>
-       {"getType", (PyCFunction) SCA_PropertySensor::sPyGetType, METH_VARARGS, (PY_METHODCHAR)GetType_doc},
-       {"setType", (PyCFunction) SCA_PropertySensor::sPySetType, METH_VARARGS, (PY_METHODCHAR)SetType_doc},
-       {"getProperty", (PyCFunction) SCA_PropertySensor::sPyGetProperty, METH_VARARGS, (PY_METHODCHAR)GetProperty_doc},
-       {"setProperty", (PyCFunction) SCA_PropertySensor::sPySetProperty, METH_VARARGS, (PY_METHODCHAR)SetProperty_doc},
-       {"getValue", (PyCFunction) SCA_PropertySensor::sPyGetValue, METH_VARARGS, (PY_METHODCHAR)GetValue_doc},
-       {"setValue", (PyCFunction) SCA_PropertySensor::sPySetValue, METH_VARARGS, (PY_METHODCHAR)SetValue_doc},
-       //<----- Deprecated
-       {NULL,NULL} //Sentinel
-};
-
-PyObject* SCA_PropertySensor::_getattr(const STR_String& attr) {
-       if (attr == "type") {
-               return PyInt_FromLong(m_checktype);
-       }
-       if (attr == "property") {
-               return PyString_FromString(m_checkpropname);
-       }
-       if (attr == "value") {
-               return PyString_FromString(m_checkpropval);
-       }
-       _getattr_up(SCA_ISensor); /* implicit return! */
-}
+int SCA_PropertySensor::validValueForProperty(void *self, const PyAttributeDef*)
+{
+       /*  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       */
 
-int SCA_PropertySensor::_setattr(const STR_String& attr, PyObject *value) {
-       if (PyInt_Check(value)) {
-               int ival = PyInt_AsLong(value);
-               if (attr == "type") {
-                       if ((ival <= KX_PROPSENSOR_NODEF) || (ival >= KX_PROPSENSOR_MAX)) {
-                               PyErr_SetString(PyExc_ValueError, "type out of range");
-                               return 1;
-                       }
-                       m_checktype =  ival;
-               }
-               return 0;
-       }
-       if (PyString_Check(value)) {
-               char* sval = PyString_AsString(value);
-               if (attr == "property") {
-                       CValue *prop = FindIdentifier(STR_String(sval));
-                       bool error = prop->IsError();
-                       prop->Release();
-                       if (error) {
-                               PyErr_SetString(PyExc_ValueError, "string does not correspond to a property");
-                               return 1;
-                       }
-                       m_checkpropname = sval;
-               } else if (attr == "value") {
-                       if (!validValueForProperty(sval, m_checkpropname)) {
-                               PyErr_SetString(PyExc_ValueError, "string does not represent a suitable value for the property");
-                               return 1;
-                       }
-                       m_checkpropval = sval;
-               }       
-               return 0;
-       }
-       return SCA_ISensor::_setattr(attr, value);
+       /*  There is no type checking at this moment, unfortunately...           */
+       return 0;
 }
 
-/* 1. getType */
-const char SCA_PropertySensor::GetType_doc[] = 
-"getType()\n"
-"\tReturns the type of check this sensor performs.\n";
-PyObject* SCA_PropertySensor::PyGetType(PyObject* self, PyObject* args, PyObject* kwds)
+int SCA_PropertySensor::validValueForIntervalProperty(void *self, const PyAttributeDef*)
 {
-       ShowDeprecationWarning("getType()", "the type property");
-       return PyInt_FromLong(m_checktype);
-}
+       SCA_PropertySensor*     sensor = reinterpret_cast<SCA_PropertySensor*>(self);
 
-/* 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* self, PyObject* args, PyObject* kwds) 
-{
-       ShowDeprecationWarning("setType()", "the type property");
-       int typeArg;
-       
-       if (!PyArg_ParseTuple(args, "i", &typeArg)) {
-               return NULL;
-       }
-       
-       if ( (typeArg > KX_PROPSENSOR_NODEF) 
-                && (typeArg < KX_PROPSENSOR_MAX) ) {
-               m_checktype =  typeArg;
+       if (sensor->m_checktype==KX_PROPSENSOR_INTERVAL)
+       {
+               sensor->PrecalculateRangeExpression();
        }
-       
-       Py_Return;
+       return 0;
 }
 
-/* 3. getProperty */
-const char SCA_PropertySensor::GetProperty_doc[] = 
-"getProperty()\n"
-"\tReturn the property with which the sensor operates.\n";
-PyObject* SCA_PropertySensor::PyGetProperty(PyObject* self, PyObject* args, PyObject* kwds) 
+int SCA_PropertySensor::modeChange(void *self, const PyAttributeDef* attrdef)
 {
-       ShowDeprecationWarning("getProperty()", "the 'property' property");
-       return PyString_FromString(m_checkpropname);
-}
+       SCA_PropertySensor*     sensor = reinterpret_cast<SCA_PropertySensor*>(self);
 
-/* 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* self, PyObject* args, PyObject* kwds) 
-{
-       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", &propNameArg)) {
-               return NULL;
-       }
-
-       CValue *prop = FindIdentifier(STR_String(propNameArg));
-       if (!prop->IsError()) {
-               m_checkpropname = propNameArg;
-       } else {
-               ; /* error: bad property name */
+       if (sensor->m_checktype==KX_PROPSENSOR_INTERVAL)
+       {
+               sensor->PrecalculateRangeExpression();
        }
-       prop->Release();
-       Py_Return;
+       return 0;
 }
 
-/* 5. getValue */
-const char SCA_PropertySensor::GetValue_doc[] = 
-"getValue()\n"
-"\tReturns the value with which the sensor operates.\n";
-PyObject* SCA_PropertySensor::PyGetValue(PyObject* self, PyObject* args, PyObject* kwds) 
-{
-       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* self, PyObject* args, PyObject* kwds) 
-{
-       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;
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_PropertySensor::Type = {
+       PyVarObject_HEAD_INIT(NULL, 0)
+       "SCA_PropertySensor",
+       sizeof(PyObjectPlus_Proxy),
+       0,
+       py_base_dealloc,
+       0,
+       0,
+       0,
+       0,
+       py_base_repr,
+       0,0,0,0,0,0,0,0,0,
+       Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+       0,0,0,0,0,0,0,
+       Methods,
+       0,
+       0,
+       &SCA_ISensor::Type,
+       0,0,0,0,0,0,
+       py_base_new
+};
 
-       if(!PyArg_ParseTuple(args, "s", &propValArg)) {
-               return NULL;
-       }
+PyMethodDef SCA_PropertySensor::Methods[] = {
+       {NULL,NULL} //Sentinel
+};
 
-       if (validValueForProperty(propValArg, m_checkpropname)) {
-               m_checkpropval = propValArg;
-       }       
+PyAttributeDef SCA_PropertySensor::Attributes[] = {
+       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
+};
 
-       Py_Return;
-}
+#endif // WITH_PYTHON
 
 /* eof */