Panda3D
|
00001 #ifndef PY_PANDA_H_ 00002 #define PY_PANDA_H_ 00003 // Filename: py_panda.h 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 ////////////////////////////////////////////////////////////////////////////////////////////// 00015 // Too do list .. 00016 // We need a better dispatcher for the functions.. The behavior today is 00017 // try one till it works or you run out of possibilities.. This is anything but optimal 00018 // for performance and is treading on thin ice for function python or c++ will 00019 // course there types to other types. 00020 // 00021 // The linking step will produce allot of warnings 00022 // warning LNK4049: locally defined symbol.. 00023 // 00024 // Get a second coder to review this file and the generated code .. 00025 // 00026 ////////////////////////////////////////////////////////////////////////////////////////////// 00027 #include <set> 00028 #include <map> 00029 #include <string> 00030 00031 #ifdef USE_DEBUG_PYTHON 00032 #define Py_DEBUG 00033 #endif 00034 00035 #ifndef NO_RUNTIME_TYPES 00036 00037 #include "dtoolbase.h" 00038 #include "typedObject.h" 00039 #include "typeRegistry.h" 00040 00041 #endif 00042 00043 #if defined(HAVE_PYTHON) && !defined(CPPPARSER) 00044 00045 #ifdef HAVE_LONG_LONG 00046 #undef HAVE_LONG_LONG 00047 #endif 00048 #ifdef _POSIX_C_SOURCE 00049 #undef _POSIX_C_SOURCE 00050 #endif 00051 00052 #include "Python.h" 00053 #include "structmember.h" 00054 #ifdef HAVE_LONG_LONG 00055 #undef HAVE_LONG_LONG 00056 #endif 00057 00058 #if PY_VERSION_HEX < 0x02050000 00059 00060 // Prior to Python 2.5, we didn't have Py_ssize_t. 00061 typedef int Py_ssize_t; 00062 #define PyInt_FromSsize_t PyInt_FromLong 00063 #define PyInt_AsSsize_t PyInt_AsLong 00064 00065 #endif // PY_VERSION_HEX 00066 00067 // 2.4 macros which aren't available in 2.3 00068 #ifndef Py_RETURN_NONE 00069 inline PyObject* doPy_RETURN_NONE() 00070 { Py_INCREF(Py_None); return Py_None; } 00071 #define Py_RETURN_NONE return doPy_RETURN_NONE() 00072 #endif 00073 00074 #ifndef Py_RETURN_TRUE 00075 inline PyObject* doPy_RETURN_TRUE() 00076 {Py_INCREF(Py_True); return Py_True;} 00077 #define Py_RETURN_TRUE return doPy_RETURN_TRUE() 00078 #endif 00079 00080 #ifndef Py_RETURN_FALSE 00081 inline PyObject* doPy_RETURN_FALSE() 00082 {Py_INCREF(Py_False); return Py_False;} 00083 #define Py_RETURN_FALSE return doPy_RETURN_FALSE() 00084 #endif 00085 00086 using namespace std; 00087 00088 #define PY_PANDA_SMALLER_FOOTPRINT 1 00089 00090 /////////////////////////////////////////////////////////////////////////////////// 00091 // this is tempory .. untill this is glued better into the panda build system 00092 /////////////////////////////////////////////////////////////////////////////////// 00093 00094 #if defined(_WIN32) && !defined(LINK_ALL_STATIC) 00095 #define EXPORT_THIS __declspec(dllexport) 00096 #define IMPORT_THIS extern __declspec(dllimport) 00097 #else 00098 #define EXPORT_THIS 00099 #define IMPORT_THIS extern 00100 #endif 00101 /////////////////////////////////////////////////////////////////////////////////// 00102 00103 struct Dtool_PyTypedObject; 00104 typedef std::map< int , Dtool_PyTypedObject *> RunTimeTypeDictionary; 00105 typedef std::set<int > RunTimeTypeList; 00106 00107 EXPCL_DTOOLCONFIG RunTimeTypeDictionary & GetRunTimeDictionary(); 00108 EXPCL_DTOOLCONFIG RunTimeTypeList & GetRunTimeTypeList(); 00109 00110 00111 ////////////////////////////////////////////////////////// 00112 // used to stamp dtool instance.. 00113 #define PY_PANDA_SIGNATURE 0xbeaf 00114 typedef void * ( * ConvertFunctionType )(PyObject *,Dtool_PyTypedObject * ); 00115 typedef void * ( * ConvertFunctionType1 )(void *, Dtool_PyTypedObject *); 00116 typedef void ( *FreeFunction )(PyObject *); 00117 typedef void ( *PyModuleClassInit)(PyObject *module); 00118 //inline Dtool_PyTypedObject * Dtool_RuntimeTypeDtoolType(int type); 00119 inline void Dtool_Deallocate_General(PyObject * self); 00120 //inline int DTOOL_PyObject_Compare(PyObject *v1, PyObject *v2); 00121 // 00122 //////////////////////////////////////////////////////////////////////// 00123 // THIS IS THE INSTANCE CONTAINER FOR ALL panda py objects.... 00124 //////////////////////////////////////////////////////////////////////// 00125 #ifdef PY_PANDA_SMALLER_FOOTPRINT 00126 // this should save 8 bytes per object .... 00127 struct Dtool_PyInstDef 00128 { 00129 PyObject_HEAD 00130 void *_ptr_to_object; 00131 struct Dtool_PyTypedObject *_My_Type; 00132 unsigned short _signature ; 00133 int _memory_rules : 1; // true if we own the pointer and should delete it or unref it 00134 int _is_const : 1; // true if this is a "const" pointer. 00135 }; 00136 00137 00138 00139 #else 00140 struct Dtool_PyInstDef { 00141 PyObject_HEAD 00142 void *_ptr_to_object; 00143 int _memory_rules; // true if we own the pointer and should delete it or unref it 00144 int _is_const; // true if this is a "const" pointer. 00145 unsigned long _signature; 00146 struct Dtool_PyTypedObject *_My_Type; 00147 }; 00148 #endif 00149 00150 //////////////////////////////////////////////////////////////////////// 00151 // A Offset Dictionary Defining How to read the Above Object.. 00152 //////////////////////////////////////////////////////////////////////// 00153 extern EXPCL_DTOOLCONFIG PyMemberDef standard_type_members[]; 00154 00155 //////////////////////////////////////////////////////////////////////// 00156 // The Class Definition Structor For a Dtool python type. 00157 //////////////////////////////////////////////////////////////////////// 00158 struct Dtool_PyTypedObject { 00159 // Standard Python Features.. 00160 PyTypeObject _PyType; 00161 00162 // My Class Level Features.. 00163 const char *_name; // cpp name for the object 00164 bool _Dtool_IsRunTimeCapable; // derived from TypedObject 00165 ConvertFunctionType _Dtool_UpcastInterface; // The Upcast Function By Slot 00166 ConvertFunctionType1 _Dtool_DowncastInterface; // The Downcast Function By Slot 00167 FreeFunction _Dtool_FreeInstance; 00168 PyModuleClassInit _Dtool_ClassInit; // The init function pointer 00169 00170 // some convenience functions.. 00171 inline PyTypeObject &As_PyTypeObject() { return _PyType; }; 00172 inline PyObject &As_PyObject() { return (PyObject &)_PyType; }; 00173 }; 00174 00175 00176 //////////////////////////////////////////////////////////////////////// 00177 // Macros from Hell.. May want to just add this to the code generator.. 00178 //////////////////////////////////////////////////////////////////////// 00179 #define Define_Dtool_Class(MODULE_NAME, CLASS_NAME, PUBLIC_NAME) \ 00180 static PyNumberMethods Dtool_PyNumberMethods_##CLASS_NAME = \ 00181 { \ 00182 0,/*binaryfunc nb_add*/ \ 00183 0,/*binaryfunc nb_subtract*/ \ 00184 0,/*binaryfunc nb_multiply*/ \ 00185 0,/*binaryfunc nb_divide*/ \ 00186 0,/*binaryfunc nb_remainder*/ \ 00187 0,/*binaryfunc nb_divmod*/ \ 00188 0,/*ternaryfunc nb_power*/ \ 00189 0,/*unaryfunc nb_negative*/ \ 00190 0,/*unaryfunc nb_positive*/ \ 00191 0,/*unaryfunc nb_absolute*/ \ 00192 0,/*inquiry nb_nonzero*/ \ 00193 0,/*unaryfunc nb_invert*/ \ 00194 0,/*binaryfunc nb_lshift*/ \ 00195 0,/*binaryfunc nb_rshift*/ \ 00196 0,/*binaryfunc nb_and*/ \ 00197 0,/*binaryfunc nb_xor*/ \ 00198 0,/*binaryfunc nb_or*/ \ 00199 0,/*coercion nb_coerce*/ \ 00200 0,/*unaryfunc nb_int*/ \ 00201 0,/*unaryfunc nb_long*/ \ 00202 0,/*unaryfunc nb_float*/ \ 00203 0,/*unaryfunc nb_oct*/ \ 00204 0,/*unaryfunc nb_hex*/ \ 00205 0,/*binaryfunc nb_inplace_add*/ \ 00206 0,/*binaryfunc nb_inplace_subtract*/ \ 00207 0,/*binaryfunc nb_inplace_multiply*/ \ 00208 0,/*binaryfunc nb_inplace_divide*/ \ 00209 0,/*binaryfunc nb_inplace_remainder*/ \ 00210 0,/*ternaryfunc nb_inplace_power*/ \ 00211 0,/*binaryfunc nb_inplace_lshift*/ \ 00212 0,/*binaryfunc nb_inplace_rshift*/ \ 00213 0,/*binaryfunc nb_inplace_and*/ \ 00214 0,/*binaryfunc nb_inplace_xor*/ \ 00215 0,/*binaryfunc nb_inplace_or*/ \ 00216 0,/*binaryfunc nb_floor_divide*/ \ 00217 0,/*binaryfunc nb_true_divide*/ \ 00218 0,/*binaryfunc nb_inplace_floor_divide*/ \ 00219 0,/*binaryfunc nb_inplace_true_divide*/ \ 00220 }; \ 00221 static PySequenceMethods Dtool_PySequenceMethods_##CLASS_NAME = \ 00222 { \ 00223 0,/*lenfunc sq_length */ \ 00224 0,/*binaryfunc sq_concat */ \ 00225 0,/*ssizeargfunc sq_repeat */ \ 00226 0,/*ssizeargfunc sq_item */ \ 00227 0,/*ssizeargfunc sq_ass_item */ \ 00228 0,/*objobjproc sq_contains */ \ 00229 0,/*binaryfunc sq_inplace_concat */ \ 00230 0,/*ssizeargfunc sq_inplace_repeat */ \ 00231 }; \ 00232 static PyMappingMethods Dtool_PyMappingMethods_##CLASS_NAME = \ 00233 { \ 00234 0,/*inquiry mp_length */ \ 00235 0,/*binaryfunc mp_subscript */ \ 00236 0,/*objobjargproc mp_ass_subscript */ \ 00237 }; \ 00238 EXPORT_THIS Dtool_PyTypedObject Dtool_##CLASS_NAME = \ 00239 { \ 00240 { \ 00241 PyObject_HEAD_INIT(NULL) \ 00242 0, \ 00243 "lib" #MODULE_NAME "." #PUBLIC_NAME, /*type name with module */ \ 00244 sizeof(Dtool_PyInstDef), /* tp_basicsize */ \ 00245 0, /* tp_itemsize */ \ 00246 &Dtool_Deallocate_General, /* tp_dealloc */ \ 00247 0, /* tp_print */ \ 00248 0, /* tp_getattr */ \ 00249 0, /* tp_setattr */ \ 00250 0, /* tp_compare */ \ 00251 0, /* tp_repr */ \ 00252 &Dtool_PyNumberMethods_##CLASS_NAME, /* tp_as_number */ \ 00253 &Dtool_PySequenceMethods_##CLASS_NAME, /* tp_as_sequence */ \ 00254 &Dtool_PyMappingMethods_##CLASS_NAME, /* tp_as_mapping */ \ 00255 0, /* tp_hash */ \ 00256 0, /* tp_call */ \ 00257 0, /* tp_str */ \ 00258 PyObject_GenericGetAttr, /* tp_getattro */ \ 00259 PyObject_GenericSetAttr, /* tp_setattro */ \ 00260 0, /* tp_as_buffer */ \ 00261 (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES), /* tp_flags */ \ 00262 0, /* tp_doc */ \ 00263 0, /* tp_traverse */ \ 00264 0, /* tp_clear */ \ 00265 0, /* tp_richcompare */ \ 00266 0, /* tp_weaklistoffset */ \ 00267 0, /* tp_iter */ \ 00268 0, /* tp_iternext */ \ 00269 Dtool_Methods_##CLASS_NAME, /* tp_methods */ \ 00270 standard_type_members, /* tp_members */ \ 00271 0, /* tp_getset */ \ 00272 0, /* tp_base */ \ 00273 0, /* tp_dict */ \ 00274 0, /* tp_descr_get */ \ 00275 0, /* tp_descr_set */ \ 00276 0, /* tp_dictoffset */ \ 00277 Dtool_Init_##CLASS_NAME, /* tp_init */ \ 00278 PyType_GenericAlloc, /* tp_alloc */ \ 00279 Dtool_new_##CLASS_NAME, /* tp_new */ \ 00280 _PyObject_Del, /* tp_free */ \ 00281 }, \ 00282 #CLASS_NAME, \ 00283 false, \ 00284 Dtool_UpcastInterface_##CLASS_NAME, \ 00285 Dtool_DowncastInterface_##CLASS_NAME, \ 00286 Dtool_FreeInstance_##CLASS_NAME, \ 00287 Dtool_PyModuleClassInit_##CLASS_NAME \ 00288 }; 00289 00290 00291 //////////////////////////////////////////////////////////////////////// 00292 // The Fast Deallocator.. for Our instances.. 00293 //////////////////////////////////////////////////////////////////////// 00294 inline void Dtool_Deallocate_General(PyObject * self) { 00295 ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_FreeInstance(self); 00296 self->ob_type->tp_free(self); 00297 } 00298 00299 //////////////////////////////////////////////////////////////////////// 00300 // More Macro(s) to Implement class functions.. Usually used if C++ needs type information 00301 //////////////////////////////////////////////////////////////////////// 00302 #define Define_Dtool_new(CLASS_NAME,CNAME)\ 00303 PyObject *Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds)\ 00304 {\ 00305 PyObject *self = type->tp_alloc(type, 0);\ 00306 ((Dtool_PyInstDef *)self)->_signature = PY_PANDA_SIGNATURE;\ 00307 ((Dtool_PyInstDef *)self)->_ptr_to_object = NULL;\ 00308 ((Dtool_PyInstDef *)self)->_memory_rules = false;\ 00309 ((Dtool_PyInstDef *)self)->_is_const = false;\ 00310 ((Dtool_PyInstDef *)self)->_My_Type = &Dtool_##CLASS_NAME;\ 00311 return self;\ 00312 } 00313 00314 //////////////////////////////////////////////////////////////////////// 00315 /// Delete functions.. 00316 //////////////////////////////////////////////////////////////////////// 00317 #ifdef NDEBUG 00318 #define Define_Dtool_FreeInstance_Private(CLASS_NAME,CNAME)\ 00319 static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self)\ 00320 {\ 00321 } 00322 #else // NDEBUG 00323 #define Define_Dtool_FreeInstance_Private(CLASS_NAME,CNAME)\ 00324 static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self)\ 00325 {\ 00326 if(((Dtool_PyInstDef *)self)->_ptr_to_object != NULL)\ 00327 if(((Dtool_PyInstDef *)self)->_memory_rules)\ 00328 {\ 00329 cerr << "Detected leak for " << #CLASS_NAME \ 00330 << " which interrogate cannot delete.\n"; \ 00331 }\ 00332 } 00333 #endif // NDEBUG 00334 00335 #define Define_Dtool_FreeInstance(CLASS_NAME,CNAME)\ 00336 static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self)\ 00337 {\ 00338 if(((Dtool_PyInstDef *)self)->_ptr_to_object != NULL)\ 00339 if(((Dtool_PyInstDef *)self)->_memory_rules)\ 00340 {\ 00341 delete ((CNAME *)((Dtool_PyInstDef *)self)->_ptr_to_object);\ 00342 }\ 00343 } 00344 00345 #define Define_Dtool_FreeInstanceRef(CLASS_NAME,CNAME)\ 00346 static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self)\ 00347 {\ 00348 if(((Dtool_PyInstDef *)self)->_ptr_to_object != NULL)\ 00349 if(((Dtool_PyInstDef *)self)->_memory_rules)\ 00350 {\ 00351 unref_delete((CNAME *)((Dtool_PyInstDef *)self)->_ptr_to_object);\ 00352 }\ 00353 } 00354 00355 //////////////////////////////////////////////////////////////////////// 00356 /// Simple Recognition Functions.. 00357 //////////////////////////////////////////////////////////////////////// 00358 EXPCL_DTOOLCONFIG bool DtoolCanThisBeAPandaInstance(PyObject *self); 00359 00360 //////////////////////////////////////////////////////////////////////// 00361 // Function : DTOOL_Call_ExtractThisPointerForType 00362 // 00363 // These are the wrappers that allow for down and upcast from type .. 00364 // needed by the Dtool py interface.. Be very careful if you muck 00365 // with these as the generated code depends on how this is set 00366 // up.. 00367 //////////////////////////////////////////////////////////////////////// 00368 EXPCL_DTOOLCONFIG void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject * classdef, void ** answer); 00369 00370 00371 EXPCL_DTOOLCONFIG void * DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const string &function_name, bool const_ok, PyObject **coerced, bool report_errors); 00372 00373 EXPCL_DTOOLCONFIG void * DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const string &function_name, bool const_ok, PyObject **coerced); 00374 00375 EXPCL_DTOOLCONFIG void * DTOOL_Call_GetPointerThis(PyObject *self); 00376 00377 //////////////////////////////////////////////////////////////////////// 00378 // Function : DTool_CreatePyInstanceTyped 00379 // 00380 // this function relies on the behavior of typed objects in the panda system. 00381 // 00382 //////////////////////////////////////////////////////////////////////// 00383 EXPCL_DTOOLCONFIG PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int RunTimeType); 00384 00385 //////////////////////////////////////////////////////////////////////// 00386 // DTool_CreatePyInstance .. wrapper function to finalize the existance of a general 00387 // dtool py instance.. 00388 //////////////////////////////////////////////////////////////////////// 00389 EXPCL_DTOOLCONFIG PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_classdef, bool memory_rules, bool is_const); 00390 00391 /////////////////////////////////////////////////////////////////////////////// 00392 // Macro(s) class definition .. Used to allocate storage and 00393 // init some values for a Dtool Py Type object. 00394 ///////////////////////////////////////////////////////////////////////////////// 00395 /////////////////////////////////////////////////////////////////////////////// 00396 //struct Dtool_PyTypedObject Dtool_##CLASS_NAME; 00397 00398 #define Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\ 00399 extern EXPORT_THIS Dtool_PyTypedObject Dtool_##CLASS_NAME; \ 00400 extern struct PyMethodDef Dtool_Methods_##CLASS_NAME[];\ 00401 int Dtool_Init_##CLASS_NAME(PyObject *self, PyObject *args, PyObject *kwds);\ 00402 PyObject * Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds);\ 00403 void * Dtool_UpcastInterface_##CLASS_NAME(PyObject *self, Dtool_PyTypedObject *requested_type);\ 00404 void * Dtool_DowncastInterface_##CLASS_NAME(void *self, Dtool_PyTypedObject *requested_type);\ 00405 void Dtool_PyModuleClassInit_##CLASS_NAME(PyObject *module); 00406 00407 /////////////////////////////////////////////////////////////////////////////// 00408 #define Define_Module_Class(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\ 00409 Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\ 00410 Define_Dtool_new(CLASS_NAME,CNAME)\ 00411 Define_Dtool_FreeInstance(CLASS_NAME,CNAME)\ 00412 Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME) 00413 00414 /////////////////////////////////////////////////////////////////////////////// 00415 #define Define_Module_Class_Private(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\ 00416 Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\ 00417 Define_Dtool_new(CLASS_NAME,CNAME)\ 00418 Define_Dtool_FreeInstance_Private(CLASS_NAME,CNAME)\ 00419 Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME) 00420 00421 /////////////////////////////////////////////////////////////////////////////// 00422 #define Define_Module_ClassRef_Private(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\ 00423 Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\ 00424 Define_Dtool_new(CLASS_NAME,CNAME)\ 00425 Define_Dtool_FreeInstance_Private(CLASS_NAME,CNAME)\ 00426 Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME) 00427 00428 /////////////////////////////////////////////////////////////////////////////// 00429 #define Define_Module_ClassRef(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\ 00430 Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\ 00431 Define_Dtool_new(CLASS_NAME,CNAME)\ 00432 Define_Dtool_FreeInstanceRef(CLASS_NAME,CNAME)\ 00433 Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME) 00434 00435 00436 /////////////////////////////////////////////////////////////////////////////// 00437 /// Th Finalizer for simple instances.. 00438 /////////////////////////////////////////////////////////////////////////////// 00439 EXPCL_DTOOLCONFIG int DTool_PyInit_Finalize(PyObject *self, void *This, Dtool_PyTypedObject *type, bool memory_rules, bool is_const); 00440 00441 /////////////////////////////////////////////////////////////////////////////// 00442 /// A heler function to glu methed definition together .. that can not be done at 00443 // code generation time becouse of multiple generation passes in interigate.. 00444 // 00445 /////////////////////////////////////////////////////////////////////////////// 00446 typedef std::map<std::string, PyMethodDef * > MethodDefmap; 00447 00448 EXPCL_DTOOLCONFIG void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap); 00449 00450 /////////////////////////////////////////////////////////////////////////////// 00451 // ** HACK ** allert.. 00452 // 00453 // Need to keep a runtime type dictionary ... that is forward declared of typed object. 00454 // We rely on the fact that typed objects are uniquly defined by an integer. 00455 // 00456 /////////////////////////////////////////////////////////////////////////////// 00457 00458 EXPCL_DTOOLCONFIG void RegisterRuntimeClass(Dtool_PyTypedObject * otype, int class_id); 00459 00460 /////////////////////////////////////////////////////////////////////////////// 00461 /////////////////////////////////////////////////////////////////////////////// 00462 EXPCL_DTOOLCONFIG Dtool_PyTypedObject * Dtool_RuntimeTypeDtoolType(int type); 00463 00464 /////////////////////////////////////////////////////////////////////////////// 00465 //// We need a way to runtime merge compile units into a python "Module" .. this is done with the 00466 /// fallowing structors and code.. along with the support of interigate_module 00467 /////////////////////////////////////////////////////////////////////////////// 00468 struct LibrayDef 00469 { 00470 typedef void ( *ConstantFunction )(PyObject *); 00471 00472 PyMethodDef * _methods; 00473 ConstantFunction _constants; 00474 }; 00475 /////////////////////////////////////////////////////////////////////////////// 00476 00477 EXPCL_DTOOLCONFIG void Dtool_PyModuleInitHelper( LibrayDef *defs[], const char * modulename); 00478 00479 /////////////////////////////////////////////////////////////////////////////// 00480 /// HACK.... Be carefull 00481 // 00482 // Dtool_BorrowThisReference 00483 // This function can be used to grab the "THIS" pointer from an object and use it 00484 // Required to support fom historical inharatence in the for of "is this instance of".. 00485 // 00486 /////////////////////////////////////////////////////////////////////////////// 00487 EXPCL_DTOOLCONFIG PyObject * Dtool_BorrowThisReference(PyObject * self, PyObject * args ); 00488 00489 ////////////////////////////////////////////////////////////////////////////////////////////// 00490 // We do expose a dictionay for dtool classes .. this should be removed at some point.. 00491 ////////////////////////////////////////////////////////////////////////////////////////////// 00492 EXPCL_DTOOLCONFIG PyObject * Dtool_AddToDictionary(PyObject * self1, PyObject * args ); 00493 00494 /////////////////////////////////////////////////////////////////////////////////// 00495 /* 00496 EXPCL_DTOOLCONFIG long DTool_HashKey(PyObject * inst) 00497 { 00498 long outcome = (long)inst; 00499 PyObject * func = PyObject_GetAttrString(inst, "__hash__"); 00500 if (func == NULL) 00501 { 00502 if(DtoolCanThisBeAPandaInstance(inst)) 00503 if(((Dtool_PyInstDef *)inst)->_ptr_to_object != NULL) 00504 outcome = (long)((Dtool_PyInstDef *)inst)->_ptr_to_object; 00505 } 00506 else 00507 { 00508 PyObject *res = PyEval_CallObject(func, (PyObject *)NULL); 00509 Py_DECREF(func); 00510 if (res == NULL) 00511 return -1; 00512 if (PyInt_Check(res)) 00513 { 00514 outcome = PyInt_AsLong(res); 00515 if (outcome == -1) 00516 outcome = -2; 00517 } 00518 else 00519 { 00520 PyErr_SetString(PyExc_TypeError, 00521 "__hash__() should return an int"); 00522 outcome = -1; 00523 } 00524 Py_DECREF(res); 00525 } 00526 return outcome; 00527 } 00528 */ 00529 00530 /* Compare v to w. Return 00531 -1 if v < w or exception (PyErr_Occurred() true in latter case). 00532 0 if v == w. 00533 1 if v > w. 00534 XXX The docs (C API manual) say the return value is undefined in case 00535 XXX of error. 00536 */ 00537 00538 EXPCL_DTOOLCONFIG int DTOOL_PyObject_Compare_old(PyObject *v1, PyObject *v2); 00539 00540 EXPCL_DTOOLCONFIG int DTOOL_PyObject_Compare(PyObject *v1, PyObject *v2); 00541 00542 EXPCL_DTOOLCONFIG PyObject * 00543 make_list_for_item(PyObject *self, const char *num_name, 00544 const char *element_name); 00545 00546 EXPCL_DTOOLCONFIG PyObject * 00547 copy_from_make_copy(PyObject *self); 00548 00549 EXPCL_DTOOLCONFIG PyObject * 00550 copy_from_copy_constructor(PyObject *self); 00551 00552 EXPCL_DTOOLCONFIG PyObject * 00553 map_deepcopy_to_copy(PyObject *self, PyObject *args); 00554 00555 EXPCL_DTOOLCONFIG PyObject * 00556 PyLongOrInt_FromUnsignedLong(unsigned long value); 00557 00558 EXPCL_DTOOLCONFIG extern struct Dtool_PyTypedObject Dtool_DTOOL_SUPPER_BASE; 00559 00560 #endif // HAVE_PYTHON && !CPPPARSER 00561 00562 00563 #endif // PY_PANDA_H_ 00564