use contains for ListValue and KX_GameObject types (has_key is deprecated by python)
authorCampbell Barton <ideasman42@gmail.com>
Fri, 12 Jun 2009 12:56:12 +0000 (12:56 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 12 Jun 2009 12:56:12 +0000 (12:56 +0000)
eg.
 if 'prop' in gameOb: ...
 if 'GameOb' in sce.objects: ...

source/gameengine/Expressions/ListValue.cpp
source/gameengine/Ketsji/KX_Camera.cpp
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_Light.cpp

index a0d73c75d60da9cd16f753809d81e9408d6913d7..ea097ddff5b42daf9e49b57188f81d34b5a00946 100644 (file)
@@ -209,6 +209,30 @@ static PyObject *listvalue_buffer_concat(PyObject * self, PyObject * other)
        return listval_new->NewProxy(true); /* python owns this list */
 }
 
+static int listvalue_buffer_contains(PyObject *self_v, PyObject *value)
+{
+       CListValue *self= static_cast<CListValue *>(BGE_PROXY_REF(self_v));
+       
+       if (self==NULL) {
+               PyErr_SetString(PyExc_SystemError, "val in CList, "BGE_PROXY_ERROR_MSG);
+               return -1;
+       }
+       
+       if (PyString_Check(value)) {
+               if (self->FindValue((const char *)PyString_AsString(value))) {
+                       return 1;
+               }
+       }
+       else if (BGE_PROXY_CHECK_TYPE(value)) { /* not dict like at all but this worked before __contains__ was used */
+               CValue *item= static_cast<CValue *>(BGE_PROXY_REF(value));
+               for (int i=0; i < self->GetCount(); i++)
+                       if (self->GetValue(i) == item) // Com
+                               return 1;
+               
+       } // not using CheckEqual
+       
+       return 0;
+}
 
 
 static  PySequenceMethods listvalue_as_sequence = {
@@ -225,6 +249,7 @@ static  PySequenceMethods listvalue_as_sequence = {
        NULL, /*sq_ass_item*/
        NULL, /*sq_ass_slice*/
 #endif
+       (objobjproc)listvalue_buffer_contains,  /* sq_contains */
 };
 
 
@@ -264,7 +289,9 @@ PyTypeObject CListValue::Type = {
        0,
        py_base_getattro,
        py_base_setattro,
-       0,0,0,0,0,0,0,0,0,
+       0,
+       Py_TPFLAGS_DEFAULT,
+       0,0,0,0,0,0,0,
        Methods
 };
 
@@ -499,7 +526,7 @@ PyObject* CListValue::Pyreverse()
 bool CListValue::CheckEqual(CValue* first,CValue* second)
 {
        bool result = false;
-
+       
        CValue* eqval =  ((CValue*)first)->Calc(VALUE_EQL_OPERATOR,(CValue*)second);
        
        if (eqval==NULL)
@@ -528,7 +555,7 @@ PyObject* CListValue::Pyindex(PyObject *value)
        for (int i=0;i<numelem;i++)
        {
                CValue* elem =                  GetValue(i);
-               if (CheckEqual(checkobj,elem))
+               if (checkobj==elem || CheckEqual(checkobj,elem))
                {
                        result = PyInt_FromLong(i);
                        break;
@@ -560,7 +587,7 @@ PyObject* CListValue::Pycount(PyObject* value)
        for (int i=0;i<numelem;i++)
        {
                CValue* elem =                  GetValue(i);
-               if (CheckEqual(checkobj,elem))
+               if (checkobj==elem || CheckEqual(checkobj,elem))
                {
                        numfound ++;
                }
index ba4d6e22872685cece24f882fdac4543369ac1bc..40f6c99c03c6d924154ef7ef238f1a08ff94b1da 100644 (file)
@@ -547,12 +547,15 @@ PyTypeObject KX_Camera::Type = {
                0,
                0,
                py_base_repr,
-               0,0,
+               0,
+               &KX_GameObject::Sequence,
                &KX_GameObject::Mapping,
                0,0,0,
                py_base_getattro,
                py_base_setattro,
-               0,0,0,0,0,0,0,0,0,
+               0,
+               Py_TPFLAGS_DEFAULT,
+               0,0,0,0,0,0,0,
                Methods
 };
 
index fdab34c13a91419d70cf80204f205f1e83bb3a9f..b266095c71588a3fddb976e8ce973f8ec6ffdefa 100644 (file)
@@ -1287,7 +1287,7 @@ PyObject* KX_GameObject::PyGetPosition()
        return PyObjectFrom(NodeGetWorldPosition());
 }
 
-PyObject *KX_GameObject::Map_GetItem(PyObject *self_v, PyObject *item)
+static PyObject *Map_GetItem(PyObject *self_v, PyObject *item)
 {
        KX_GameObject* self= static_cast<KX_GameObject*>BGE_PROXY_REF(self_v);
        const char *attr_str= PyString_AsString(item);
@@ -1295,7 +1295,7 @@ PyObject *KX_GameObject::Map_GetItem(PyObject *self_v, PyObject *item)
        PyObject* pyconvert;
        
        if (self==NULL) {
-               PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
+               PyErr_SetString(PyExc_SystemError, "val = gameOb[key]: KX_GameObject, "BGE_PROXY_ERROR_MSG);
                return NULL;
        }
        
@@ -1321,7 +1321,7 @@ PyObject *KX_GameObject::Map_GetItem(PyObject *self_v, PyObject *item)
 }
 
 
-int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val)
+static int Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val)
 {
        KX_GameObject* self= static_cast<KX_GameObject*>BGE_PROXY_REF(self_v);
        const char *attr_str= PyString_AsString(key);
@@ -1329,7 +1329,7 @@ int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val)
                PyErr_Clear();
        
        if (self==NULL) {
-               PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
+               PyErr_SetString(PyExc_SystemError, "gameOb[key] = value: KX_GameObject, "BGE_PROXY_ERROR_MSG);
                return -1;
        }
        
@@ -1409,11 +1409,40 @@ int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val)
        return 0; /* success */
 }
 
-/* Cant set the len otherwise it can evaluate as false */
+static int Seq_Contains(PyObject *self_v, PyObject *value)
+{
+       KX_GameObject* self= static_cast<KX_GameObject*>BGE_PROXY_REF(self_v);
+       
+       if (self==NULL) {
+               PyErr_SetString(PyExc_SystemError, "val in gameOb: KX_GameObject, "BGE_PROXY_ERROR_MSG);
+               return -1;
+       }
+       
+       if(PyString_Check(value) && self->GetProperty(PyString_AsString(value)))
+               return 1;
+       
+       if (self->m_attr_dict && PyDict_GetItem(self->m_attr_dict, value))
+               return 1;
+       
+       return 0;
+}
+
+
 PyMappingMethods KX_GameObject::Mapping = {
        (lenfunc)NULL                                   ,                       /*inquiry mp_length */
-       (binaryfunc)KX_GameObject::Map_GetItem,         /*binaryfunc mp_subscript */
-       (objobjargproc)KX_GameObject::Map_SetItem,      /*objobjargproc mp_ass_subscript */
+       (binaryfunc)Map_GetItem,                /*binaryfunc mp_subscript */
+       (objobjargproc)Map_SetItem,     /*objobjargproc mp_ass_subscript */
+};
+
+PySequenceMethods KX_GameObject::Sequence = {
+       NULL,           /* Cant set the len otherwise it can evaluate as false */
+       NULL,           /* sq_concat */
+       NULL,           /* sq_repeat */
+       NULL,           /* sq_item */
+       NULL,           /* sq_slice */
+       NULL,           /* sq_ass_item */
+       NULL,           /* sq_ass_slice */
+       (objobjproc)Seq_Contains,       /* sq_contains */
 };
 
 PyTypeObject KX_GameObject::Type = {
@@ -1433,12 +1462,15 @@ PyTypeObject KX_GameObject::Type = {
                0,
                0,
                py_base_repr,
-               0,0,
+               0,
+               &Sequence,
                &Mapping,
                0,0,0,
                py_base_getattro,
                py_base_setattro,
-               0,0,0,0,0,0,0,0,0,
+               0,
+               Py_TPFLAGS_DEFAULT,
+               0,0,0,0,0,0,0,
                Methods
 };
 
@@ -2779,16 +2811,11 @@ PyObject* KX_GameObject::Pyget(PyObject *args)
 /* Matches python dict.has_key() */
 PyObject* KX_GameObject::Pyhas_key(PyObject* value)
 {
-       if(PyString_Check(value) && GetProperty(PyString_AsString(value)))
-               Py_RETURN_TRUE;
-       
-       if (m_attr_dict && PyDict_GetItem(m_attr_dict, value))
-               Py_RETURN_TRUE;
-       
-       Py_RETURN_FALSE;
+       // the ONLY error case is invalid data, this is checked by the macro'd static function
+       // that calls this one. but make sure Seq_Contains doesnt add extra errors later on.
+       return PyBool_FromLong(Seq_Contains((PyObject *)this, value));
 }
 
-
 /* --------------------------------------------------------------------- 
  * Some stuff taken from the header
  * --------------------------------------------------------------------- */
index dbdea97031d2e3663d119935d593e539fe55065a..ff5c8a01e6e0739d4c731738d66001065a37dd3d 100644 (file)
@@ -917,10 +917,8 @@ public:
        static PyObject*        pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
        
        /* getitem/setitem */
-       static Py_ssize_t                       Map_Len(PyObject* self);
        static PyMappingMethods Mapping;
-       static PyObject*                        Map_GetItem(PyObject *self_v, PyObject *item);
-       static int                                      Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val);
+       static PySequenceMethods        Sequence;
        
 private :
 
index 274d8f26d785eb72690bb668c5976f8dfd2425d2..ae9e097a96e9fbbb576269bac8eb0ca2ac7f6204 100644 (file)
@@ -293,12 +293,15 @@ PyTypeObject KX_LightObject::Type = {
                0,
                0,
                py_base_repr,
-               0,0,
+               0,
+               &KX_GameObject::Sequence,
                &KX_GameObject::Mapping,
                0,0,0,
                py_base_getattro,
                py_base_setattro,
-               0,0,0,0,0,0,0,0,0,
+               0,
+               Py_TPFLAGS_DEFAULT,
+               0,0,0,0,0,0,0,
                Methods
 };