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