BGE Py API
authorCampbell Barton <ideasman42@gmail.com>
Sat, 11 Apr 2009 20:58:09 +0000 (20:58 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 11 Apr 2009 20:58:09 +0000 (20:58 +0000)
- setting the scene attributes would always add to the scenes custom dictionary.
- new CListValue method from_id(id)

so you can store a Game Objects id and use it to get the game object back.

 ob_id = id(gameOb)
 ...
 gameOb = scene.objects.from_id(ob_id)

This is useful because names are not always unique.

source/gameengine/Expressions/ListValue.cpp
source/gameengine/Expressions/ListValue.h
source/gameengine/Expressions/PyObjectPlus.h
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_Scene.h
source/gameengine/PyDoc/CListValue.py

index d0aec645468827e347cd417c850b0739e9b72eb4..16b4fbef6b7a503d9cf22ba5218d52f9f0b6fdee 100644 (file)
@@ -233,6 +233,7 @@ PyMethodDef CListValue::Methods[] = {
        {"reverse", (PyCFunction)CListValue::sPyreverse,METH_NOARGS},
        {"index", (PyCFunction)CListValue::sPyindex,METH_O},
        {"count", (PyCFunction)CListValue::sPycount,METH_O},
+       {"from_id", (PyCFunction)CListValue::sPyfrom_id,METH_O},
        
        {NULL,NULL} //Sentinel
 };
@@ -502,6 +503,34 @@ PyObject* CListValue::Pycount(PyObject* self, PyObject* value)
 
 
 
+PyObject* CListValue::Pyfrom_id(PyObject* self, PyObject* value)
+{
+#if SIZEOF_VOID_P <= SIZEOF_LONG
+#define BGE_ID_TYPE unsigned long
+       BGE_ID_TYPE id= PyLong_AsUnsignedLong(value);
+#else
+#define BGE_ID_TYPE unsigned long long
+       BGE_ID_TYPE id= PyLong_FromUnsignedLongLong(value);
+#endif
+       
+       if (id==-1 && PyErr_Occurred())
+               return NULL;
+
+       int numelem = GetCount();
+       for (int i=0;i<numelem;i++)
+       {
+               if (reinterpret_cast<BGE_ID_TYPE>(static_cast<PyObject*>(m_pValueArray[i])) == id)
+                       return GetValue(i);
+       
+       }
+       PyErr_SetString(PyExc_IndexError, "from_id(#), id not found in CValueList");
+       return NULL;    
+
+}
+
+#undef BGE_ID_TYPE
+
+
 /* --------------------------------------------------------------------- 
  * Some stuff taken from the header
  * --------------------------------------------------------------------- */
index 1c01c2d221d7d6f003aa7ebcb0bf6e0720922b62..6f70acb93674b7a5b6debf6db017bfc13f1c66cc 100644 (file)
@@ -71,6 +71,7 @@ public:
        KX_PYMETHOD_NOARGS(CListValue,reverse);
        KX_PYMETHOD_O(CListValue,index);
        KX_PYMETHOD_O(CListValue,count);
+       KX_PYMETHOD_O(CListValue,from_id);
 
        
 private:
index 786ca1fdc4f87e299a527f38024f9bfcc7db11d1..421684616343ffd9054a6b1a4770886f4468ad52 100644 (file)
@@ -404,9 +404,9 @@ public:
 //       };                            // decref method
        
        virtual PyObject *py_getattro(PyObject *attr);                  // py_getattro method
-       static  PyObject *py_base_getattro(PyObject * PyObj, PyObject *attr)    // This should be the entry in Type. 
+       static  PyObject *py_base_getattro(PyObject * self, PyObject *attr)     // This should be the entry in Type. 
        {
-               return ((PyObjectPlus*) PyObj)->py_getattro(attr); 
+               return ((PyObjectPlus*) self)->py_getattro(attr); 
        }
        
        static PyObject*        py_get_attrdef(void *self, const PyAttributeDef *attrdef);
@@ -419,13 +419,12 @@ public:
        
        virtual int py_delattro(PyObject *attr);
        virtual int py_setattro(PyObject *attr, PyObject *value);               // py_setattro method
-       static  int py_base_setattro(PyObject *PyObj,                   // This should be the entry in Type. 
-                               PyObject *attr, 
-                               PyObject *value)
-       { 
+       static  int py_base_setattro(PyObject *self, PyObject *attr, PyObject *value) // the PyType should reference this
+       {
                if (value==NULL)
-                       return ((PyObjectPlus*) PyObj)->py_delattro(attr);
-               return ((PyObjectPlus*) PyObj)->py_setattro(attr, value);  
+                       return ((PyObjectPlus*) self)->py_delattro(attr);
+               
+               return ((PyObjectPlus*) self)->py_setattro(attr, value); 
        }
        
        virtual PyObject *py_repr(void);                                // py_repr method
index 7842076de66be28c8ac3cbfdca0d06ea219687c9..2f7c1b77794813d76d9adb060d70a2ddf48a0cc3 100644 (file)
@@ -1588,7 +1588,7 @@ PyTypeObject KX_Scene::Type = {
                py_base_repr,
                0,0,0,0,0,0,
                py_base_getattro,
-               py_base_setattro,
+               py_base_setattro_scene, /* unlike almost all other types we need out own because user attributes are supported */
                0,0,0,0,0,0,0,0,0,
                Methods
 };
@@ -1669,11 +1669,9 @@ int KX_Scene::py_delattro(PyObject *attr)
        return 0;
 }
 
+/* py_base_setattro_scene deals with setting the dict, it will run if this returns an error */
 int KX_Scene::py_setattro(PyObject *attr, PyObject *pyvalue)
 {
-       if (!PyDict_SetItem(m_attrlist, attr, pyvalue))
-               return 0;
-
        return PyObjectPlus::py_setattro(attr, pyvalue);
 }
 
index 9f05ddf70c27c5a3f37c9649a29ca444cf0a3ac1..1bdfbd45d20cdfbce34eed2af5539406c2d834be 100644 (file)
@@ -590,6 +590,27 @@ public:
        /* for dir(), python3 uses __dir__() */
        static PyObject*        pyattr_get_dir_dict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
        
+       static int py_base_setattro_scene(PyObject * self, PyObject *attr, PyObject *value)
+       {
+               if (value==NULL)
+                       return ((PyObjectPlus*) self)->py_delattro(attr);
+               
+               int ret= ((PyObjectPlus*) self)->py_setattro(attr, value);
+               
+               if (ret) {
+                       if (!PyDict_SetItem(((KX_Scene *) self)->m_attrlist, attr, value)) {
+                               PyErr_Clear();
+                               ret= 0;
+                       }
+                       else {
+                               ret= -1;
+                       }
+               }
+               
+               return ret;
+       }
+       
+       
 
        virtual PyObject* py_getattro(PyObject *attr); /* name, active_camera, gravity, suspended, viewport, framing, activity_culling, activity_culling_radius */
        virtual int py_setattro(PyObject *attr, PyObject *pyvalue);
index 33e77395c86f1898da39e20bd80a2adbfb580993..e9fc4215bb6a614aedda5acbace43bf47050f09d 100644 (file)
@@ -33,7 +33,27 @@ class CListValue: # (PyObjectPlus)
                @rtype: integer
                @return: The index of the value in the list.
                """
-       def reverse(val):
+       def reverse():
                """
                Reverse the order of the list.
+               """
+       def from_id(id):
+               """
+               This is a funtion especially for the game engine to return a value with a spesific id.
+               
+               Since object names are not always unique, the id of an object can be used to get an object from the CValueList.
+               
+               Example.
+                       
+               C{myObID = id(gameObject)}
+               
+               C{...}
+               
+               C{ob= scene.objects.from_id(myObID)}
+               
+               Where myObID is an int or long from the id function.
+               
+               This has the advantage that you can store the id in places you could not store a gameObject.
+               
+               Warning: the id is derived from a memory location and will be different each time the game engine starts.
                """
\ No newline at end of file