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