3be9a2f2bcb82eb45094fb8a7ca40448c5a4b548
[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
42 /*------------------------------
43  * Python defines
44 ------------------------------*/
45
46 /*
47    Py_RETURN_NONE
48    Python 2.4 macro.
49    defined here until we switch to 2.4
50    also in api2_2x/gen_utils.h 
51 */
52 #ifndef Py_RETURN_NONE
53 #define Py_RETURN_NONE  return Py_BuildValue("O", Py_None)
54 #endif
55 #ifndef Py_RETURN_FALSE
56 #define Py_RETURN_FALSE  return PyBool_FromLong(0)
57 #endif
58 #ifndef Py_RETURN_TRUE
59 #define Py_RETURN_TRUE  return PyBool_FromLong(1)
60 #endif
61
62 /*  for pre Py 2.5 */
63 #if PY_VERSION_HEX < 0x02050000
64 typedef int Py_ssize_t;
65 typedef Py_ssize_t (*lenfunc)(PyObject *);
66 #define PY_SSIZE_T_MAX INT_MAX
67 #define PY_SSIZE_T_MIN INT_MIN
68 #define PY_METHODCHAR char *
69 #else
70 /* Py 2.5 and later */
71 #define  intargfunc  ssizeargfunc
72 #define intintargfunc  ssizessizeargfunc
73 #define PY_METHODCHAR const char *
74 #endif
75
76 #include "descrobject.h"
77
78
79 static inline void Py_Fatal(const char *M) {
80         fprintf(stderr, "%s\n", M);
81         exit(-1);
82 };
83
84 typedef struct {
85         PyObject_HEAD           /* required python macro   */
86         class PyObjectPlus *ref;
87         bool py_owns;
88 } PyObjectPlus_Proxy;
89
90 #define BGE_PROXY_ERROR_MSG "Blender Game Engine data has been freed, cannot use this python variable"
91 #define BGE_PROXY_REF(_self) (((PyObjectPlus_Proxy *)_self)->ref)
92 #define BGE_PROXY_PYOWNS(_self) (((PyObjectPlus_Proxy *)_self)->py_owns)
93
94 /* Note, sometimes we dont care what BGE type this is as long as its a proxy */
95 #define BGE_PROXY_CHECK_TYPE(_self) ((_self)->ob_type->tp_dealloc == PyDestructor)
96
97
98                                                                 // This must be the first line of each 
99                                                                 // PyC++ class
100 #define Py_Header \
101  public: \
102   static PyTypeObject   Type; \
103   static PyMethodDef    Methods[]; \
104   static PyAttributeDef Attributes[]; \
105   static PyParentObject Parents[]; \
106   virtual PyTypeObject *GetType(void) {return &Type;}; \
107   virtual PyParentObject *GetParents(void) {return Parents;} \
108   virtual PyObject *GetProxy() {return GetProxy_Ext(this, &Type);}; \
109   virtual PyObject *NewProxy(bool py_owns) {return NewProxy_Ext(this, &Type, py_owns);}; \
110
111
112
113
114                                                                 // This defines the py_getattro_up macro
115                                                                 // which allows attribute and method calls
116                                                                 // to be properly passed up the hierarchy.
117
118 #define py_getattro_up(Parent) \
119         \
120         PyObject *descr = PyDict_GetItem(Type.tp_dict, attr); \
121          \
122         if(descr) { \
123                 if (PyCObject_Check(descr)) { \
124                         return py_get_attrdef((void *)this, (const PyAttributeDef*)PyCObject_AsVoidPtr(descr)); \
125                 } else if (descr->ob_type->tp_descr_get) { \
126                         return PyCFunction_New(((PyMethodDescrObject *)descr)->d_method, this->m_proxy); \
127                 } else { \
128                         fprintf(stderr, "unknown attribute type"); \
129                         return descr; \
130                 } \
131         } else { \
132                 PyErr_Clear(); \
133                 PyObject *rvalue= Parent::py_getattro(attr); \
134                  \
135                 if (strcmp(PyString_AsString(attr), "__dict__")==0) { \
136                         return py_getattr_dict(rvalue, Type.tp_dict); \
137                 } \
138                  \
139                 return rvalue; \
140         } \
141         return NULL;
142
143
144 /*
145  * nonzero values are an error for setattr
146  * however because of the nested lookups we need to know if the errors
147  * was because the attribute didnt exits of if there was some problem setting the value
148  */
149
150 #define PY_SET_ATTR_COERCE_FAIL  2
151 #define PY_SET_ATTR_FAIL                 1
152 #define PY_SET_ATTR_MISSING             -1
153 #define PY_SET_ATTR_SUCCESS              0
154
155 #define py_setattro_up(Parent) \
156         PyObject *descr = PyDict_GetItem(Type.tp_dict, attr); \
157          \
158         if(descr) { \
159                 if (PyCObject_Check(descr)) { \
160                         const PyAttributeDef* attrdef= reinterpret_cast<const PyAttributeDef *>(PyCObject_AsVoidPtr(descr)); \
161                         if (attrdef->m_access == KX_PYATTRIBUTE_RO) { \
162                                 PyErr_Format(PyExc_AttributeError, "\"%s\" is read only", PyString_AsString(attr)); \
163                                 return PY_SET_ATTR_FAIL; \
164                         } \
165                         else { \
166                                 return py_set_attrdef((void *)this, attrdef, value); \
167                         } \
168                 } else { \
169                         PyErr_Format(PyExc_AttributeError, "\"%s\" cannot be set", PyString_AsString(attr)); \
170                         return PY_SET_ATTR_FAIL; \
171                 } \
172         } else { \
173                 PyErr_Clear(); \
174                 return Parent::py_setattro(attr, value); \
175         }
176
177
178 /**
179  * These macros are helpfull when embedding Python routines. The second
180  * macro is one that also requires a documentation string
181  */
182 #define KX_PYMETHOD(class_name, method_name)                    \
183         PyObject* Py##method_name(PyObject* self, PyObject* args, PyObject* kwds); \
184         static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \
185                 PyObjectPlus *self_plus= BGE_PROXY_REF(self); \
186                 return ((class_name*)self_plus)->Py##method_name(self, args, kwds);             \
187         }; \
188
189 #define KX_PYMETHOD_VARARGS(class_name, method_name)                    \
190         PyObject* Py##method_name(PyObject* self, PyObject* args); \
191         static PyObject* sPy##method_name( PyObject* self, PyObject* args) { \
192                 PyObjectPlus *self_plus= BGE_PROXY_REF(self); \
193                 return ((class_name*)self_plus)->Py##method_name(self, args);           \
194         }; \
195
196 #define KX_PYMETHOD_NOARGS(class_name, method_name)                     \
197         PyObject* Py##method_name(PyObject* self); \
198         static PyObject* sPy##method_name( PyObject* self) { \
199                 PyObjectPlus *self_plus= BGE_PROXY_REF(self); \
200                 return ((class_name*)self_plus)->Py##method_name(self);         \
201         }; \
202         
203 #define KX_PYMETHOD_O(class_name, method_name)                  \
204         PyObject* Py##method_name(PyObject* self, PyObject* value); \
205         static PyObject* sPy##method_name( PyObject* self, PyObject* value) { \
206                 PyObjectPlus *self_plus= ((PyObjectPlus_Proxy *)self)->ref; \
207                 return ((class_name*) self_plus)->Py##method_name(self, value);         \
208         }; \
209
210 #define KX_PYMETHOD_DOC(class_name, method_name)                        \
211         PyObject* Py##method_name(PyObject* self, PyObject* args, PyObject* kwds); \
212         static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \
213                 PyObjectPlus *self_plus= BGE_PROXY_REF(self); \
214                 return ((class_name*)self_plus)->Py##method_name(self, args, kwds);             \
215         }; \
216     static const char method_name##_doc[]; \
217
218 #define KX_PYMETHOD_DOC_VARARGS(class_name, method_name)                        \
219         PyObject* Py##method_name(PyObject* self, PyObject* args); \
220         static PyObject* sPy##method_name( PyObject* self, PyObject* args) { \
221                 PyObjectPlus *self_plus= BGE_PROXY_REF(self); \
222                 return ((class_name*)self_plus)->Py##method_name(self, args);           \
223         }; \
224     static const char method_name##_doc[]; \
225
226 #define KX_PYMETHOD_DOC_O(class_name, method_name)                      \
227         PyObject* Py##method_name(PyObject* self, PyObject* value); \
228         static PyObject* sPy##method_name( PyObject* self, PyObject* value) { \
229                 PyObjectPlus *self_plus= BGE_PROXY_REF(self); \
230                 return ((class_name*)self_plus)->Py##method_name(self, value);          \
231         }; \
232     static const char method_name##_doc[]; \
233
234 #define KX_PYMETHOD_DOC_NOARGS(class_name, method_name)                 \
235         PyObject* Py##method_name(PyObject* self); \
236         static PyObject* sPy##method_name( PyObject* self) { \
237                 PyObjectPlus *self_plus= BGE_PROXY_REF(self); \
238                 return ((class_name*)self_plus)->Py##method_name(self);         \
239         }; \
240     static const char method_name##_doc[]; \
241
242
243 /* The line above should remain empty */
244 /**
245  * Method table macro (with doc)
246  */
247 #define KX_PYMETHODTABLE(class_name, method_name) \
248         {#method_name , (PyCFunction) class_name::sPy##method_name, METH_VARARGS, (PY_METHODCHAR)class_name::method_name##_doc}
249
250 #define KX_PYMETHODTABLE_O(class_name, method_name) \
251         {#method_name , (PyCFunction) class_name::sPy##method_name, METH_O, (PY_METHODCHAR)class_name::method_name##_doc}
252
253 #define KX_PYMETHODTABLE_NOARGS(class_name, method_name) \
254         {#method_name , (PyCFunction) class_name::sPy##method_name, METH_NOARGS, (PY_METHODCHAR)class_name::method_name##_doc}
255
256 /**
257  * Function implementation macro
258  */
259 #define KX_PYMETHODDEF_DOC(class_name, method_name, doc_string) \
260 const char class_name::method_name##_doc[] = doc_string; \
261 PyObject* class_name::Py##method_name(PyObject* self, PyObject* args, PyObject*)
262
263 #define KX_PYMETHODDEF_DOC_VARARGS(class_name, method_name, doc_string) \
264 const char class_name::method_name##_doc[] = doc_string; \
265 PyObject* class_name::Py##method_name(PyObject* self, PyObject* args)
266
267 #define KX_PYMETHODDEF_DOC_O(class_name, method_name, doc_string) \
268 const char class_name::method_name##_doc[] = doc_string; \
269 PyObject* class_name::Py##method_name(PyObject* self, PyObject* value)
270
271 #define KX_PYMETHODDEF_DOC_NOARGS(class_name, method_name, doc_string) \
272 const char class_name::method_name##_doc[] = doc_string; \
273 PyObject* class_name::Py##method_name(PyObject* self)
274
275 /**
276  * Attribute management
277  */
278 enum KX_PYATTRIBUTE_TYPE {
279         KX_PYATTRIBUTE_TYPE_BOOL,
280         KX_PYATTRIBUTE_TYPE_ENUM,
281         KX_PYATTRIBUTE_TYPE_SHORT,
282         KX_PYATTRIBUTE_TYPE_INT,
283         KX_PYATTRIBUTE_TYPE_FLOAT,
284         KX_PYATTRIBUTE_TYPE_STRING,
285         KX_PYATTRIBUTE_TYPE_DUMMY,
286         KX_PYATTRIBUTE_TYPE_FUNCTION,
287 };
288
289 enum KX_PYATTRIBUTE_ACCESS {
290         KX_PYATTRIBUTE_RW,
291         KX_PYATTRIBUTE_RO
292 };
293
294 struct KX_PYATTRIBUTE_DEF;
295 typedef int (*KX_PYATTRIBUTE_CHECK_FUNCTION)(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
296 typedef int (*KX_PYATTRIBUTE_SET_FUNCTION)(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
297 typedef PyObject* (*KX_PYATTRIBUTE_GET_FUNCTION)(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
298
299 typedef struct KX_PYATTRIBUTE_DEF {
300         const char *m_name;                             // name of the python attribute
301         KX_PYATTRIBUTE_TYPE m_type;             // type of value
302         KX_PYATTRIBUTE_ACCESS m_access; // read/write access or read-only
303         int m_imin;                                             // minimum value in case of integer attributes (for string: minimum string length)
304         int m_imax;                                             // maximum value in case of integer attributes (for string: maximum string length)
305         float m_fmin;                                   // minimum value in case of float attributes
306         float m_fmax;                                   // maximum value in case of float attributes
307         bool   m_clamp;                                 // enforce min/max value by clamping
308         size_t m_offset;                                // position of field in structure
309         size_t m_size;                                  // size of field for runtime verification (enum only)
310         size_t m_length;                                // length of array, 1=simple attribute
311         KX_PYATTRIBUTE_CHECK_FUNCTION m_checkFunction;  // static function to check the assignment, returns 0 if no error
312         KX_PYATTRIBUTE_SET_FUNCTION m_setFunction;      // static function to check the assignment, returns 0 if no error
313         KX_PYATTRIBUTE_GET_FUNCTION m_getFunction;      // static function to check the assignment, returns 0 if no error
314
315         // The following pointers are just used to have compile time check for attribute type.
316         // It would have been good to use a union but that would require C99 compatibility
317         // to initialize specific union fields through designated initializers.
318         struct {
319                 bool *m_boolPtr;
320                 short int *m_shortPtr;
321                 int *m_intPtr;
322                 float *m_floatPtr;
323                 STR_String *m_stringPtr;
324         } m_typeCheck;
325 } PyAttributeDef;
326
327 #define KX_PYATTRIBUTE_DUMMY(name) \
328         { 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} }
329
330 #define KX_PYATTRIBUTE_BOOL_RW(name,object,field) \
331         { 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} }
332 #define KX_PYATTRIBUTE_BOOL_RW_CHECK(name,object,field,function) \
333         { 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} }
334 #define KX_PYATTRIBUTE_BOOL_RO(name,object,field) \
335         { 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} }
336
337 // enum field cannot be mapped to pointer (because we would need a pointer for each enum)
338 // use field size to verify mapping at runtime only, assuming enum size is equal to int size.
339 #define KX_PYATTRIBUTE_ENUM_RW(name,min,max,clamp,object,field) \
340         { 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} }
341 #define KX_PYATTRIBUTE_ENUM_RW_CHECK(name,min,max,clamp,object,field,function) \
342         { 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} }
343 #define KX_PYATTRIBUTE_ENUM_RO(name,object,field) \
344         { 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} }
345
346 #define KX_PYATTRIBUTE_SHORT_RW(name,min,max,clamp,object,field) \
347         { 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} }
348 #define KX_PYATTRIBUTE_SHORT_RW_CHECK(name,min,max,clamp,object,field,function) \
349         { 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} }
350 #define KX_PYATTRIBUTE_SHORT_RO(name,object,field) \
351         { 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} }
352 #define KX_PYATTRIBUTE_SHORT_ARRAY_RW(name,min,max,clamp,object,field,length) \
353         { 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} }
354 #define KX_PYATTRIBUTE_SHORT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \
355         { 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} }
356 #define KX_PYATTRIBUTE_SHORT_ARRAY_RO(name,object,field,length) \
357         { 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} }
358 // SHORT_LIST
359 #define KX_PYATTRIBUTE_SHORT_LIST_RW(name,min,max,clamp,object,field,length) \
360         { 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} }
361 #define KX_PYATTRIBUTE_SHORT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \
362         { 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} }
363 #define KX_PYATTRIBUTE_SHORT_LIST_RO(name,object,field,length) \
364         { 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} }
365
366 #define KX_PYATTRIBUTE_INT_RW(name,min,max,clamp,object,field) \
367         { 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} }
368 #define KX_PYATTRIBUTE_INT_RW_CHECK(name,min,max,clamp,object,field,function) \
369         { 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} }
370 #define KX_PYATTRIBUTE_INT_RO(name,object,field) \
371         { 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} }
372 #define KX_PYATTRIBUTE_INT_ARRAY_RW(name,min,max,clamp,object,field,length) \
373         { 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} }
374 #define KX_PYATTRIBUTE_INT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \
375         { 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} }
376 #define KX_PYATTRIBUTE_INT_ARRAY_RO(name,object,field,length) \
377         { 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} }
378 // INT_LIST
379 #define KX_PYATTRIBUTE_INT_LIST_RW(name,min,max,clamp,object,field,length) \
380         { 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} }
381 #define KX_PYATTRIBUTE_INT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \
382         { 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} }
383 #define KX_PYATTRIBUTE_INT_LIST_RO(name,object,field,length) \
384         { 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} }
385
386 // always clamp for float
387 #define KX_PYATTRIBUTE_FLOAT_RW(name,min,max,object,field) \
388         { 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} }
389 #define KX_PYATTRIBUTE_FLOAT_RW_CHECK(name,min,max,object,field,function) \
390         { 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} }
391 #define KX_PYATTRIBUTE_FLOAT_RO(name,object,field) \
392         { 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} }
393 #define KX_PYATTRIBUTE_FLOAT_ARRAY_RW(name,min,max,object,field,length) \
394         { 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} }
395 #define KX_PYATTRIBUTE_FLOAT_ARRAY_RW_CHECK(name,min,max,object,field,length,function) \
396         { 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} }
397 #define KX_PYATTRIBUTE_FLOAT_ARRAY_RO(name,object,field,length) \
398         { 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} }
399
400 #define KX_PYATTRIBUTE_STRING_RW(name,min,max,clamp,object,field) \
401         { 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} }
402 #define KX_PYATTRIBUTE_STRING_RW_CHECK(name,min,max,clamp,object,field,function) \
403         { 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} }
404 #define KX_PYATTRIBUTE_STRING_RO(name,object,field) \
405         { 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} }
406
407 #define KX_PYATTRIBUTE_RW_FUNCTION(name,object,getfunction,setfunction) \
408         { 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} }
409 #define KX_PYATTRIBUTE_RO_FUNCTION(name,object,getfunction) \
410         { 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} }
411 #define KX_PYATTRIBUTE_ARRAY_RW_FUNCTION(name,object,length,getfunction,setfunction) \
412         { 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} }
413 #define KX_PYATTRIBUTE_ARRAY_RO_FUNCTION(name,object,length,getfunction) \
414         { 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} }
415
416
417 /*------------------------------
418  * PyObjectPlus
419 ------------------------------*/
420 typedef PyTypeObject * PyParentObject;                          // Define the PyParent Object
421
422 class PyObjectPlus 
423 {                               // The PyObjectPlus abstract class
424         Py_Header;                                                      // Always start with Py_Header
425         
426 public:
427         PyObjectPlus(PyTypeObject *T);
428
429         PyObject *m_proxy; /* actually a PyObjectPlus_Proxy */
430         
431         virtual ~PyObjectPlus();                                        // destructor
432         static void PyDestructor(PyObject *self);                               // python wrapper
433         
434 //      void INCREF(void) {
435 //                Py_INCREF(this);
436 //        };                            // incref method
437 //      void DECREF(void) {
438 //                Py_DECREF(this);
439 //        };                            // decref method
440         
441         virtual PyObject *py_getattro(PyObject *attr);                  // py_getattro method
442         static  PyObject *py_base_getattro(PyObject * self, PyObject *attr)     // This should be the entry in Type. 
443         {
444                 PyObjectPlus *self_plus= BGE_PROXY_REF(self);
445                 if(self_plus==NULL) {
446                         if(!strcmp("isValid", PyString_AsString(attr))) {
447                                 Py_RETURN_TRUE;
448                         }
449                         PyErr_SetString(PyExc_RuntimeError, "data has been removed");
450                         return NULL;
451                 }
452                 return self_plus->py_getattro(attr); 
453         }
454         
455         static PyObject*        py_get_attrdef(void *self, const PyAttributeDef *attrdef);
456         static int                      py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyObject *value);
457         
458 #if 0
459         static PyObject *py_getattro_self(const PyAttributeDef attrlist[], void *self, PyObject *attr);
460         static int py_setattro_self(const PyAttributeDef attrlist[], void *self, PyObject *attr, PyObject *value);
461 #endif
462         
463         virtual int py_delattro(PyObject *attr);
464         virtual int py_setattro(PyObject *attr, PyObject *value);               // py_setattro method
465         static  int py_base_setattro(PyObject *self, PyObject *attr, PyObject *value) // the PyType should reference this
466         {
467                 PyObjectPlus *self_plus= BGE_PROXY_REF(self);
468                 if(self_plus==NULL) {
469                         PyErr_SetString(PyExc_RuntimeError, "data has been removed");
470                         return -1;
471                 }
472                 
473                 if (value==NULL)
474                         return self_plus->py_delattro(attr);
475                 
476                 return self_plus->py_setattro(attr, value); 
477         }
478         
479         virtual PyObject *py_repr(void);                                // py_repr method
480         static  PyObject *py_base_repr(PyObject *self)                  // This should be the entry in Type.
481         {
482                 
483                 PyObjectPlus *self_plus= BGE_PROXY_REF(self);
484                 if(self_plus==NULL) {
485                         PyErr_SetString(PyExc_RuntimeError, "data has been removed");
486                         return NULL;
487                 }
488                 
489                 return self_plus->py_repr();  
490         }
491         
492                                                                         // isA methods
493         bool isA(PyTypeObject *T);
494         bool isA(const char *mytypename);
495         PyObject *Py_isA(PyObject *value);
496         static PyObject *sPy_isA(PyObject *self, PyObject *value)
497         {
498                 PyObjectPlus *self_plus= BGE_PROXY_REF(self);
499                 if(self_plus==NULL) {
500                         PyErr_SetString(PyExc_RuntimeError, "data has been removed");
501                         return NULL;
502                 }
503                 
504                 return self_plus->Py_isA(value);
505         }
506         
507         /* Kindof dumb, always returns True, the false case is checked for, before this function gets accessed */
508         static PyObject*        pyattr_get_is_valid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
509         
510         static PyObject *GetProxy_Ext(PyObjectPlus *self, PyTypeObject *tp);
511         static PyObject *NewProxy_Ext(PyObjectPlus *self, PyTypeObject *tp, bool py_owns);
512 };
513
514 PyObject *py_getattr_dict(PyObject *pydict, PyObject *tp_dict);
515
516 #endif //  _adr_py_lib_h_
517
518 #endif //NO_EXP_PYTHON_EMBEDDING
519