Blender V2.61 - r43446

PyObjectPlus.h

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): none yet.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00032 #ifndef _PY_OBJECT_PLUS_H
00033 #define _PY_OBJECT_PLUS_H
00034 
00035 /* for now keep weakrefs optional */
00036 #define USE_WEAKREFS
00037 
00038 
00039 #ifndef __cplusplus             // c++ only
00040 #error Must be compiled with C++
00041 #endif
00042 
00043 #include "KX_Python.h"
00044 #include "STR_String.h"
00045 #include "MT_Vector3.h"
00046 #include "SG_QList.h"
00047 #include <stddef.h>
00048 
00049 #ifdef WITH_PYTHON
00050 #ifdef USE_MATHUTILS
00051 extern "C" {
00052 #include "../../blender/python/mathutils/mathutils.h" /* so we can have mathutils callbacks */
00053 #include "../../blender/python/generic/py_capi_utils.h" /* for PyC_LineSpit only */
00054 }
00055 #endif
00056 
00057 #define MAX_PROP_NAME 64
00058 
00059 static inline void Py_Fatal(const char *M)
00060 {
00061     fprintf(stderr, "%s\n", M);
00062     exit(-1);
00063 };
00064 
00065 
00066 /* Use with ShowDeprecationWarning macro */
00067 typedef struct {
00068     bool warn_done;
00069     void *link;
00070 } WarnLink;
00071 
00072 #define ShowDeprecationWarning(old_way, new_way)                              \
00073 {                                                                             \
00074     static WarnLink wlink = {false, NULL};                                    \
00075     if ((m_ignore_deprecation_warnings || wlink.warn_done)==0)                \
00076     {                                                                         \
00077         ShowDeprecationWarning_func(old_way, new_way);                        \
00078                                                                               \
00079         WarnLink *wlink_last= GetDeprecationWarningLinkLast();                \
00080         wlink.warn_done = true;                                               \
00081         wlink.link = NULL;                                                    \
00082                                                                               \
00083         if(wlink_last) {                                                      \
00084             wlink_last->link= (void *)&(wlink);                               \
00085             SetDeprecationWarningLinkLast(&(wlink));                          \
00086         }                                                                     \
00087         else {                                                                \
00088             SetDeprecationWarningFirst(&(wlink));                             \
00089             SetDeprecationWarningLinkLast(&(wlink));                          \
00090         }                                                                     \
00091     }                                                                         \
00092 }                                                                             \
00093 
00094 
00095 
00096 typedef struct PyObjectPlus_Proxy {
00097     PyObject_HEAD       /* required python macro   */
00098     class PyObjectPlus *ref;    // pointer to GE object, it holds a reference to this proxy
00099     void *ptr;                  // optional pointer to generic structure, the structure holds no reference to this proxy
00100     bool py_owns;       // true if the object pointed by ref should be deleted when the proxy is deleted
00101     bool py_ref;        // true if proxy is connected to a GE object (ref is used)
00102 #ifdef USE_WEAKREFS
00103     PyObject *in_weakreflist; // weak reference enabler
00104 #endif
00105 } PyObjectPlus_Proxy;
00106 
00107 #define BGE_PROXY_ERROR_MSG "Blender Game Engine data has been freed, cannot use this python variable"
00108 #define BGE_PROXY_REF(_self) (((PyObjectPlus_Proxy *)_self)->ref)
00109 #define BGE_PROXY_PTR(_self) (((PyObjectPlus_Proxy *)_self)->ptr)
00110 #define BGE_PROXY_PYOWNS(_self) (((PyObjectPlus_Proxy *)_self)->py_owns)
00111 #define BGE_PROXY_PYREF(_self) (((PyObjectPlus_Proxy *)_self)->py_ref)
00112 #ifdef USE_WEAKREFS
00113 #  define BGE_PROXY_WKREF(_self) (((PyObjectPlus_Proxy *)_self)->in_weakreflist)
00114 #endif
00115 
00116 /* Note, sometimes we dont care what BGE type this is as long as its a proxy */
00117 #define BGE_PROXY_CHECK_TYPE(_type) ((_type)->tp_dealloc == PyObjectPlus::py_base_dealloc)
00118 
00119 /* Opposite of BGE_PROXY_REF */
00120 #define BGE_PROXY_FROM_REF(_self) (((PyObjectPlus *)_self)->GetProxy())
00121 
00122 
00123 // This must be the first line of each 
00124 // PyC++ class
00125 // AttributesPtr correspond to attributes of proxy generic pointer 
00126 // each PyC++ class must be registered in KX_PythonInitTypes.cpp
00127 #define __Py_Header                                                           \
00128 public:                                                                       \
00129     static PyTypeObject   Type;                                               \
00130     static PyMethodDef    Methods[];                                          \
00131     static PyAttributeDef Attributes[];                                       \
00132     virtual PyTypeObject *GetType(void) {                                     \
00133         return &Type;                                                         \
00134     }                                                                         \
00135     virtual PyObject *GetProxy() {                                            \
00136         return GetProxyPlus_Ext(this, &Type, NULL);                           \
00137     }                                                                         \
00138     virtual PyObject *NewProxy(bool py_owns) {                                \
00139         return NewProxyPlus_Ext(this, &Type, NULL, py_owns);                  \
00140     }                                                                         \
00141 
00142 // leave above line empty (macro)!
00143 // use this macro for class that use generic pointer in proxy
00144 // GetProxy() and NewProxy() must be defined to set the correct pointer in the proxy
00145 #define __Py_HeaderPtr                                                        \
00146 public:                                                                       \
00147     static PyTypeObject   Type;                                               \
00148     static PyMethodDef    Methods[];                                          \
00149     static PyAttributeDef Attributes[];                                       \
00150     static PyAttributeDef AttributesPtr[];                                    \
00151     virtual PyTypeObject *GetType(void) {                                     \
00152         return &Type;                                                         \
00153     }                                                                         \
00154     virtual PyObject *GetProxy();                                             \
00155     virtual PyObject *NewProxy(bool py_owns);                                 \
00156 
00157 // leave above line empty (macro)!
00158 #ifdef WITH_CXX_GUARDEDALLOC
00159 #define Py_Header __Py_Header                                                 \
00160     void *operator new(size_t num_bytes) {                                    \
00161         return MEM_mallocN(num_bytes, Type.tp_name);                          \
00162     }                                                                         \
00163     void operator delete(void *mem) {                                         \
00164         MEM_freeN(mem);                                                       \
00165     }                                                                         \
00166 
00167 #else
00168 #  define Py_Header __Py_Header
00169 #endif
00170 
00171 #ifdef WITH_CXX_GUARDEDALLOC
00172 #define Py_HeaderPtr __Py_HeaderPtr                                           \
00173     void *operator new(size_t num_bytes) {                                    \
00174         return MEM_mallocN(num_bytes, Type.tp_name);                          \
00175     }                                                                         \
00176     void operator delete( void *mem ) {                                       \
00177         MEM_freeN(mem);                                                       \
00178     }                                                                         \
00179 
00180 #else
00181 #  define Py_HeaderPtr __Py_HeaderPtr
00182 #endif
00183 
00184 /*
00185  * nonzero values are an error for setattr
00186  * however because of the nested lookups we need to know if the errors
00187  * was because the attribute didnt exits of if there was some problem setting the value
00188  */
00189 
00190 #define PY_SET_ATTR_COERCE_FAIL  2
00191 #define PY_SET_ATTR_FAIL         1
00192 #define PY_SET_ATTR_MISSING     -1
00193 #define PY_SET_ATTR_SUCCESS      0
00194 
00199 #define KX_PYMETHOD(class_name, method_name)                                   \
00200     PyObject* Py##method_name(PyObject* args, PyObject* kwds);                 \
00201     static PyObject*                                                           \
00202     sPy##method_name(PyObject* self, PyObject* args, PyObject* kwds) {         \
00203         if(BGE_PROXY_REF(self)==NULL) {                                        \
00204             PyErr_SetString(PyExc_RuntimeError,                                \
00205                             #class_name "." #method_name "() - "               \
00206                             BGE_PROXY_ERROR_MSG);                              \
00207             return NULL;                                                       \
00208         }                                                                      \
00209         return((class_name*)BGE_PROXY_REF(self))->Py##method_name(args, kwds); \
00210     }                                                                          \
00211 
00212 #define KX_PYMETHOD_VARARGS(class_name, method_name)                           \
00213     PyObject* Py##method_name(PyObject* args);                                 \
00214     static PyObject*                                                           \
00215     sPy##method_name(PyObject* self, PyObject* args) {                         \
00216         if(BGE_PROXY_REF(self)==NULL) {                                        \
00217             PyErr_SetString(PyExc_RuntimeError,                                \
00218                             #class_name "." #method_name "() - "               \
00219                             BGE_PROXY_ERROR_MSG); return NULL;                 \
00220         }                                                                      \
00221         return((class_name*)BGE_PROXY_REF(self))->Py##method_name(args);       \
00222     }                                                                          \
00223 
00224 #define KX_PYMETHOD_NOARGS(class_name, method_name)                            \
00225     PyObject* Py##method_name();                                               \
00226     static PyObject*                                                           \
00227     sPy##method_name(PyObject* self) {                                         \
00228         if(BGE_PROXY_REF(self)==NULL) {                                        \
00229             PyErr_SetString(PyExc_RuntimeError,                                \
00230                             #class_name "." #method_name "() - "               \
00231                             BGE_PROXY_ERROR_MSG); return NULL;                 \
00232         }                                                                      \
00233         return((class_name*)BGE_PROXY_REF(self))->Py##method_name();           \
00234     }                                                                          \
00235 
00236 #define KX_PYMETHOD_O(class_name, method_name)                                 \
00237     PyObject* Py##method_name(PyObject* value);                                \
00238     static PyObject*                                                           \
00239     sPy##method_name(PyObject* self, PyObject* value) {                        \
00240         if(BGE_PROXY_REF(self)==NULL) {                                        \
00241             PyErr_SetString(PyExc_RuntimeError,                                \
00242                             #class_name "." #method_name "(value) - "          \
00243                             BGE_PROXY_ERROR_MSG); return NULL;                 \
00244         }                                                                      \
00245         return((class_name*)BGE_PROXY_REF(self))->Py##method_name(value);      \
00246     }                                                                          \
00247 
00248 #define KX_PYMETHOD_DOC(class_name, method_name)                               \
00249     PyObject* Py##method_name(PyObject* args, PyObject* kwds);                 \
00250     static PyObject*                                                           \
00251     sPy##method_name(PyObject* self, PyObject* args, PyObject* kwds) {         \
00252         if(BGE_PROXY_REF(self)==NULL) {                                        \
00253             PyErr_SetString(PyExc_RuntimeError,                                \
00254                             #class_name "." #method_name "(...) - "            \
00255                             BGE_PROXY_ERROR_MSG); return NULL;                 \
00256         }                                                                      \
00257         return((class_name*)BGE_PROXY_REF(self))->Py##method_name(args, kwds); \
00258     }                                                                          \
00259     static const char method_name##_doc[];                                     \
00260 
00261 #define KX_PYMETHOD_DOC_VARARGS(class_name, method_name)                       \
00262     PyObject* Py##method_name(PyObject* args);                                 \
00263     static PyObject*                                                           \
00264     sPy##method_name(PyObject* self, PyObject* args) {                         \
00265         if(BGE_PROXY_REF(self)==NULL) {                                        \
00266             PyErr_SetString(PyExc_RuntimeError,                                \
00267                             #class_name "." #method_name "(...) - "            \
00268                             BGE_PROXY_ERROR_MSG);                              \
00269             return NULL;                                                       \
00270         }                                                                      \
00271         return((class_name*)BGE_PROXY_REF(self))->Py##method_name(args);       \
00272     }                                                                          \
00273     static const char method_name##_doc[];                                     \
00274 
00275 #define KX_PYMETHOD_DOC_O(class_name, method_name)                             \
00276     PyObject* Py##method_name(PyObject* value);                                \
00277     static PyObject*                                                           \
00278     sPy##method_name(PyObject* self, PyObject* value) {                        \
00279         if(BGE_PROXY_REF(self)==NULL) {                                        \
00280             PyErr_SetString(PyExc_RuntimeError,                                \
00281                             #class_name "." #method_name "(value) - "          \
00282                             BGE_PROXY_ERROR_MSG);                              \
00283             return NULL;                                                       \
00284         }                                                                      \
00285         return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(value);     \
00286     }                                                                          \
00287     static const char method_name##_doc[];                                     \
00288 
00289 #define KX_PYMETHOD_DOC_NOARGS(class_name, method_name)                        \
00290     PyObject* Py##method_name();                                               \
00291     static PyObject*                                                           \
00292     sPy##method_name(PyObject* self) {                                         \
00293         if(BGE_PROXY_REF(self)==NULL) {                                        \
00294             PyErr_SetString(PyExc_RuntimeError,                                \
00295                             #class_name "." #method_name "() - "               \
00296                             BGE_PROXY_ERROR_MSG);                              \
00297             return NULL;                                                       \
00298         }                                                                      \
00299         return ((class_name*)BGE_PROXY_REF(self))->Py##method_name();          \
00300     }                                                                          \
00301     static const char method_name##_doc[];                                     \
00302 
00303 
00304 /* The line above should remain empty */
00308 #define KX_PYMETHODTABLE(class_name, method_name) \
00309     {#method_name , (PyCFunction) class_name::sPy##method_name, METH_VARARGS, (const char *)class_name::method_name##_doc}
00310 
00311 #define KX_PYMETHODTABLE_O(class_name, method_name) \
00312     {#method_name , (PyCFunction) class_name::sPy##method_name, METH_O, (const char *)class_name::method_name##_doc}
00313 
00314 #define KX_PYMETHODTABLE_NOARGS(class_name, method_name) \
00315     {#method_name , (PyCFunction) class_name::sPy##method_name, METH_NOARGS, (const char *)class_name::method_name##_doc}
00316 
00317 #define KX_PYMETHODTABLE_KEYWORDS(class_name, method_name) \
00318     {#method_name , (PyCFunction) class_name::sPy##method_name, METH_VARARGS|METH_KEYWORDS, (const char *)class_name::method_name##_doc}
00319 
00323 #define KX_PYMETHODDEF_DOC(class_name, method_name, doc_string) \
00324 const char class_name::method_name##_doc[] = doc_string; \
00325 PyObject* class_name::Py##method_name(PyObject* args, PyObject* kwds)
00326 
00327 #define KX_PYMETHODDEF_DOC_VARARGS(class_name, method_name, doc_string) \
00328 const char class_name::method_name##_doc[] = doc_string; \
00329 PyObject* class_name::Py##method_name(PyObject* args)
00330 
00331 #define KX_PYMETHODDEF_DOC_O(class_name, method_name, doc_string) \
00332 const char class_name::method_name##_doc[] = doc_string; \
00333 PyObject* class_name::Py##method_name(PyObject* value)
00334 
00335 #define KX_PYMETHODDEF_DOC_NOARGS(class_name, method_name, doc_string) \
00336 const char class_name::method_name##_doc[] = doc_string; \
00337 PyObject* class_name::Py##method_name()
00338 
00342 enum KX_PYATTRIBUTE_TYPE {
00343     KX_PYATTRIBUTE_TYPE_BOOL,
00344     KX_PYATTRIBUTE_TYPE_ENUM,
00345     KX_PYATTRIBUTE_TYPE_SHORT,
00346     KX_PYATTRIBUTE_TYPE_INT,
00347     KX_PYATTRIBUTE_TYPE_FLOAT,
00348     KX_PYATTRIBUTE_TYPE_STRING,
00349     KX_PYATTRIBUTE_TYPE_DUMMY,
00350     KX_PYATTRIBUTE_TYPE_FUNCTION,
00351     KX_PYATTRIBUTE_TYPE_VECTOR,
00352     KX_PYATTRIBUTE_TYPE_FLAG,
00353     KX_PYATTRIBUTE_TYPE_CHAR
00354 };
00355 
00356 enum KX_PYATTRIBUTE_ACCESS {
00357     KX_PYATTRIBUTE_RW,
00358     KX_PYATTRIBUTE_RO
00359 };
00360 
00361 struct KX_PYATTRIBUTE_DEF;
00362 typedef int (*KX_PYATTRIBUTE_CHECK_FUNCTION)(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
00363 typedef int (*KX_PYATTRIBUTE_SET_FUNCTION)(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
00364 typedef PyObject* (*KX_PYATTRIBUTE_GET_FUNCTION)(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
00365 
00366 typedef struct KX_PYATTRIBUTE_DEF {
00367     const char *m_name;             // name of the python attribute
00368     KX_PYATTRIBUTE_TYPE m_type;     // type of value
00369     KX_PYATTRIBUTE_ACCESS m_access; // read/write access or read-only
00370     int m_imin;                     // minimum value in case of integer attributes 
00371                                     // (for string: minimum string length, for flag: mask value, for float: matrix row size)
00372     int m_imax;                     // maximum value in case of integer attributes 
00373                                     // (for string: maximum string length, for flag: 1 if flag is negative, float: vector/matrix col size)
00374     float m_fmin;                   // minimum value in case of float attributes
00375     float m_fmax;                   // maximum value in case of float attributes
00376     bool   m_clamp;                 // enforce min/max value by clamping
00377     bool   m_usePtr;                // the attribute uses the proxy generic pointer, set at runtime
00378     size_t m_offset;                // position of field in structure
00379     size_t m_size;                  // size of field for runtime verification (enum only)
00380     size_t m_length;                // length of array, 1=simple attribute
00381     KX_PYATTRIBUTE_CHECK_FUNCTION m_checkFunction;  // static function to check the assignment, returns 0 if no error
00382     KX_PYATTRIBUTE_SET_FUNCTION m_setFunction;  // static function to check the assignment, returns 0 if no error
00383     KX_PYATTRIBUTE_GET_FUNCTION m_getFunction;  // static function to check the assignment, returns 0 if no error
00384 
00385     // The following pointers are just used to have compile time check for attribute type.
00386     // It would have been good to use a union but that would require C99 compatibility
00387     // to initialize specific union fields through designated initializers.
00388     struct {
00389         bool *m_boolPtr;
00390         short int *m_shortPtr;
00391         int *m_intPtr;
00392         float *m_floatPtr;
00393         STR_String *m_stringPtr;
00394         MT_Vector3 *m_vectorPtr;
00395         char *m_charPtr;
00396     } m_typeCheck;
00397 } PyAttributeDef;
00398 
00399 #define KX_PYATTRIBUTE_BOOL_RW(name,object,field) \
00400     { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RW, 0, 1, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL, NULL} }
00401 #define KX_PYATTRIBUTE_BOOL_RW_CHECK(name,object,field,function) \
00402     { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RW, 0, 1, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL, NULL} }
00403 #define KX_PYATTRIBUTE_BOOL_RO(name,object,field) \
00404     { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RO, 0, 1, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL, NULL} }
00405 
00406 /* attribute points to a single bit of an integer field, attribute=true if bit is set */
00407 #define KX_PYATTRIBUTE_FLAG_RW(name,object,field,bit) \
00408     { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
00409 #define KX_PYATTRIBUTE_FLAG_RW_CHECK(name,object,field,bit,function) \
00410     { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
00411 #define KX_PYATTRIBUTE_FLAG_RO(name,object,field,bit) \
00412     { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RO, bit, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
00413 
00414 /* attribute points to a single bit of an integer field, attribute=true if bit is set*/
00415 #define KX_PYATTRIBUTE_FLAG_NEGATIVE_RW(name,object,field,bit) \
00416     { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 1, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
00417 #define KX_PYATTRIBUTE_FLAG_NEGATIVE_RW_CHECK(name,object,field,bit,function) \
00418     { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 1, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
00419 #define KX_PYATTRIBUTE_FLAG_NEGATIVE_RO(name,object,field,bit) \
00420     { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RO, bit, 1, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
00421 
00422 // enum field cannot be mapped to pointer (because we would need a pointer for each enum)
00423 // use field size to verify mapping at runtime only, assuming enum size is equal to int size.
00424 #define KX_PYATTRIBUTE_ENUM_RW(name,min,max,clamp,object,field) \
00425     { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
00426 #define KX_PYATTRIBUTE_ENUM_RW_CHECK(name,min,max,clamp,object,field,function) \
00427     { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
00428 #define KX_PYATTRIBUTE_ENUM_RO(name,object,field) \
00429     { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
00430 
00431 #define KX_PYATTRIBUTE_SHORT_RW(name,min,max,clamp,object,field) \
00432     { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
00433 #define KX_PYATTRIBUTE_SHORT_RW_CHECK(name,min,max,clamp,object,field,function) \
00434     { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
00435 #define KX_PYATTRIBUTE_SHORT_RO(name,object,field) \
00436     { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
00437 #define KX_PYATTRIBUTE_SHORT_ARRAY_RW(name,min,max,clamp,object,field,length) \
00438     { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
00439 #define KX_PYATTRIBUTE_SHORT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \
00440     { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
00441 #define KX_PYATTRIBUTE_SHORT_ARRAY_RO(name,object,field,length) \
00442     { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
00443 // SHORT_LIST
00444 #define KX_PYATTRIBUTE_SHORT_LIST_RW(name,min,max,clamp,object,field,length) \
00445     { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
00446 #define KX_PYATTRIBUTE_SHORT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \
00447     { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
00448 #define KX_PYATTRIBUTE_SHORT_LIST_RO(name,object,field,length) \
00449     { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
00450 
00451 #define KX_PYATTRIBUTE_INT_RW(name,min,max,clamp,object,field) \
00452     { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
00453 #define KX_PYATTRIBUTE_INT_RW_CHECK(name,min,max,clamp,object,field,function) \
00454     { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
00455 #define KX_PYATTRIBUTE_INT_RO(name,object,field) \
00456     { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
00457 #define KX_PYATTRIBUTE_INT_ARRAY_RW(name,min,max,clamp,object,field,length) \
00458     { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
00459 #define KX_PYATTRIBUTE_INT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \
00460     { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
00461 #define KX_PYATTRIBUTE_INT_ARRAY_RO(name,object,field,length) \
00462     { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
00463 // INT_LIST
00464 #define KX_PYATTRIBUTE_INT_LIST_RW(name,min,max,clamp,object,field,length) \
00465     { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
00466 #define KX_PYATTRIBUTE_INT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \
00467     { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
00468 #define KX_PYATTRIBUTE_INT_LIST_RO(name,object,field,length) \
00469     { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
00470 
00471 // always clamp for float
00472 #define KX_PYATTRIBUTE_FLOAT_RW(name,min,max,object,field) \
00473     { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
00474 #define KX_PYATTRIBUTE_FLOAT_RW_CHECK(name,min,max,object,field,function) \
00475     { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
00476 #define KX_PYATTRIBUTE_FLOAT_RO(name,object,field) \
00477     { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
00478 // field must be float[n], returns a sequence
00479 #define KX_PYATTRIBUTE_FLOAT_ARRAY_RW(name,min,max,object,field,length) \
00480     { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
00481 #define KX_PYATTRIBUTE_FLOAT_ARRAY_RW_CHECK(name,min,max,object,field,length,function) \
00482     { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
00483 #define KX_PYATTRIBUTE_FLOAT_ARRAY_RO(name,object,field,length) \
00484     { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
00485 // field must be float[n], returns a vector
00486 #define KX_PYATTRIBUTE_FLOAT_VECTOR_RW(name,min,max,object,field,length) \
00487     { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, length, min, max, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
00488 #define KX_PYATTRIBUTE_FLOAT_VECTOR_RW_CHECK(name,min,max,object,field,length,function) \
00489     { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, length, min, max, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
00490 #define KX_PYATTRIBUTE_FLOAT_VECTOR_RO(name,object,field,length) \
00491     { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, length, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
00492 // field must be float[n][n], returns a matrix
00493 #define KX_PYATTRIBUTE_FLOAT_MATRIX_RW(name,min,max,object,field,length) \
00494     { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, length, length, min, max, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field[0], NULL, NULL, NULL} }
00495 #define KX_PYATTRIBUTE_FLOAT_MATRIX_RW_CHECK(name,min,max,object,field,length,function) \
00496     { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, length, length, min, max, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field[0], NULL, NULL, NULL} }
00497 #define KX_PYATTRIBUTE_FLOAT_MATRIX_RO(name,object,field,length) \
00498     { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, length, length, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field[0], NULL, NULL, NULL} }
00499 
00500 // only for STR_String member
00501 #define KX_PYATTRIBUTE_STRING_RW(name,min,max,clamp,object,field) \
00502     { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
00503 #define KX_PYATTRIBUTE_STRING_RW_CHECK(name,min,max,clamp,object,field,function) \
00504     { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
00505 #define KX_PYATTRIBUTE_STRING_RO(name,object,field) \
00506     { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
00507 
00508 // only for char [] array 
00509 #define KX_PYATTRIBUTE_CHAR_RW(name,object,field) \
00510     { name, KX_PYATTRIBUTE_TYPE_CHAR, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0.f, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, ((object *)0)->field} }
00511 #define KX_PYATTRIBUTE_CHAR_RW_CHECK(name,object,field,function) \
00512     { name, KX_PYATTRIBUTE_TYPE_CHAR, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0.f, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, ((object *)0)->field} }
00513 #define KX_PYATTRIBUTE_CHAR_RO(name,object,field) \
00514     { name, KX_PYATTRIBUTE_TYPE_CHAR, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, ((object *)0)->field} }
00515 
00516 // for MT_Vector3 member
00517 #define KX_PYATTRIBUTE_VECTOR_RW(name,min,max,object,field) \
00518     { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
00519 #define KX_PYATTRIBUTE_VECTOR_RW_CHECK(name,min,max,clamp,object,field,function) \
00520     { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
00521 #define KX_PYATTRIBUTE_VECTOR_RO(name,object,field) \
00522     { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
00523 
00524 #define KX_PYATTRIBUTE_RW_FUNCTION(name,object,getfunction,setfunction) \
00525     { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0.f, false, false, 0, 0, 1, NULL, &object::setfunction, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
00526 #define KX_PYATTRIBUTE_RO_FUNCTION(name,object,getfunction) \
00527     { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, 0, 0, 1, NULL, NULL, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
00528 #define KX_PYATTRIBUTE_ARRAY_RW_FUNCTION(name,object,length,getfunction,setfunction) \
00529     { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0,f, false, false, 0, 0, length, NULL, &object::setfunction, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
00530 #define KX_PYATTRIBUTE_ARRAY_RO_FUNCTION(name,object,length,getfunction) \
00531     { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0,f, false, false, 0, 0, length, NULL, NULL, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
00532 
00533 
00534 /*------------------------------
00535  * PyObjectPlus
00536 ------------------------------*/
00537 typedef PyTypeObject * PyParentObject;              // Define the PyParent Object
00538 
00539 #else // WITH_PYTHON
00540 
00541 #ifdef WITH_CXX_GUARDEDALLOC
00542 #define Py_Header                                                             \
00543 public:                                                                       \
00544     void *operator new(size_t num_bytes) {                                    \
00545         return MEM_mallocN(num_bytes, "GE:PyObjectPlus");                     \
00546     }                                                                         \
00547     void operator delete( void *mem ) {                                       \
00548         MEM_freeN(mem);                                                       \
00549     }                                                                         \
00550 
00551 #define Py_HeaderPtr                                                          \
00552 public:                                                                       \
00553     void *operator new(size_t num_bytes) {                                    \
00554         return MEM_mallocN(num_bytes, "GE:PyObjectPlusPtr");                  \
00555     }                                                                         \
00556     void operator delete( void *mem ) {                                       \
00557     MEM_freeN(mem);                                                           \
00558     }                                                                         \
00559 
00560 #else // WITH_CXX_GUARDEDALLOC
00561 
00562 #define Py_Header \
00563 public: \
00564 
00565 #define Py_HeaderPtr \
00566 public: \
00567 
00568 #endif // WITH_CXX_GUARDEDALLOC
00569 
00570 #endif
00571 
00572 
00573 // By making SG_QList the ultimate parent for PyObjectPlus objects, it
00574 // allows to put them in 2 different dynamic lists at the same time
00575 // The use of these links is interesting because they free of memory allocation
00576 // but it's very important not to mess up with them. If you decide that 
00577 // the SG_QList or SG_DList component is used for something for a certain class,
00578 // they cannot can be used for anything else at a parent level!
00579 // What these lists are and what they are used for must be carefully documented
00580 // at the level where they are used.
00581 // DON'T MAKE ANY USE OF THESE LIST AT THIS LEVEL, they are already used
00582 // at SCA_IActuator, SCA_ISensor, SCA_IController level which rules out the
00583 // possibility to use them at SCA_ILogicBrick, CValue and PyObjectPlus level.
00584 class PyObjectPlus : public SG_QList
00585 {               // The PyObjectPlus abstract class
00586     Py_Header                           // Always start with Py_Header
00587     
00588 public:
00589     PyObjectPlus();
00590     
00591     virtual ~PyObjectPlus();                    // destructor
00592     
00593 #ifdef WITH_PYTHON
00594     PyObject *m_proxy; /* actually a PyObjectPlus_Proxy */
00595 
00596     /* These static functions are referenced by ALL PyObjectPlus_Proxy types
00597      * they take the C++ reference from the PyObjectPlus_Proxy and call
00598      * its own virtual py_repr, py_base_dealloc ,etc. functions.
00599      */
00600 
00601     static PyObject*        py_base_new(PyTypeObject *type, PyObject *args, PyObject *kwds); /* allows subclassing */
00602     static void         py_base_dealloc(PyObject *self);
00603     static PyObject*        py_base_repr(PyObject *self);
00604 
00605     /* These are all virtual python methods that are defined in each class
00606      * Our own fake subclassing calls these on each class, then calls the parent */
00607     virtual PyObject*       py_repr(void);
00608     /* subclass may overwrite this function to implement more sophisticated method of validating a proxy */
00609     virtual bool            py_is_valid(void) { return true; }
00610 
00611     static PyObject*        py_get_attrdef(PyObject *self_py, const PyAttributeDef *attrdef);
00612     static int              py_set_attrdef(PyObject *self_py, PyObject *value, const PyAttributeDef *attrdef);
00613     
00614     /* Kindof dumb, always returns True, the false case is checked for, before this function gets accessed */
00615     static PyObject*    pyattr_get_invalid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
00616 
00617     static PyObject *GetProxyPlus_Ext(PyObjectPlus *self, PyTypeObject *tp, void *ptr);
00618     /* self=NULL => proxy to generic pointer detached from GE object
00619                     if py_owns is true, the memory pointed by ptr will be deleted automatially with MEM_freeN 
00620        self!=NULL=> proxy attached to GE object, ptr is optional and point to a struct from which attributes can be defined
00621                     if py_owns is true, the object will be deleted automatically, ptr will NOT be deleted 
00622                     (assume object destructor takes care of it) */
00623     static PyObject *NewProxyPlus_Ext(PyObjectPlus *self, PyTypeObject *tp, void *ptr, bool py_owns);
00624 
00625     static  WarnLink*       GetDeprecationWarningLinkFirst(void);
00626     static  WarnLink*       GetDeprecationWarningLinkLast(void);
00627     static  void            SetDeprecationWarningFirst(WarnLink* wlink);
00628     static  void            SetDeprecationWarningLinkLast(WarnLink* wlink);
00629     static void         NullDeprecationWarning();
00630     
00632     static void         SetDeprecationWarnings(bool ignoreDeprecationWarnings);
00634     static void         ShowDeprecationWarning_func(const char* method,const char* prop);
00635     static void         ClearDeprecationWarning();
00636     
00637 #endif
00638 
00639     void    InvalidateProxy();
00640 
00644     virtual void ProcessReplica();
00645 
00646     static bool         m_ignore_deprecation_warnings;
00647 };
00648 
00649 #ifdef WITH_PYTHON
00650 PyObject *py_getattr_dict(PyObject *pydict, PyObject *tp_dict);
00651 
00652 PyObject *PyUnicode_From_STR_String(const STR_String& str);
00653 #endif
00654 
00655 #endif //  _PY_OBJECT_PLUS_H