BGE PyAPI fixes
[blender.git] / source / gameengine / Expressions / PyObjectPlus.h
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #ifndef NO_EXP_PYTHON_EMBEDDING
31
32 #ifndef _adr_py_lib_h_                          // only process once,
33 #define _adr_py_lib_h_                          // even if multiply included
34
35 #ifndef __cplusplus                             // c++ only
36 #error Must be compiled with C++
37 #endif
38
39 #include "KX_Python.h"
40 #include "STR_String.h"
41 #include "MT_Vector3.h"
42 #include "SG_QList.h"
43
44 /*------------------------------
45  * Python defines
46 ------------------------------*/
47
48
49
50 #if PY_VERSION_HEX > 0x03000000
51 #define PyString_FromString PyUnicode_FromString
52 #define PyString_FromFormat PyUnicode_FromFormat
53 #define PyString_Check PyUnicode_Check
54 #define PyString_Size PyUnicode_GetSize
55
56 #define PyInt_FromLong PyLong_FromSsize_t
57 #define PyInt_AsLong PyLong_AsSsize_t
58 #define PyString_AsString _PyUnicode_AsString
59 #define PyInt_Check PyLong_Check
60 #define PyInt_AS_LONG PyLong_AsLong // TODO - check this one
61 #endif
62
63
64
65 /*
66    Py_RETURN_NONE
67    Python 2.4 macro.
68    defined here until we switch to 2.4
69    also in api2_2x/gen_utils.h 
70 */
71 #ifndef Py_RETURN_NONE
72 #define Py_RETURN_NONE  return Py_INCREF(Py_None), Py_None
73 #endif
74 #ifndef Py_RETURN_FALSE
75 #define Py_RETURN_FALSE  return Py_INCREF(Py_False), Py_False
76 #endif
77 #ifndef Py_RETURN_TRUE
78 #define Py_RETURN_TRUE  return Py_INCREF(Py_True), Py_True
79 #endif
80
81 /*  for pre Py 2.5 */
82 #if PY_VERSION_HEX < 0x02050000
83 typedef int Py_ssize_t;
84 typedef Py_ssize_t (*lenfunc)(PyObject *);
85 #define PY_SSIZE_T_MAX INT_MAX
86 #define PY_SSIZE_T_MIN INT_MIN
87 #define PY_METHODCHAR char *
88 #else
89 /* Py 2.5 and later */
90 #define  intargfunc  ssizeargfunc
91 #define intintargfunc  ssizessizeargfunc
92 #define PY_METHODCHAR const char *
93 #endif
94
95 #include "descrobject.h"
96
97
98 static inline void Py_Fatal(const char *M) {
99         fprintf(stderr, "%s\n", M);
100         exit(-1);
101 };
102
103
104 /* Use with ShowDeprecationWarning macro */
105 typedef struct {
106         bool warn_done;
107         void *link;
108 } WarnLink;
109
110 #define ShowDeprecationWarning(old_way, new_way) \
111 { \
112         static WarnLink wlink = {false, NULL}; \
113         if ((m_ignore_deprecation_warnings || wlink.warn_done)==0) \
114         { \
115                 ShowDeprecationWarning_func(old_way, new_way); \
116                 WarnLink *wlink_last= GetDeprecationWarningLinkLast(); \
117                 ShowDeprecationWarning_func(old_way, new_way); \
118                 wlink.warn_done = true; \
119                 wlink.link = NULL; \
120          \
121                 if(wlink_last) { \
122                         wlink_last->link= (void *)&(wlink); \
123                         SetDeprecationWarningLinkLast(&(wlink)); \
124                 } else { \
125                         SetDeprecationWarningFirst(&(wlink)); \
126                         SetDeprecationWarningLinkLast(&(wlink)); \
127                 } \
128         } \
129 } \
130
131
132
133 typedef struct {
134         PyObject_HEAD           /* required python macro   */
135         class PyObjectPlus *ref;
136         bool py_owns;
137 } PyObjectPlus_Proxy;
138
139 #define BGE_PROXY_ERROR_MSG "Blender Game Engine data has been freed, cannot use this python variable"
140 #define BGE_PROXY_REF(_self) (((PyObjectPlus_Proxy *)_self)->ref)
141 #define BGE_PROXY_PYOWNS(_self) (((PyObjectPlus_Proxy *)_self)->py_owns)
142
143 /* Note, sometimes we dont care what BGE type this is as long as its a proxy */
144 #define BGE_PROXY_CHECK_TYPE(_self) ((_self)->ob_type->tp_dealloc == PyObjectPlus::py_base_dealloc)
145
146
147                                                                 // This must be the first line of each 
148                                                                 // PyC++ class
149 #define Py_Header \
150  public: \
151   static PyTypeObject   Type; \
152   static PyMethodDef    Methods[]; \
153   static PyAttributeDef Attributes[]; \
154   static PyParentObject Parents[]; \
155   virtual PyTypeObject *GetType(void) {return &Type;}; \
156   virtual PyParentObject *GetParents(void) {return Parents;} \
157   virtual PyObject *GetProxy() {return GetProxy_Ext(this, &Type);}; \
158   virtual PyObject *NewProxy(bool py_owns) {return NewProxy_Ext(this, &Type, py_owns);}; \
159
160
161
162
163                                                                 // This defines the py_getattro_up macro
164                                                                 // which allows attribute and method calls
165                                                                 // to be properly passed up the hierarchy.
166                                                                 // 
167                                                                 // Note, PyDict_GetItem() WONT set an exception!
168                                                                 // let the py_base_getattro function do this.
169
170 #define py_getattro_up(Parent) \
171         \
172         PyObject *descr = PyDict_GetItem(Type.tp_dict, attr); \
173          \
174         if(descr) { \
175                 if (PyCObject_Check(descr)) { \
176                         return py_get_attrdef((void *)this, (const PyAttributeDef*)PyCObject_AsVoidPtr(descr)); \
177                 } else if (descr->ob_type->tp_descr_get) { \
178                         return PyCFunction_New(((PyMethodDescrObject *)descr)->d_method, this->m_proxy); \
179                 } else { \
180                         return NULL; \
181                 } \
182         } else { \
183                 return Parent::py_getattro(attr); \
184         }
185
186 #define py_getattro_dict_up(Parent) \
187         return py_getattr_dict(Parent::py_getattro_dict(), Type.tp_dict);
188
189 /*
190  * nonzero values are an error for setattr
191  * however because of the nested lookups we need to know if the errors
192  * was because the attribute didnt exits of if there was some problem setting the value
193  */
194
195 #define PY_SET_ATTR_COERCE_FAIL  2
196 #define PY_SET_ATTR_FAIL                 1
197 #define PY_SET_ATTR_MISSING             -1
198 #define PY_SET_ATTR_SUCCESS              0
199
200 #define py_setattro_up(Parent) \
201         PyObject *descr = PyDict_GetItem(Type.tp_dict, attr); \
202          \
203         if(descr) { \
204                 if (PyCObject_Check(descr)) { \
205                         const PyAttributeDef* attrdef= reinterpret_cast<const PyAttributeDef *>(PyCObject_AsVoidPtr(descr)); \
206                         if (attrdef->m_access == KX_PYATTRIBUTE_RO) { \
207                                 PyErr_Format(PyExc_AttributeError, "\"%s\" is read only", PyString_AsString(attr)); \
208                                 return PY_SET_ATTR_FAIL; \
209                         } \
210                         else { \
211                                 return py_set_attrdef((void *)this, attrdef, value); \
212                         } \
213                 } else { \
214                         PyErr_Format(PyExc_AttributeError, "\"%s\" cannot be set", PyString_AsString(attr)); \
215                         return PY_SET_ATTR_FAIL; \
216                 } \
217         } else { \
218                 PyErr_Clear(); \
219                 return Parent::py_setattro(attr, value); \
220         }
221
222
223 /**
224  * These macros are helpfull when embedding Python routines. The second
225  * macro is one that also requires a documentation string
226  */
227 #define KX_PYMETHOD(class_name, method_name)                    \
228         PyObject* Py##method_name(PyObject* args, PyObject* kwds); \
229         static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \
230                 if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \
231                 return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args, kwds);         \
232         }; \
233
234 #define KX_PYMETHOD_VARARGS(class_name, method_name)                    \
235         PyObject* Py##method_name(PyObject* args); \
236         static PyObject* sPy##method_name( PyObject* self, PyObject* args) { \
237                 if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \
238                 return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args);               \
239         }; \
240
241 #define KX_PYMETHOD_NOARGS(class_name, method_name)                     \
242         PyObject* Py##method_name(); \
243         static PyObject* sPy##method_name( PyObject* self) { \
244                 if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \
245                 return ((class_name*)BGE_PROXY_REF(self))->Py##method_name();           \
246         }; \
247         
248 #define KX_PYMETHOD_O(class_name, method_name)                  \
249         PyObject* Py##method_name(PyObject* value); \
250         static PyObject* sPy##method_name( PyObject* self, PyObject* value) { \
251                 if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(value) - " BGE_PROXY_ERROR_MSG); return NULL; } \
252                 return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(value);              \
253         }; \
254
255 #define KX_PYMETHOD_DOC(class_name, method_name)                        \
256         PyObject* Py##method_name(PyObject* args, PyObject* kwds); \
257         static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \
258                 if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(...) - " BGE_PROXY_ERROR_MSG); return NULL; } \
259                 return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args, kwds);         \
260         }; \
261     static const char method_name##_doc[]; \
262
263 #define KX_PYMETHOD_DOC_VARARGS(class_name, method_name)                        \
264         PyObject* Py##method_name(PyObject* args); \
265         static PyObject* sPy##method_name( PyObject* self, PyObject* args) { \
266                 if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(...) - " BGE_PROXY_ERROR_MSG); return NULL; } \
267                 return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args);               \
268         }; \
269     static const char method_name##_doc[]; \
270
271 #define KX_PYMETHOD_DOC_O(class_name, method_name)                      \
272         PyObject* Py##method_name(PyObject* value); \
273         static PyObject* sPy##method_name( PyObject* self, PyObject* value) { \
274                 if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(value) - " BGE_PROXY_ERROR_MSG); return NULL; } \
275                 return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(value);              \
276         }; \
277     static const char method_name##_doc[]; \
278
279 #define KX_PYMETHOD_DOC_NOARGS(class_name, method_name)                 \
280         PyObject* Py##method_name(); \
281         static PyObject* sPy##method_name( PyObject* self) { \
282                 if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \
283                 return ((class_name*)BGE_PROXY_REF(self))->Py##method_name();           \
284         }; \
285     static const char method_name##_doc[]; \
286
287
288 /* The line above should remain empty */
289 /**
290  * Method table macro (with doc)
291  */
292 #define KX_PYMETHODTABLE(class_name, method_name) \
293         {#method_name , (PyCFunction) class_name::sPy##method_name, METH_VARARGS, (PY_METHODCHAR)class_name::method_name##_doc}
294
295 #define KX_PYMETHODTABLE_O(class_name, method_name) \
296         {#method_name , (PyCFunction) class_name::sPy##method_name, METH_O, (PY_METHODCHAR)class_name::method_name##_doc}
297
298 #define KX_PYMETHODTABLE_NOARGS(class_name, method_name) \
299         {#method_name , (PyCFunction) class_name::sPy##method_name, METH_NOARGS, (PY_METHODCHAR)class_name::method_name##_doc}
300
301 /**
302  * Function implementation macro
303  */
304 #define KX_PYMETHODDEF_DOC(class_name, method_name, doc_string) \
305 const char class_name::method_name##_doc[] = doc_string; \
306 PyObject* class_name::Py##method_name(PyObject* args, PyObject*)
307
308 #define KX_PYMETHODDEF_DOC_VARARGS(class_name, method_name, doc_string) \
309 const char class_name::method_name##_doc[] = doc_string; \
310 PyObject* class_name::Py##method_name(PyObject* args)
311
312 #define KX_PYMETHODDEF_DOC_O(class_name, method_name, doc_string) \
313 const char class_name::method_name##_doc[] = doc_string; \
314 PyObject* class_name::Py##method_name(PyObject* value)
315
316 #define KX_PYMETHODDEF_DOC_NOARGS(class_name, method_name, doc_string) \
317 const char class_name::method_name##_doc[] = doc_string; \
318 PyObject* class_name::Py##method_name()
319
320 /**
321  * Attribute management
322  */
323 enum KX_PYATTRIBUTE_TYPE {
324         KX_PYATTRIBUTE_TYPE_BOOL,
325         KX_PYATTRIBUTE_TYPE_ENUM,
326         KX_PYATTRIBUTE_TYPE_SHORT,
327         KX_PYATTRIBUTE_TYPE_INT,
328         KX_PYATTRIBUTE_TYPE_FLOAT,
329         KX_PYATTRIBUTE_TYPE_STRING,
330         KX_PYATTRIBUTE_TYPE_DUMMY,
331         KX_PYATTRIBUTE_TYPE_FUNCTION,
332         KX_PYATTRIBUTE_TYPE_VECTOR,
333 };
334
335 enum KX_PYATTRIBUTE_ACCESS {
336         KX_PYATTRIBUTE_RW,
337         KX_PYATTRIBUTE_RO
338 };
339
340 struct KX_PYATTRIBUTE_DEF;
341 typedef int (*KX_PYATTRIBUTE_CHECK_FUNCTION)(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
342 typedef int (*KX_PYATTRIBUTE_SET_FUNCTION)(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
343 typedef PyObject* (*KX_PYATTRIBUTE_GET_FUNCTION)(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
344
345 typedef struct KX_PYATTRIBUTE_DEF {
346         const char *m_name;                             // name of the python attribute
347         KX_PYATTRIBUTE_TYPE m_type;             // type of value
348         KX_PYATTRIBUTE_ACCESS m_access; // read/write access or read-only
349         int m_imin;                                             // minimum value in case of integer attributes (for string: minimum string length)
350         int m_imax;                                             // maximum value in case of integer attributes (for string: maximum string length)
351         float m_fmin;                                   // minimum value in case of float attributes
352         float m_fmax;                                   // maximum value in case of float attributes
353         bool   m_clamp;                                 // enforce min/max value by clamping
354         size_t m_offset;                                // position of field in structure
355         size_t m_size;                                  // size of field for runtime verification (enum only)
356         size_t m_length;                                // length of array, 1=simple attribute
357         KX_PYATTRIBUTE_CHECK_FUNCTION m_checkFunction;  // static function to check the assignment, returns 0 if no error
358         KX_PYATTRIBUTE_SET_FUNCTION m_setFunction;      // static function to check the assignment, returns 0 if no error
359         KX_PYATTRIBUTE_GET_FUNCTION m_getFunction;      // static function to check the assignment, returns 0 if no error
360
361         // The following pointers are just used to have compile time check for attribute type.
362         // It would have been good to use a union but that would require C99 compatibility
363         // to initialize specific union fields through designated initializers.
364         struct {
365                 bool *m_boolPtr;
366                 short int *m_shortPtr;
367                 int *m_intPtr;
368                 float *m_floatPtr;
369                 STR_String *m_stringPtr;
370                 MT_Vector3 *m_vectorPtr;
371         } m_typeCheck;
372 } PyAttributeDef;
373
374 #define KX_PYATTRIBUTE_DUMMY(name) \
375         { name, KX_PYATTRIBUTE_TYPE_DUMMY, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, 0, 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL} }
376
377 #define KX_PYATTRIBUTE_BOOL_RW(name,object,field) \
378         { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RW, 0, 1, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
379 #define KX_PYATTRIBUTE_BOOL_RW_CHECK(name,object,field,function) \
380         { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RW, 0, 1, 0.f, 0.f, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
381 #define KX_PYATTRIBUTE_BOOL_RO(name,object,field) \
382         { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RO, 0, 1, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
383
384 // enum field cannot be mapped to pointer (because we would need a pointer for each enum)
385 // use field size to verify mapping at runtime only, assuming enum size is equal to int size.
386 #define KX_PYATTRIBUTE_ENUM_RW(name,min,max,clamp,object,field) \
387         { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL} }
388 #define KX_PYATTRIBUTE_ENUM_RW_CHECK(name,min,max,clamp,object,field,function) \
389         { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL} }
390 #define KX_PYATTRIBUTE_ENUM_RO(name,object,field) \
391         { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL} }
392
393 #define KX_PYATTRIBUTE_SHORT_RW(name,min,max,clamp,object,field) \
394         { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
395 #define KX_PYATTRIBUTE_SHORT_RW_CHECK(name,min,max,clamp,object,field,function) \
396         { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
397 #define KX_PYATTRIBUTE_SHORT_RO(name,object,field) \
398         { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
399 #define KX_PYATTRIBUTE_SHORT_ARRAY_RW(name,min,max,clamp,object,field,length) \
400         { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
401 #define KX_PYATTRIBUTE_SHORT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \
402         { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
403 #define KX_PYATTRIBUTE_SHORT_ARRAY_RO(name,object,field,length) \
404         { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
405 // SHORT_LIST
406 #define KX_PYATTRIBUTE_SHORT_LIST_RW(name,min,max,clamp,object,field,length) \
407         { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
408 #define KX_PYATTRIBUTE_SHORT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \
409         { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
410 #define KX_PYATTRIBUTE_SHORT_LIST_RO(name,object,field,length) \
411         { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
412
413 #define KX_PYATTRIBUTE_INT_RW(name,min,max,clamp,object,field) \
414         { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
415 #define KX_PYATTRIBUTE_INT_RW_CHECK(name,min,max,clamp,object,field,function) \
416         { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
417 #define KX_PYATTRIBUTE_INT_RO(name,object,field) \
418         { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
419 #define KX_PYATTRIBUTE_INT_ARRAY_RW(name,min,max,clamp,object,field,length) \
420         { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
421 #define KX_PYATTRIBUTE_INT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \
422         { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
423 #define KX_PYATTRIBUTE_INT_ARRAY_RO(name,object,field,length) \
424         { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
425 // INT_LIST
426 #define KX_PYATTRIBUTE_INT_LIST_RW(name,min,max,clamp,object,field,length) \
427         { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
428 #define KX_PYATTRIBUTE_INT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \
429         { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
430 #define KX_PYATTRIBUTE_INT_LIST_RO(name,object,field,length) \
431         { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
432
433 // always clamp for float
434 #define KX_PYATTRIBUTE_FLOAT_RW(name,min,max,object,field) \
435         { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
436 #define KX_PYATTRIBUTE_FLOAT_RW_CHECK(name,min,max,object,field,function) \
437         { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
438 #define KX_PYATTRIBUTE_FLOAT_RO(name,object,field) \
439         { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
440 #define KX_PYATTRIBUTE_FLOAT_ARRAY_RW(name,min,max,object,field,length) \
441         { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL} }
442 #define KX_PYATTRIBUTE_FLOAT_ARRAY_RW_CHECK(name,min,max,object,field,length,function) \
443         { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL} }
444 #define KX_PYATTRIBUTE_FLOAT_ARRAY_RO(name,object,field,length) \
445         { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL} }
446
447 #define KX_PYATTRIBUTE_STRING_RW(name,min,max,clamp,object,field) \
448         { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
449 #define KX_PYATTRIBUTE_STRING_RW_CHECK(name,min,max,clamp,object,field,function) \
450         { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
451 #define KX_PYATTRIBUTE_STRING_RO(name,object,field) \
452         { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
453
454 #define KX_PYATTRIBUTE_VECTOR_RW(name,min,max,object,field) \
455         { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field} }
456 #define KX_PYATTRIBUTE_VECTOR_RW_CHECK(name,min,max,clamp,object,field,function) \
457         { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field} }
458 #define KX_PYATTRIBUTE_VECTOR_RO(name,object,field) \
459         { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field} }
460
461 #define KX_PYATTRIBUTE_RW_FUNCTION(name,object,getfunction,setfunction) \
462         { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0.f, false, 0, 0, 1, NULL, &object::setfunction, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL} }
463 #define KX_PYATTRIBUTE_RO_FUNCTION(name,object,getfunction) \
464         { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, 0, 0, 1, NULL, NULL, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL} }
465 #define KX_PYATTRIBUTE_ARRAY_RW_FUNCTION(name,object,length,getfunction,setfunction) \
466         { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0,f, false, 0, 0, length, NULL, &object::setfunction, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL} }
467 #define KX_PYATTRIBUTE_ARRAY_RO_FUNCTION(name,object,length,getfunction) \
468         { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0,f, false, 0, 0, length, NULL, NULL, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL} }
469
470
471 /*------------------------------
472  * PyObjectPlus
473 ------------------------------*/
474 typedef PyTypeObject * PyParentObject;                          // Define the PyParent Object
475
476 // By making SG_QList the ultimate parent for PyObjectPlus objects, it
477 // allows to put them in 2 different dynamic lists at the same time
478 // The use of these links is interesting because they free of memory allocation
479 // but it's very important not to mess up with them. If you decide that 
480 // the SG_QList or SG_DList component is used for something for a certain class,
481 // they cannot can be used for anything else at a parent level!
482 // What these lists are and what they are used for must be carefully documented
483 // at the level where they are used.
484 // DON'T MAKE ANY USE OF THESE LIST AT THIS LEVEL, they are already used
485 // at SCA_IActuator, SCA_ISensor, SCA_IController level which rules out the
486 // possibility to use them at SCA_ILogicBrick, CValue and PyObjectPlus level.
487 class PyObjectPlus : public SG_QList
488 {                               // The PyObjectPlus abstract class
489         Py_Header;                                                      // Always start with Py_Header
490         
491 public:
492         PyObjectPlus(PyTypeObject *T);
493
494         PyObject *m_proxy; /* actually a PyObjectPlus_Proxy */
495         
496         virtual ~PyObjectPlus();                                        // destructor
497         
498         /* These static functions are referenced by ALL PyObjectPlus_Proxy types
499          * they take the C++ reference from the PyObjectPlus_Proxy and call
500          * its own virtual py_getattro, py_setattro etc. functions.
501          */
502         static void                     py_base_dealloc(PyObject *self);
503         static  PyObject*               py_base_getattro(PyObject * self, PyObject *attr);
504         static  int                     py_base_setattro(PyObject *self, PyObject *attr, PyObject *value);
505         static PyObject*                py_base_repr(PyObject *self);
506
507         /* These are all virtual python methods that are defined in each class
508          * Our own fake subclassing calls these on each class, then calls the parent */
509         virtual PyObject*               py_getattro(PyObject *attr);
510         virtual PyObject*               py_getattro_dict();
511         virtual int                     py_delattro(PyObject *attr);
512         virtual int                     py_setattro(PyObject *attr, PyObject *value);
513         virtual PyObject*               py_repr(void);
514
515         static PyObject*                py_get_attrdef(void *self, const PyAttributeDef *attrdef);
516         static int                              py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyObject *value);
517         
518         /* isA() methods, shonky replacement for pythons issubclass()
519          * which we cant use because we have our own subclass system  */
520         bool isA(PyTypeObject *T);
521         bool isA(const char *mytypename);
522         
523         KX_PYMETHOD_O(PyObjectPlus,isA);
524         
525         /* Kindof dumb, always returns True, the false case is checked for, before this function gets accessed */
526         static PyObject*        pyattr_get_invalid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
527         
528         static PyObject *GetProxy_Ext(PyObjectPlus *self, PyTypeObject *tp);
529         static PyObject *NewProxy_Ext(PyObjectPlus *self, PyTypeObject *tp, bool py_owns);
530         
531         void    InvalidateProxy();
532         
533         /**
534          * Makes sure any internal data owned by this class is deep copied.
535          */
536         virtual void ProcessReplica();
537         
538         
539         static bool                     m_ignore_deprecation_warnings;
540         
541         static  WarnLink*               GetDeprecationWarningLinkFirst(void);
542         static  WarnLink*               GetDeprecationWarningLinkLast(void);
543         static  void                    SetDeprecationWarningFirst(WarnLink* wlink);
544         static  void                    SetDeprecationWarningLinkLast(WarnLink* wlink);
545         static void                     NullDeprecationWarning();
546         
547         /** enable/disable display of deprecation warnings */
548         static void                     SetDeprecationWarnings(bool ignoreDeprecationWarnings);
549         /** Shows a deprecation warning */
550         static void                     ShowDeprecationWarning_func(const char* method,const char* prop);
551         static void                     ClearDeprecationWarning();
552         
553 };
554
555
556 PyObject *py_getattr_dict(PyObject *pydict, PyObject *tp_dict);
557
558 #endif //  _adr_py_lib_h_
559
560 #endif //NO_EXP_PYTHON_EMBEDDING
561