Panda3D
py_panda.h
1 #ifndef PY_PANDA_H_
2 #define PY_PANDA_H_
3 // Filename: py_panda.h
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 //////////////////////////////////////////////////////////////////////////////////////////////
15 // Too do list ..
16 // We need a better dispatcher for the functions.. The behavior today is
17 // try one till it works or you run out of possibilities.. This is anything but optimal
18 // for performance and is treading on thin ice for function python or c++ will
19 // course there types to other types.
20 //
21 // The linking step will produce allot of warnings
22 // warning LNK4049: locally defined symbol..
23 //
24 // Get a second coder to review this file and the generated code ..
25 //
26 //////////////////////////////////////////////////////////////////////////////////////////////
27 #include <set>
28 #include <map>
29 #include <string>
30 
31 #ifdef USE_DEBUG_PYTHON
32 #define Py_DEBUG
33 #endif
34 
35 #ifndef NO_RUNTIME_TYPES
36 
37 #include "dtoolbase.h"
38 #include "typedObject.h"
39 #include "typeRegistry.h"
40 
41 #endif
42 
43 #include "pnotify.h"
44 
45 #if defined(HAVE_PYTHON) && !defined(CPPPARSER)
46 
47 #ifdef _POSIX_C_SOURCE
48 #undef _POSIX_C_SOURCE
49 #endif
50 
51 #define PY_SSIZE_T_CLEAN 1
52 
53 #include "Python.h"
54 #include "structmember.h"
55 
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)
63 #endif
64 
65 #if PY_VERSION_HEX < 0x02050000
66 
67 // Prior to Python 2.5, we didn't have Py_ssize_t.
68 typedef int Py_ssize_t;
69 #define PyInt_FromSsize_t PyInt_FromLong
70 #define PyInt_AsSsize_t PyInt_AsLong
71 
72 #endif // PY_VERSION_HEX
73 
74 // 2.4 macros which aren't available in 2.3
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()
79 #endif
80 
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()
85 #endif
86 
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()
91 #endif
92 
93 #ifndef PyVarObject_HEAD_INIT
94 #define PyVarObject_HEAD_INIT(type, size) \
95  PyObject_HEAD_INIT(type) size,
96 #endif
97 
98 #ifndef Py_TYPE
99 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
100 #endif
101 
102 #ifndef Py_TPFLAGS_CHECKTYPES
103 // Always on in Python 3
104 #define Py_TPFLAGS_CHECKTYPES 0
105 #endif
106 
107 #if PY_MAJOR_VERSION >= 3
108 // For writing code that will compile in both versions.
109 #define nb_nonzero nb_bool
110 #define nb_divide nb_true_divide
111 #define nb_inplace_divide nb_inplace_true_divide
112 
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
122 #else
123 #define PyLongOrInt_Check(x) (PyInt_Check(x) || PyLong_Check(x))
124 // PyInt_FromSize_t automatically picks the right type.
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
129 
130 // For more portably defining hash functions.
131 typedef long Py_hash_t;
132 #endif
133 
134 #if PY_MAJOR_VERSION >= 3
135 // Python 3 versions before 3.3.3 defined this incorrectly.
136 #undef _PyErr_OCCURRED
137 #define _PyErr_OCCURRED() (PyThreadState_GET()->curexc_type)
138 
139 // Python versions before 3.3 did not define this.
140 #if PY_VERSION_HEX < 0x03030000
141 #define PyUnicode_AsUTF8 _PyUnicode_AsString
142 #define PyUnicode_AsUTF8AndSize _PyUnicode_AsStringAndSize
143 #endif
144 #endif
145 
146 using namespace std;
147 
148 ///////////////////////////////////////////////////////////////////////////////////
149 // this is tempory .. untill this is glued better into the panda build system
150 ///////////////////////////////////////////////////////////////////////////////////
151 
152 #if defined(_WIN32) && !defined(LINK_ALL_STATIC)
153 #define EXPORT_THIS __declspec(dllexport)
154 #define IMPORT_THIS extern __declspec(dllimport)
155 #else
156 #define EXPORT_THIS
157 #define IMPORT_THIS extern
158 #endif
159 ///////////////////////////////////////////////////////////////////////////////////
160 
161 struct Dtool_PyTypedObject;
162 typedef std::map<int, Dtool_PyTypedObject *> RunTimeTypeDictionary;
163 typedef std::set<int> RunTimeTypeList;
164 
165 EXPCL_DTOOLCONFIG RunTimeTypeDictionary &GetRunTimeDictionary();
166 EXPCL_DTOOLCONFIG RunTimeTypeList &GetRunTimeTypeList();
167 
168 //////////////////////////////////////////////////////////
169 // used to stamp dtool instance..
170 #define PY_PANDA_SIGNATURE 0xbeaf
171 typedef void *(*UpcastFunction)(PyObject *,Dtool_PyTypedObject *);
172 typedef void *(*DowncastFunction)(void *, Dtool_PyTypedObject *);
173 
174 //inline Dtool_PyTypedObject * Dtool_RuntimeTypeDtoolType(int type);
175 //inline void Dtool_Deallocate_General(PyObject * self);
176 //inline int DTOOL_PyObject_Compare(PyObject *v1, PyObject *v2);
177 //
178 ////////////////////////////////////////////////////////////////////////
179 // THIS IS THE INSTANCE CONTAINER FOR ALL panda py objects....
180 ////////////////////////////////////////////////////////////////////////
181 struct Dtool_PyInstDef {
182  PyObject_HEAD
183 
184  // This is a pointer to the Dtool_PyTypedObject type. It's tempting
185  // not to store this and to instead use PY_TYPE(self) and upcast that,
186  // but that breaks when someone inherits from our class in Python.
187  struct Dtool_PyTypedObject *_My_Type;
188 
189  // Pointer to the underlying C++ object.
190  void *_ptr_to_object;
191 
192  // This is always set to PY_PANDA_SIGNATURE, so that we can quickly
193  // detect whether an object is a Panda object.
194  unsigned short _signature;
195 
196  // True if we own the pointer and should delete it or unref it.
197  bool _memory_rules;
198 
199  // True if this is a "const" pointer.
200  bool _is_const;
201 };
202 
203 ////////////////////////////////////////////////////////////////////////
204 // A Offset Dictionary Defining How to read the Above Object..
205 ////////////////////////////////////////////////////////////////////////
206 extern EXPCL_DTOOLCONFIG PyMemberDef standard_type_members[];
207 
208 ////////////////////////////////////////////////////////////////////////
209 // The Class Definition Structor For a Dtool python type.
210 ////////////////////////////////////////////////////////////////////////
211 struct Dtool_PyTypedObject {
212  // Standard Python Features..
213  PyTypeObject _PyType;
214 
215  // My Class Level Features..
216  UpcastFunction _Dtool_UpcastInterface; // The Upcast Function By Slot
217  DowncastFunction _Dtool_DowncastInterface; // The Downcast Function By Slot
218 
219  // May be TypeHandle::none() to indicate a non-TypedObject class.
220  TypeHandle _type;
221 
222  // some convenience functions..
223  inline PyTypeObject &As_PyTypeObject() { return _PyType; };
224  inline PyObject &As_PyObject() { return (PyObject &)_PyType; };
225 };
226 
227 // This is now simply a forward declaration. The actual definition is created
228 // by the code generator.
229 #define Define_Dtool_Class(MODULE_NAME, CLASS_NAME, PUBLIC_NAME) \
230  extern Dtool_PyTypedObject Dtool_##CLASS_NAME;
231 
232 ////////////////////////////////////////////////////////////////////////
233 // More Macro(s) to Implement class functions.. Usually used if C++ needs type information
234 ////////////////////////////////////////////////////////////////////////
235 #define Define_Dtool_new(CLASS_NAME,CNAME)\
236 PyObject *Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds) {\
237  (void) args; (void) kwds;\
238  PyObject *self = type->tp_alloc(type, 0);\
239  ((Dtool_PyInstDef *)self)->_signature = PY_PANDA_SIGNATURE;\
240  ((Dtool_PyInstDef *)self)->_My_Type = &Dtool_##CLASS_NAME;\
241  return self;\
242 }
243 
244 // The following used to be in the above macro, but it doesn't seem to
245 // be necessary as tp_alloc memsets the object to 0.
246  //((Dtool_PyInstDef *)self)->_ptr_to_object = NULL;\
247  //((Dtool_PyInstDef *)self)->_memory_rules = false;\
248  //((Dtool_PyInstDef *)self)->_is_const = false;\
249 
250 ////////////////////////////////////////////////////////////////////////
251 /// Delete functions..
252 ////////////////////////////////////////////////////////////////////////
253 #ifdef NDEBUG
254 #define Define_Dtool_FreeInstance_Private(CLASS_NAME,CNAME)\
255 static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
256  Py_TYPE(self)->tp_free(self);\
257 }
258 #else // NDEBUG
259 #define Define_Dtool_FreeInstance_Private(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  cerr << "Detected leak for " << #CLASS_NAME \
264  << " which interrogate cannot delete.\n"; \
265  }\
266  }\
267  Py_TYPE(self)->tp_free(self);\
268 }
269 #endif // NDEBUG
270 
271 #define Define_Dtool_FreeInstance(CLASS_NAME,CNAME)\
272 static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
273  if (((Dtool_PyInstDef *)self)->_ptr_to_object != NULL) {\
274  if (((Dtool_PyInstDef *)self)->_memory_rules) {\
275  delete ((CNAME *)((Dtool_PyInstDef *)self)->_ptr_to_object);\
276  }\
277  }\
278  Py_TYPE(self)->tp_free(self);\
279 }
280 
281 #define Define_Dtool_FreeInstanceRef(CLASS_NAME,CNAME)\
282 static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
283  if (((Dtool_PyInstDef *)self)->_ptr_to_object != NULL) {\
284  if (((Dtool_PyInstDef *)self)->_memory_rules) {\
285  unref_delete((CNAME *)((Dtool_PyInstDef *)self)->_ptr_to_object);\
286  }\
287  }\
288  Py_TYPE(self)->tp_free(self);\
289 }
290 
291 #define Define_Dtool_Simple_FreeInstance(CLASS_NAME, CNAME)\
292 static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
293  ((Dtool_InstDef_##CLASS_NAME *)self)->_value.~##CLASS_NAME();\
294  Py_TYPE(self)->tp_free(self);\
295 }
296 
297 ////////////////////////////////////////////////////////////////////////
298 /// Simple Recognition Functions..
299 ////////////////////////////////////////////////////////////////////////
300 EXPCL_DTOOLCONFIG bool DtoolCanThisBeAPandaInstance(PyObject *self);
301 
302 ///////////////////////////////////////////////////////////////////////////////
303 // ** HACK ** allert..
304 //
305 // Need to keep a runtime type dictionary ... that is forward declared of typed object.
306 // We rely on the fact that typed objects are uniquly defined by an integer.
307 //
308 ///////////////////////////////////////////////////////////////////////////////
309 
310 EXPCL_DTOOLCONFIG void RegisterRuntimeClass(Dtool_PyTypedObject *otype, int class_id);
311 
312 ///////////////////////////////////////////////////////////////////////////////
313 ///////////////////////////////////////////////////////////////////////////////
314 EXPCL_DTOOLCONFIG Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type);
315 
316 ////////////////////////////////////////////////////////////////////////
317 // Function : DTOOL_Call_ExtractThisPointerForType
318 //
319 // These are the wrappers that allow for down and upcast from type ..
320 // needed by the Dtool py interface.. Be very careful if you muck
321 // with these as the generated code depends on how this is set
322 // up..
323 ////////////////////////////////////////////////////////////////////////
324 EXPCL_DTOOLCONFIG void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject * classdef, void ** answer);
325 
326 EXPCL_DTOOLCONFIG void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const string &function_name, bool const_ok, bool report_errors);
327 
328 EXPCL_DTOOLCONFIG void *DTOOL_Call_GetPointerThis(PyObject *self);
329 
330 EXPCL_DTOOLCONFIG bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer);
331 
332 EXPCL_DTOOLCONFIG bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef,
333  void **answer, const char *method_name);
334 
335 template<class T> INLINE bool DTOOL_Call_ExtractThisPointer(PyObject *self, T *&into) {
336  if (DtoolCanThisBeAPandaInstance(self)) {
337  Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
338  if (target_class != NULL) {
339  into = (T*) ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_UpcastInterface(self, target_class);
340  return (into != NULL);
341  }
342  }
343  into = NULL;
344  return false;
345 }
346 
347 // Functions related to error reporting.
348 
349 // _PyErr_OCCURRED is an undocumented macro version of PyErr_Occurred.
350 // Some implementations of the CPython API (e.g. PyPy's cpyext) do not define
351 // it, so in these cases we just silently fall back to PyErr_Occurred.
352 #ifndef _PyErr_OCCURRED
353 #define _PyErr_OCCURRED() PyErr_Occurred()
354 #endif
355 
356 #ifdef NDEBUG
357 #define Dtool_CheckErrorOccurred() (_PyErr_OCCURRED() != NULL)
358 #else
359 EXPCL_DTOOLCONFIG bool Dtool_CheckErrorOccurred();
360 #endif
361 
362 EXPCL_DTOOLCONFIG PyObject *Dtool_Raise_AssertionError();
363 EXPCL_DTOOLCONFIG PyObject *Dtool_Raise_TypeError(const char *message);
364 EXPCL_DTOOLCONFIG PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name);
365 EXPCL_DTOOLCONFIG PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute);
366 
367 EXPCL_DTOOLCONFIG PyObject *_Dtool_Raise_BadArgumentsError();
368 #ifdef NDEBUG
369 // Define it to a function that just prints a generic message.
370 #define Dtool_Raise_BadArgumentsError(x) _Dtool_Raise_BadArgumentsError()
371 #else
372 // Expand this to a TypeError listing all of the overloads.
373 #define Dtool_Raise_BadArgumentsError(x) Dtool_Raise_TypeError("Arguments must match:\n" x)
374 #endif
375 
376 EXPCL_DTOOLCONFIG PyObject *_Dtool_Return_None();
377 EXPCL_DTOOLCONFIG PyObject *Dtool_Return_Bool(bool value);
378 EXPCL_DTOOLCONFIG PyObject *_Dtool_Return(PyObject *value);
379 
380 #ifdef NDEBUG
381 #define Dtool_Return_None() (_PyErr_OCCURRED() != NULL ? NULL : (Py_INCREF(Py_None), Py_None))
382 #define Dtool_Return(value) (_PyErr_OCCURRED() != NULL ? NULL : value)
383 #else
384 #define Dtool_Return_None() _Dtool_Return_None()
385 #define Dtool_Return(value) _Dtool_Return(value)
386 #endif
387 
388 ////////////////////////////////////////////////////////////////////////
389 // Function : DTool_CreatePyInstanceTyped
390 //
391 // this function relies on the behavior of typed objects in the panda system.
392 //
393 ////////////////////////////////////////////////////////////////////////
394 EXPCL_DTOOLCONFIG PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int RunTimeType);
395 
396 ////////////////////////////////////////////////////////////////////////
397 // DTool_CreatePyInstance .. wrapper function to finalize the existance of a general
398 // dtool py instance..
399 ////////////////////////////////////////////////////////////////////////
400 EXPCL_DTOOLCONFIG PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_classdef, bool memory_rules, bool is_const);
401 
402 // These template methods allow use when the Dtool_PyTypedObject is not known.
403 // They require a get_class_type() to be defined for the class.
404 template<class T> INLINE PyObject *DTool_CreatePyInstance(const 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_CreatePyInstance((void*) obj, *known_class, memory_rules, true);
408 }
409 
410 template<class T> INLINE PyObject *DTool_CreatePyInstance(T *obj, bool memory_rules) {
411  Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
412  nassertr(known_class != NULL, NULL);
413  return DTool_CreatePyInstance((void*) obj, *known_class, memory_rules, false);
414 }
415 
416 template<class T> INLINE PyObject *DTool_CreatePyInstanceTyped(const T *obj, bool memory_rules) {
417  Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
418  nassertr(known_class != NULL, NULL);
419  return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, true, obj->get_type().get_index());
420 }
421 
422 template<class T> INLINE PyObject *DTool_CreatePyInstanceTyped(T *obj, bool memory_rules) {
423  Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
424  nassertr(known_class != NULL, NULL);
425  return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, false, obj->get_type().get_index());
426 }
427 
428 ///////////////////////////////////////////////////////////////////////////////
429 // Macro(s) class definition .. Used to allocate storage and
430 // init some values for a Dtool Py Type object.
431 /////////////////////////////////////////////////////////////////////////////////
432 ///////////////////////////////////////////////////////////////////////////////
433 //struct Dtool_PyTypedObject Dtool_##CLASS_NAME;
434 
435 #define Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\
436 extern EXPORT_THIS Dtool_PyTypedObject Dtool_##CLASS_NAME;\
437 int Dtool_Init_##CLASS_NAME(PyObject *self, PyObject *args, PyObject *kwds);\
438 PyObject * Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds);\
439 void * Dtool_UpcastInterface_##CLASS_NAME(PyObject *self, Dtool_PyTypedObject *requested_type);\
440 void * Dtool_DowncastInterface_##CLASS_NAME(void *self, Dtool_PyTypedObject *requested_type);
441 
442 ///////////////////////////////////////////////////////////////////////////////
443 #define Define_Module_Class(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\
444 Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\
445 Define_Dtool_new(CLASS_NAME,CNAME)\
446 Define_Dtool_FreeInstance(CLASS_NAME,CNAME)\
447 Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME)
448 
449 ///////////////////////////////////////////////////////////////////////////////
450 #define Define_Module_Class_Private(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\
451 Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\
452 Define_Dtool_new(CLASS_NAME,CNAME)\
453 Define_Dtool_FreeInstance_Private(CLASS_NAME,CNAME)\
454 Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME)
455 
456 ///////////////////////////////////////////////////////////////////////////////
457 #define Define_Module_ClassRef_Private(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\
458 Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\
459 Define_Dtool_new(CLASS_NAME,CNAME)\
460 Define_Dtool_FreeInstance_Private(CLASS_NAME,CNAME)\
461 Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME)
462 
463 ///////////////////////////////////////////////////////////////////////////////
464 #define Define_Module_ClassRef(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\
465 Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\
466 Define_Dtool_new(CLASS_NAME,CNAME)\
467 Define_Dtool_FreeInstanceRef(CLASS_NAME,CNAME)\
468 Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME)
469 
470 ///////////////////////////////////////////////////////////////////////////////
471 /// Th Finalizer for simple instances..
472 ///////////////////////////////////////////////////////////////////////////////
473 EXPCL_DTOOLCONFIG int DTool_PyInit_Finalize(PyObject *self, void *This, Dtool_PyTypedObject *type, bool memory_rules, bool is_const);
474 
475 ///////////////////////////////////////////////////////////////////////////////
476 /// A heler function to glu methed definition together .. that can not be done at
477 // code generation time becouse of multiple generation passes in interigate..
478 //
479 ///////////////////////////////////////////////////////////////////////////////
480 typedef std::map<std::string, PyMethodDef *> MethodDefmap;
481 
482 EXPCL_DTOOLCONFIG void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap);
483 
484 ///////////////////////////////////////////////////////////////////////////////
485 //// We need a way to runtime merge compile units into a python "Module" .. this is done with the
486 /// fallowing structors and code.. along with the support of interigate_module
487 ///////////////////////////////////////////////////////////////////////////////
488 struct LibraryDef {
489  typedef void (*ConstantFunction)(PyObject *);
490 
491  PyMethodDef *_methods;
492  ConstantFunction _constants;
493 };
494 ///////////////////////////////////////////////////////////////////////////////
495 
496 #if PY_MAJOR_VERSION >= 3
497 EXPCL_DTOOLCONFIG PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], PyModuleDef *module_def);
498 #else
499 EXPCL_DTOOLCONFIG PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename);
500 #endif
501 
502 ///////////////////////////////////////////////////////////////////////////////
503 /// HACK.... Be carefull
504 //
505 // Dtool_BorrowThisReference
506 // This function can be used to grab the "THIS" pointer from an object and use it
507 // Required to support fom historical inharatence in the for of "is this instance of"..
508 //
509 ///////////////////////////////////////////////////////////////////////////////
510 EXPCL_DTOOLCONFIG PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args);
511 
512 //////////////////////////////////////////////////////////////////////////////////////////////
513 // We do expose a dictionay for dtool classes .. this should be removed at some point..
514 //////////////////////////////////////////////////////////////////////////////////////////////
515 EXPCL_DTOOLCONFIG PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args);
516 
517 ///////////////////////////////////////////////////////////////////////////////////
518 
519 EXPCL_DTOOLCONFIG Py_hash_t DTOOL_PyObject_HashPointer(PyObject *obj);
520 
521 /* Compare v to w. Return
522  -1 if v < w or exception (PyErr_Occurred() true in latter case).
523  0 if v == w.
524  1 if v > w.
525  XXX The docs (C API manual) say the return value is undefined in case
526  XXX of error.
527 */
528 
529 EXPCL_DTOOLCONFIG int DTOOL_PyObject_ComparePointers(PyObject *v1, PyObject *v2);
530 EXPCL_DTOOLCONFIG int DTOOL_PyObject_Compare(PyObject *v1, PyObject *v2);
531 
532 EXPCL_DTOOLCONFIG PyObject *DTOOL_PyObject_RichCompare(PyObject *v1, PyObject *v2, int op);
533 
534 EXPCL_DTOOLCONFIG PyObject *
535 make_list_for_item(PyObject *self, const char *num_name,
536  const char *element_name);
537 
538 EXPCL_DTOOLCONFIG PyObject *
539 copy_from_make_copy(PyObject *self);
540 
541 EXPCL_DTOOLCONFIG PyObject *
542 copy_from_copy_constructor(PyObject *self);
543 
544 EXPCL_DTOOLCONFIG PyObject *
545 map_deepcopy_to_copy(PyObject *self, PyObject *args);
546 
547 #if PY_MAJOR_VERSION < 3
548 // In the Python 3 case, it is defined as a macro, at the beginning of this file.
549 EXPCL_DTOOLCONFIG PyObject *
550 PyLongOrInt_FromUnsignedLong(unsigned long value);
551 #endif
552 
553 EXPCL_DTOOLCONFIG extern struct Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE;
554 EXPCL_DTOOLCONFIG extern void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module);
555 
556 #endif // HAVE_PYTHON && !CPPPARSER
557 
558 #endif // PY_PANDA_H_
STL namespace.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85