31 #ifdef USE_DEBUG_PYTHON
35 #ifndef NO_RUNTIME_TYPES
37 #include "dtoolbase.h"
38 #include "typedObject.h"
39 #include "typeRegistry.h"
45 #if defined(HAVE_PYTHON) && !defined(CPPPARSER)
47 #ifdef _POSIX_C_SOURCE
48 #undef _POSIX_C_SOURCE
51 #define PY_SSIZE_T_CLEAN 1
54 #include "structmember.h"
56 #ifndef HAVE_LONG_LONG
57 #define PyLong_FromLongLong(x) PyLong_FromLong((long) (x))
58 #define PyLong_FromUnsignedLongLong(x) PyLong_FromUnsignedLong((unsigned long) (x))
59 #define PyLong_AsLongLong(x) PyLong_AsLong(x)
60 #define PyLong_AsUnsignedLongLong(x) PyLong_AsUnsignedLong(x)
61 #define PyLong_AsUnsignedLongLongMask(x) PyLong_AsUnsignedLongMask(x)
62 #define PyLong_AsLongLongAndOverflow(x) PyLong_AsLongAndOverflow(x)
65 #if PY_VERSION_HEX < 0x02050000
68 typedef int Py_ssize_t;
69 #define PyInt_FromSsize_t PyInt_FromLong
70 #define PyInt_AsSsize_t PyInt_AsLong
72 #endif // PY_VERSION_HEX
75 #ifndef Py_RETURN_NONE
76 inline PyObject* doPy_RETURN_NONE()
77 { Py_INCREF(Py_None);
return Py_None; }
78 #define Py_RETURN_NONE return doPy_RETURN_NONE()
81 #ifndef Py_RETURN_TRUE
82 inline PyObject* doPy_RETURN_TRUE()
83 {Py_INCREF(Py_True);
return Py_True;}
84 #define Py_RETURN_TRUE return doPy_RETURN_TRUE()
87 #ifndef Py_RETURN_FALSE
88 inline PyObject* doPy_RETURN_FALSE()
89 {Py_INCREF(Py_False);
return Py_False;}
90 #define Py_RETURN_FALSE return doPy_RETURN_FALSE()
93 #ifndef PyVarObject_HEAD_INIT
94 #define PyVarObject_HEAD_INIT(type, size) \
95 PyObject_HEAD_INIT(type) size,
99 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
102 #ifndef Py_TPFLAGS_CHECKTYPES
104 #define Py_TPFLAGS_CHECKTYPES 0
107 #if PY_MAJOR_VERSION >= 3
109 #define nb_nonzero nb_bool
110 #define nb_divide nb_true_divide
111 #define nb_inplace_divide nb_inplace_true_divide
113 #define PyLongOrInt_Check(x) PyLong_Check(x)
114 #define PyLongOrInt_FromSize_t PyLong_FromSize_t
115 #define PyLongOrInt_FromSsize_t PyLong_FromSsize_t
116 #define PyLongOrInt_FromLong PyLong_FromLong
117 #define PyLongOrInt_FromUnsignedLong PyLong_FromUnsignedLong
118 #define PyLongOrInt_AS_LONG PyLong_AS_LONG
119 #define PyInt_Check PyLong_Check
120 #define PyInt_AsLong PyLong_AsLong
121 #define PyInt_AS_LONG PyLong_AS_LONG
123 #define PyLongOrInt_Check(x) (PyInt_Check(x) || PyLong_Check(x))
125 #define PyLongOrInt_FromSize_t PyInt_FromSize_t
126 #define PyLongOrInt_FromSsize_t PyInt_FromSsize_t
127 #define PyLongOrInt_FromLong PyInt_FromLong
128 #define PyLongOrInt_AS_LONG PyInt_AsLong
131 typedef long Py_hash_t;
140 #if defined(_WIN32) && !defined(LINK_ALL_STATIC)
141 #define EXPORT_THIS __declspec(dllexport)
142 #define IMPORT_THIS extern __declspec(dllimport)
145 #define IMPORT_THIS extern
149 struct Dtool_PyTypedObject;
150 typedef std::map<int, Dtool_PyTypedObject *> RunTimeTypeDictionary;
151 typedef std::set<int> RunTimeTypeList;
153 EXPCL_DTOOLCONFIG RunTimeTypeDictionary &GetRunTimeDictionary();
154 EXPCL_DTOOLCONFIG RunTimeTypeList &GetRunTimeTypeList();
158 #define PY_PANDA_SIGNATURE 0xbeaf
159 typedef void *(*UpcastFunction)(PyObject *,Dtool_PyTypedObject *);
160 typedef void *(*DowncastFunction)(
void *, Dtool_PyTypedObject *);
169 struct Dtool_PyInstDef {
175 struct Dtool_PyTypedObject *_My_Type;
178 void *_ptr_to_object;
182 unsigned short _signature;
194 extern EXPCL_DTOOLCONFIG PyMemberDef standard_type_members[];
199 struct Dtool_PyTypedObject {
201 PyTypeObject _PyType;
204 UpcastFunction _Dtool_UpcastInterface;
205 DowncastFunction _Dtool_DowncastInterface;
211 inline PyTypeObject &As_PyTypeObject() {
return _PyType; };
212 inline PyObject &As_PyObject() {
return (PyObject &)_PyType; };
217 #define Define_Dtool_Class(MODULE_NAME, CLASS_NAME, PUBLIC_NAME) \
218 extern Dtool_PyTypedObject Dtool_##CLASS_NAME;
223 #define Define_Dtool_new(CLASS_NAME,CNAME)\
224 PyObject *Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds) {\
225 (void) args; (void) kwds;\
226 PyObject *self = type->tp_alloc(type, 0);\
227 ((Dtool_PyInstDef *)self)->_signature = PY_PANDA_SIGNATURE;\
228 ((Dtool_PyInstDef *)self)->_My_Type = &Dtool_##CLASS_NAME;\
242 #define Define_Dtool_FreeInstance_Private(CLASS_NAME,CNAME)\
243 static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
244 Py_TYPE(self)->tp_free(self);\
247 #define Define_Dtool_FreeInstance_Private(CLASS_NAME,CNAME)\
248 static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
249 if (((Dtool_PyInstDef *)self)->_ptr_to_object != NULL) {\
250 if (((Dtool_PyInstDef *)self)->_memory_rules) {\
251 cerr << "Detected leak for " << #CLASS_NAME \
252 << " which interrogate cannot delete.\n"; \
255 Py_TYPE(self)->tp_free(self);\
259 #define Define_Dtool_FreeInstance(CLASS_NAME,CNAME)\
260 static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
261 if (((Dtool_PyInstDef *)self)->_ptr_to_object != NULL) {\
262 if (((Dtool_PyInstDef *)self)->_memory_rules) {\
263 delete ((CNAME *)((Dtool_PyInstDef *)self)->_ptr_to_object);\
266 Py_TYPE(self)->tp_free(self);\
269 #define Define_Dtool_FreeInstanceRef(CLASS_NAME,CNAME)\
270 static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
271 if (((Dtool_PyInstDef *)self)->_ptr_to_object != NULL) {\
272 if (((Dtool_PyInstDef *)self)->_memory_rules) {\
273 unref_delete((CNAME *)((Dtool_PyInstDef *)self)->_ptr_to_object);\
276 Py_TYPE(self)->tp_free(self);\
279 #define Define_Dtool_Simple_FreeInstance(CLASS_NAME, CNAME)\
280 static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
281 ((Dtool_InstDef_##CLASS_NAME *)self)->_value.~##CLASS_NAME();\
282 Py_TYPE(self)->tp_free(self);\
288 EXPCL_DTOOLCONFIG
bool DtoolCanThisBeAPandaInstance(PyObject *
self);
298 EXPCL_DTOOLCONFIG
void RegisterRuntimeClass(Dtool_PyTypedObject *otype,
int class_id);
302 EXPCL_DTOOLCONFIG Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(
int type);
312 EXPCL_DTOOLCONFIG
void DTOOL_Call_ExtractThisPointerForType(PyObject *
self, Dtool_PyTypedObject * classdef,
void ** answer);
314 EXPCL_DTOOLCONFIG
void *DTOOL_Call_GetPointerThisClass(PyObject *
self, Dtool_PyTypedObject *classdef,
int param,
const string &function_name,
bool const_ok,
bool report_errors);
316 EXPCL_DTOOLCONFIG
void *DTOOL_Call_GetPointerThis(PyObject *
self);
318 EXPCL_DTOOLCONFIG
bool Dtool_Call_ExtractThisPointer(PyObject *
self, Dtool_PyTypedObject &classdef,
void **answer);
320 EXPCL_DTOOLCONFIG
bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *
self, Dtool_PyTypedObject &classdef,
321 void **answer,
const char *method_name);
323 template<
class T> INLINE
bool DTOOL_Call_ExtractThisPointer(PyObject *
self, T *&into) {
324 if (DtoolCanThisBeAPandaInstance(
self)) {
325 Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
326 if (target_class != NULL) {
327 into = (T*) ((Dtool_PyInstDef *)
self)->_My_Type->_Dtool_UpcastInterface(
self, target_class);
328 return (into != NULL);
339 #define Dtool_CheckErrorOccurred() (_PyErr_OCCURRED() != NULL)
341 EXPCL_DTOOLCONFIG
bool Dtool_CheckErrorOccurred();
344 EXPCL_DTOOLCONFIG PyObject *Dtool_Raise_AssertionError();
345 EXPCL_DTOOLCONFIG PyObject *Dtool_Raise_TypeError(
const char *message);
346 EXPCL_DTOOLCONFIG PyObject *Dtool_Raise_ArgTypeError(PyObject *obj,
int param,
const char *function_name,
const char *type_name);
347 EXPCL_DTOOLCONFIG PyObject *Dtool_Raise_AttributeError(PyObject *obj,
const char *attribute);
349 EXPCL_DTOOLCONFIG PyObject *_Dtool_Raise_BadArgumentsError();
352 #define Dtool_Raise_BadArgumentsError(x) _Dtool_Raise_BadArgumentsError()
355 #define Dtool_Raise_BadArgumentsError(x) Dtool_Raise_TypeError("Arguments must match:\n" x)
358 EXPCL_DTOOLCONFIG PyObject *_Dtool_Return_None();
359 EXPCL_DTOOLCONFIG PyObject *Dtool_Return_Bool(
bool value);
360 EXPCL_DTOOLCONFIG PyObject *_Dtool_Return(PyObject *value);
363 #define Dtool_Return_None() (_PyErr_OCCURRED() != NULL ? NULL : (Py_INCREF(Py_None), Py_None))
364 #define Dtool_Return(value) (_PyErr_OCCURRED() != NULL ? NULL : value)
366 #define Dtool_Return_None() _Dtool_Return_None()
367 #define Dtool_Return(value) _Dtool_Return(value)
376 EXPCL_DTOOLCONFIG PyObject *DTool_CreatePyInstanceTyped(
void *local_this_in, Dtool_PyTypedObject &known_class_type,
bool memory_rules,
bool is_const,
int RunTimeType);
382 EXPCL_DTOOLCONFIG PyObject *DTool_CreatePyInstance(
void *local_this, Dtool_PyTypedObject &in_classdef,
bool memory_rules,
bool is_const);
386 template<
class T> INLINE PyObject *DTool_CreatePyInstance(
const T *obj,
bool memory_rules) {
387 Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
388 nassertr(known_class != NULL, NULL);
389 return DTool_CreatePyInstance((
void*) obj, *known_class, memory_rules,
true);
392 template<
class T> INLINE PyObject *DTool_CreatePyInstance(T *obj,
bool memory_rules) {
393 Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
394 nassertr(known_class != NULL, NULL);
395 return DTool_CreatePyInstance((
void*) obj, *known_class, memory_rules,
false);
398 template<
class T> INLINE PyObject *DTool_CreatePyInstanceTyped(
const T *obj,
bool memory_rules) {
399 Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
400 nassertr(known_class != NULL, NULL);
401 return DTool_CreatePyInstanceTyped((
void*) obj, *known_class, memory_rules,
true, obj->get_type().get_index());
404 template<
class T> INLINE PyObject *DTool_CreatePyInstanceTyped(T *obj,
bool memory_rules) {
405 Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
406 nassertr(known_class != NULL, NULL);
407 return DTool_CreatePyInstanceTyped((
void*) obj, *known_class, memory_rules,
false, obj->get_type().get_index());
417 #define Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\
418 extern EXPORT_THIS Dtool_PyTypedObject Dtool_##CLASS_NAME;\
419 int Dtool_Init_##CLASS_NAME(PyObject *self, PyObject *args, PyObject *kwds);\
420 PyObject * Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds);\
421 void * Dtool_UpcastInterface_##CLASS_NAME(PyObject *self, Dtool_PyTypedObject *requested_type);\
422 void * Dtool_DowncastInterface_##CLASS_NAME(void *self, Dtool_PyTypedObject *requested_type);
425 #define Define_Module_Class(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\
426 Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\
427 Define_Dtool_new(CLASS_NAME,CNAME)\
428 Define_Dtool_FreeInstance(CLASS_NAME,CNAME)\
429 Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME)
432 #define Define_Module_Class_Private(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\
433 Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\
434 Define_Dtool_new(CLASS_NAME,CNAME)\
435 Define_Dtool_FreeInstance_Private(CLASS_NAME,CNAME)\
436 Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME)
439 #define Define_Module_ClassRef_Private(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\
440 Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\
441 Define_Dtool_new(CLASS_NAME,CNAME)\
442 Define_Dtool_FreeInstance_Private(CLASS_NAME,CNAME)\
443 Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME)
446 #define Define_Module_ClassRef(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\
447 Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\
448 Define_Dtool_new(CLASS_NAME,CNAME)\
449 Define_Dtool_FreeInstanceRef(CLASS_NAME,CNAME)\
450 Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME)
455 EXPCL_DTOOLCONFIG
int DTool_PyInit_Finalize(PyObject *
self,
void *This, Dtool_PyTypedObject *type,
bool memory_rules,
bool is_const);
462 typedef std::map<std::string, PyMethodDef *> MethodDefmap;
464 EXPCL_DTOOLCONFIG
void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap);
471 typedef void (*ConstantFunction)(PyObject *);
473 PyMethodDef *_methods;
474 ConstantFunction _constants;
478 #if PY_MAJOR_VERSION >= 3
479 EXPCL_DTOOLCONFIG PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], PyModuleDef *module_def);
481 EXPCL_DTOOLCONFIG PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[],
const char *modulename);
492 EXPCL_DTOOLCONFIG PyObject *Dtool_BorrowThisReference(PyObject *
self, PyObject *args);
497 EXPCL_DTOOLCONFIG PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args);
501 EXPCL_DTOOLCONFIG Py_hash_t DTOOL_PyObject_HashPointer(PyObject *obj);
511 EXPCL_DTOOLCONFIG
int DTOOL_PyObject_ComparePointers(PyObject *v1, PyObject *v2);
512 EXPCL_DTOOLCONFIG
int DTOOL_PyObject_Compare(PyObject *v1, PyObject *v2);
514 EXPCL_DTOOLCONFIG PyObject *DTOOL_PyObject_RichCompare(PyObject *v1, PyObject *v2,
int op);
516 EXPCL_DTOOLCONFIG PyObject *
517 make_list_for_item(PyObject *
self,
const char *num_name,
518 const char *element_name);
520 EXPCL_DTOOLCONFIG PyObject *
521 copy_from_make_copy(PyObject *
self);
523 EXPCL_DTOOLCONFIG PyObject *
524 copy_from_copy_constructor(PyObject *
self);
526 EXPCL_DTOOLCONFIG PyObject *
527 map_deepcopy_to_copy(PyObject *
self, PyObject *args);
529 #if PY_MAJOR_VERSION < 3
531 EXPCL_DTOOLCONFIG PyObject *
532 PyLongOrInt_FromUnsignedLong(
unsigned long value);
535 EXPCL_DTOOLCONFIG
extern struct Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE;
536 EXPCL_DTOOLCONFIG
extern void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module);
538 #endif // HAVE_PYTHON && !CPPPARSER
540 #endif // PY_PANDA_H_
TypeHandle is the identifier used to differentiate C++ class types.