remove python2.x support
[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 #ifdef USE_MATHUTILS
49 extern "C" {
50 #include "../../blender/python/generic/Mathutils.h" /* so we can have mathutils callbacks */
51 }
52 #endif
53
54 static inline void Py_Fatal(const char *M) {
55         fprintf(stderr, "%s\n", M);
56         exit(-1);
57 };
58
59
60 /* Use with ShowDeprecationWarning macro */
61 typedef struct {
62         bool warn_done;
63         void *link;
64 } WarnLink;
65
66 #define ShowDeprecationWarning(old_way, new_way) \
67 { \
68         static WarnLink wlink = {false, NULL}; \
69         if ((m_ignore_deprecation_warnings || wlink.warn_done)==0) \
70         { \
71                 ShowDeprecationWarning_func(old_way, new_way); \
72  \
73                 WarnLink *wlink_last= GetDeprecationWarningLinkLast(); \
74                 wlink.warn_done = true; \
75                 wlink.link = NULL; \
76          \
77                 if(wlink_last) { \
78                         wlink_last->link= (void *)&(wlink); \
79                         SetDeprecationWarningLinkLast(&(wlink)); \
80                 } else { \
81                         SetDeprecationWarningFirst(&(wlink)); \
82                         SetDeprecationWarningLinkLast(&(wlink)); \
83                 } \
84         } \
85 } \
86
87
88
89 typedef struct {
90         PyObject_HEAD           /* required python macro   */
91         class PyObjectPlus *ref;
92         bool py_owns;
93 } PyObjectPlus_Proxy;
94
95 #define BGE_PROXY_ERROR_MSG "Blender Game Engine data has been freed, cannot use this python variable"
96 #define BGE_PROXY_REF(_self) (((PyObjectPlus_Proxy *)_self)->ref)
97 #define BGE_PROXY_PYOWNS(_self) (((PyObjectPlus_Proxy *)_self)->py_owns)
98
99 /* Note, sometimes we dont care what BGE type this is as long as its a proxy */
100 #define BGE_PROXY_CHECK_TYPE(_type) ((_type)->tp_dealloc == PyObjectPlus::py_base_dealloc)
101
102
103                                                                 // This must be the first line of each 
104                                                                 // PyC++ class
105 #define Py_Header \
106  public: \
107   static PyTypeObject   Type; \
108   static PyMethodDef    Methods[]; \
109   static PyAttributeDef Attributes[]; \
110   virtual PyTypeObject *GetType(void) {return &Type;}; \
111   virtual PyObject *GetProxy() {return GetProxy_Ext(this, &Type);}; \
112   virtual PyObject *NewProxy(bool py_owns) {return NewProxy_Ext(this, &Type, py_owns);}; \
113
114 /*
115  * nonzero values are an error for setattr
116  * however because of the nested lookups we need to know if the errors
117  * was because the attribute didnt exits of if there was some problem setting the value
118  */
119
120 #define PY_SET_ATTR_COERCE_FAIL  2
121 #define PY_SET_ATTR_FAIL                 1
122 #define PY_SET_ATTR_MISSING             -1
123 #define PY_SET_ATTR_SUCCESS              0
124
125 /**
126  * These macros are helpfull when embedding Python routines. The second
127  * macro is one that also requires a documentation string
128  */
129 #define KX_PYMETHOD(class_name, method_name)                    \
130         PyObject* Py##method_name(PyObject* args, PyObject* kwds); \
131         static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \
132                 if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \
133                 return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args, kwds);         \
134         }; \
135
136 #define KX_PYMETHOD_VARARGS(class_name, method_name)                    \
137         PyObject* Py##method_name(PyObject* args); \
138         static PyObject* sPy##method_name( PyObject* self, PyObject* args) { \
139                 if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \
140                 return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args);               \
141         }; \
142
143 #define KX_PYMETHOD_NOARGS(class_name, method_name)                     \
144         PyObject* Py##method_name(); \
145         static PyObject* sPy##method_name( PyObject* self) { \
146                 if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \
147                 return ((class_name*)BGE_PROXY_REF(self))->Py##method_name();           \
148         }; \
149         
150 #define KX_PYMETHOD_O(class_name, method_name)                  \
151         PyObject* Py##method_name(PyObject* value); \
152         static PyObject* sPy##method_name( PyObject* self, PyObject* value) { \
153                 if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(value) - " BGE_PROXY_ERROR_MSG); return NULL; } \
154                 return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(value);              \
155         }; \
156
157 #define KX_PYMETHOD_DOC(class_name, method_name)                        \
158         PyObject* Py##method_name(PyObject* args, PyObject* kwds); \
159         static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \
160                 if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(...) - " BGE_PROXY_ERROR_MSG); return NULL; } \
161                 return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args, kwds);         \
162         }; \
163     static const char method_name##_doc[]; \
164
165 #define KX_PYMETHOD_DOC_VARARGS(class_name, method_name)                        \
166         PyObject* Py##method_name(PyObject* args); \
167         static PyObject* sPy##method_name( PyObject* self, PyObject* args) { \
168                 if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(...) - " BGE_PROXY_ERROR_MSG); return NULL; } \
169                 return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args);               \
170         }; \
171     static const char method_name##_doc[]; \
172
173 #define KX_PYMETHOD_DOC_O(class_name, method_name)                      \
174         PyObject* Py##method_name(PyObject* value); \
175         static PyObject* sPy##method_name( PyObject* self, PyObject* value) { \
176                 if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(value) - " BGE_PROXY_ERROR_MSG); return NULL; } \
177                 return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(value);              \
178         }; \
179     static const char method_name##_doc[]; \
180
181 #define KX_PYMETHOD_DOC_NOARGS(class_name, method_name)                 \
182         PyObject* Py##method_name(); \
183         static PyObject* sPy##method_name( PyObject* self) { \
184                 if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \
185                 return ((class_name*)BGE_PROXY_REF(self))->Py##method_name();           \
186         }; \
187     static const char method_name##_doc[]; \
188
189
190 /* The line above should remain empty */
191 /**
192  * Method table macro (with doc)
193  */
194 #define KX_PYMETHODTABLE(class_name, method_name) \
195         {#method_name , (PyCFunction) class_name::sPy##method_name, METH_VARARGS, (const char *)class_name::method_name##_doc}
196
197 #define KX_PYMETHODTABLE_O(class_name, method_name) \
198         {#method_name , (PyCFunction) class_name::sPy##method_name, METH_O, (const char *)class_name::method_name##_doc}
199
200 #define KX_PYMETHODTABLE_NOARGS(class_name, method_name) \
201         {#method_name , (PyCFunction) class_name::sPy##method_name, METH_NOARGS, (const char *)class_name::method_name##_doc}
202
203 /**
204  * Function implementation macro
205  */
206 #define KX_PYMETHODDEF_DOC(class_name, method_name, doc_string) \
207 const char class_name::method_name##_doc[] = doc_string; \
208 PyObject* class_name::Py##method_name(PyObject* args, PyObject*)
209
210 #define KX_PYMETHODDEF_DOC_VARARGS(class_name, method_name, doc_string) \
211 const char class_name::method_name##_doc[] = doc_string; \
212 PyObject* class_name::Py##method_name(PyObject* args)
213
214 #define KX_PYMETHODDEF_DOC_O(class_name, method_name, doc_string) \
215 const char class_name::method_name##_doc[] = doc_string; \
216 PyObject* class_name::Py##method_name(PyObject* value)
217
218 #define KX_PYMETHODDEF_DOC_NOARGS(class_name, method_name, doc_string) \
219 const char class_name::method_name##_doc[] = doc_string; \
220 PyObject* class_name::Py##method_name()
221
222 /**
223  * Attribute management
224  */
225 enum KX_PYATTRIBUTE_TYPE {
226         KX_PYATTRIBUTE_TYPE_BOOL,
227         KX_PYATTRIBUTE_TYPE_ENUM,
228         KX_PYATTRIBUTE_TYPE_SHORT,
229         KX_PYATTRIBUTE_TYPE_INT,
230         KX_PYATTRIBUTE_TYPE_FLOAT,
231         KX_PYATTRIBUTE_TYPE_STRING,
232         KX_PYATTRIBUTE_TYPE_DUMMY,
233         KX_PYATTRIBUTE_TYPE_FUNCTION,
234         KX_PYATTRIBUTE_TYPE_VECTOR,
235 };
236
237 enum KX_PYATTRIBUTE_ACCESS {
238         KX_PYATTRIBUTE_RW,
239         KX_PYATTRIBUTE_RO
240 };
241
242 struct KX_PYATTRIBUTE_DEF;
243 typedef int (*KX_PYATTRIBUTE_CHECK_FUNCTION)(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
244 typedef int (*KX_PYATTRIBUTE_SET_FUNCTION)(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
245 typedef PyObject* (*KX_PYATTRIBUTE_GET_FUNCTION)(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
246
247 typedef struct KX_PYATTRIBUTE_DEF {
248         const char *m_name;                             // name of the python attribute
249         KX_PYATTRIBUTE_TYPE m_type;             // type of value
250         KX_PYATTRIBUTE_ACCESS m_access; // read/write access or read-only
251         int m_imin;                                             // minimum value in case of integer attributes (for string: minimum string length)
252         int m_imax;                                             // maximum value in case of integer attributes (for string: maximum string length)
253         float m_fmin;                                   // minimum value in case of float attributes
254         float m_fmax;                                   // maximum value in case of float attributes
255         bool   m_clamp;                                 // enforce min/max value by clamping
256         size_t m_offset;                                // position of field in structure
257         size_t m_size;                                  // size of field for runtime verification (enum only)
258         size_t m_length;                                // length of array, 1=simple attribute
259         KX_PYATTRIBUTE_CHECK_FUNCTION m_checkFunction;  // static function to check the assignment, returns 0 if no error
260         KX_PYATTRIBUTE_SET_FUNCTION m_setFunction;      // static function to check the assignment, returns 0 if no error
261         KX_PYATTRIBUTE_GET_FUNCTION m_getFunction;      // static function to check the assignment, returns 0 if no error
262
263         // The following pointers are just used to have compile time check for attribute type.
264         // It would have been good to use a union but that would require C99 compatibility
265         // to initialize specific union fields through designated initializers.
266         struct {
267                 bool *m_boolPtr;
268                 short int *m_shortPtr;
269                 int *m_intPtr;
270                 float *m_floatPtr;
271                 STR_String *m_stringPtr;
272                 MT_Vector3 *m_vectorPtr;
273         } m_typeCheck;
274 } PyAttributeDef;
275
276 #define KX_PYATTRIBUTE_DUMMY(name) \
277         { 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} }
278
279 #define KX_PYATTRIBUTE_BOOL_RW(name,object,field) \
280         { 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} }
281 #define KX_PYATTRIBUTE_BOOL_RW_CHECK(name,object,field,function) \
282         { 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} }
283 #define KX_PYATTRIBUTE_BOOL_RO(name,object,field) \
284         { 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} }
285
286 // enum field cannot be mapped to pointer (because we would need a pointer for each enum)
287 // use field size to verify mapping at runtime only, assuming enum size is equal to int size.
288 #define KX_PYATTRIBUTE_ENUM_RW(name,min,max,clamp,object,field) \
289         { 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} }
290 #define KX_PYATTRIBUTE_ENUM_RW_CHECK(name,min,max,clamp,object,field,function) \
291         { 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} }
292 #define KX_PYATTRIBUTE_ENUM_RO(name,object,field) \
293         { 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} }
294
295 #define KX_PYATTRIBUTE_SHORT_RW(name,min,max,clamp,object,field) \
296         { 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} }
297 #define KX_PYATTRIBUTE_SHORT_RW_CHECK(name,min,max,clamp,object,field,function) \
298         { 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} }
299 #define KX_PYATTRIBUTE_SHORT_RO(name,object,field) \
300         { 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} }
301 #define KX_PYATTRIBUTE_SHORT_ARRAY_RW(name,min,max,clamp,object,field,length) \
302         { 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} }
303 #define KX_PYATTRIBUTE_SHORT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \
304         { 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} }
305 #define KX_PYATTRIBUTE_SHORT_ARRAY_RO(name,object,field,length) \
306         { 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} }
307 // SHORT_LIST
308 #define KX_PYATTRIBUTE_SHORT_LIST_RW(name,min,max,clamp,object,field,length) \
309         { 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} }
310 #define KX_PYATTRIBUTE_SHORT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \
311         { 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} }
312 #define KX_PYATTRIBUTE_SHORT_LIST_RO(name,object,field,length) \
313         { 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} }
314
315 #define KX_PYATTRIBUTE_INT_RW(name,min,max,clamp,object,field) \
316         { 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} }
317 #define KX_PYATTRIBUTE_INT_RW_CHECK(name,min,max,clamp,object,field,function) \
318         { 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} }
319 #define KX_PYATTRIBUTE_INT_RO(name,object,field) \
320         { 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} }
321 #define KX_PYATTRIBUTE_INT_ARRAY_RW(name,min,max,clamp,object,field,length) \
322         { 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} }
323 #define KX_PYATTRIBUTE_INT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \
324         { 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} }
325 #define KX_PYATTRIBUTE_INT_ARRAY_RO(name,object,field,length) \
326         { 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} }
327 // INT_LIST
328 #define KX_PYATTRIBUTE_INT_LIST_RW(name,min,max,clamp,object,field,length) \
329         { 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} }
330 #define KX_PYATTRIBUTE_INT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \
331         { 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} }
332 #define KX_PYATTRIBUTE_INT_LIST_RO(name,object,field,length) \
333         { 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} }
334
335 // always clamp for float
336 #define KX_PYATTRIBUTE_FLOAT_RW(name,min,max,object,field) \
337         { 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} }
338 #define KX_PYATTRIBUTE_FLOAT_RW_CHECK(name,min,max,object,field,function) \
339         { 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} }
340 #define KX_PYATTRIBUTE_FLOAT_RO(name,object,field) \
341         { 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} }
342 #define KX_PYATTRIBUTE_FLOAT_ARRAY_RW(name,min,max,object,field,length) \
343         { 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} }
344 #define KX_PYATTRIBUTE_FLOAT_ARRAY_RW_CHECK(name,min,max,object,field,length,function) \
345         { 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} }
346 #define KX_PYATTRIBUTE_FLOAT_ARRAY_RO(name,object,field,length) \
347         { 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} }
348
349 #define KX_PYATTRIBUTE_STRING_RW(name,min,max,clamp,object,field) \
350         { 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} }
351 #define KX_PYATTRIBUTE_STRING_RW_CHECK(name,min,max,clamp,object,field,function) \
352         { 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} }
353 #define KX_PYATTRIBUTE_STRING_RO(name,object,field) \
354         { 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} }
355
356 #define KX_PYATTRIBUTE_VECTOR_RW(name,min,max,object,field) \
357         { 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} }
358 #define KX_PYATTRIBUTE_VECTOR_RW_CHECK(name,min,max,clamp,object,field,function) \
359         { 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} }
360 #define KX_PYATTRIBUTE_VECTOR_RO(name,object,field) \
361         { 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} }
362
363 #define KX_PYATTRIBUTE_RW_FUNCTION(name,object,getfunction,setfunction) \
364         { 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} }
365 #define KX_PYATTRIBUTE_RO_FUNCTION(name,object,getfunction) \
366         { 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} }
367 #define KX_PYATTRIBUTE_ARRAY_RW_FUNCTION(name,object,length,getfunction,setfunction) \
368         { 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} }
369 #define KX_PYATTRIBUTE_ARRAY_RO_FUNCTION(name,object,length,getfunction) \
370         { 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} }
371
372
373 /*------------------------------
374  * PyObjectPlus
375 ------------------------------*/
376 typedef PyTypeObject * PyParentObject;                          // Define the PyParent Object
377
378 // By making SG_QList the ultimate parent for PyObjectPlus objects, it
379 // allows to put them in 2 different dynamic lists at the same time
380 // The use of these links is interesting because they free of memory allocation
381 // but it's very important not to mess up with them. If you decide that 
382 // the SG_QList or SG_DList component is used for something for a certain class,
383 // they cannot can be used for anything else at a parent level!
384 // What these lists are and what they are used for must be carefully documented
385 // at the level where they are used.
386 // DON'T MAKE ANY USE OF THESE LIST AT THIS LEVEL, they are already used
387 // at SCA_IActuator, SCA_ISensor, SCA_IController level which rules out the
388 // possibility to use them at SCA_ILogicBrick, CValue and PyObjectPlus level.
389 class PyObjectPlus : public SG_QList
390 {                               // The PyObjectPlus abstract class
391         Py_Header;                                                      // Always start with Py_Header
392         
393 public:
394         PyObjectPlus();
395
396         PyObject *m_proxy; /* actually a PyObjectPlus_Proxy */
397         
398         virtual ~PyObjectPlus();                                        // destructor
399         
400         /* These static functions are referenced by ALL PyObjectPlus_Proxy types
401          * they take the C++ reference from the PyObjectPlus_Proxy and call
402          * its own virtual py_repr, py_base_dealloc ,etc. functions.
403          */
404
405         static PyObject*                py_base_new(PyTypeObject *type, PyObject *args, PyObject *kwds); /* allows subclassing */
406         static void                     py_base_dealloc(PyObject *self);
407         static PyObject*                py_base_repr(PyObject *self);
408
409         /* These are all virtual python methods that are defined in each class
410          * Our own fake subclassing calls these on each class, then calls the parent */
411         virtual PyObject*               py_repr(void);
412
413         static PyObject*                py_get_attrdef(PyObject *self_py, const PyAttributeDef *attrdef);
414         static int                              py_set_attrdef(PyObject *self_py, PyObject *value, const PyAttributeDef *attrdef);
415         
416         /* Kindof dumb, always returns True, the false case is checked for, before this function gets accessed */
417         static PyObject*        pyattr_get_invalid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
418         
419         static PyObject *GetProxy_Ext(PyObjectPlus *self, PyTypeObject *tp);
420         static PyObject *NewProxy_Ext(PyObjectPlus *self, PyTypeObject *tp, bool py_owns);
421         
422         void    InvalidateProxy();
423         
424         /**
425          * Makes sure any internal data owned by this class is deep copied.
426          */
427         virtual void ProcessReplica();
428         
429         
430         static bool                     m_ignore_deprecation_warnings;
431         
432         static  WarnLink*               GetDeprecationWarningLinkFirst(void);
433         static  WarnLink*               GetDeprecationWarningLinkLast(void);
434         static  void                    SetDeprecationWarningFirst(WarnLink* wlink);
435         static  void                    SetDeprecationWarningLinkLast(WarnLink* wlink);
436         static void                     NullDeprecationWarning();
437         
438         /** enable/disable display of deprecation warnings */
439         static void                     SetDeprecationWarnings(bool ignoreDeprecationWarnings);
440         /** Shows a deprecation warning */
441         static void                     ShowDeprecationWarning_func(const char* method,const char* prop);
442         static void                     ClearDeprecationWarning();
443         
444 };
445
446
447 PyObject *py_getattr_dict(PyObject *pydict, PyObject *tp_dict);
448
449 #endif //  _adr_py_lib_h_
450
451 #endif //NO_EXP_PYTHON_EMBEDDING
452