00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "py_panda.h"
00016 #include "config_interrogatedb.h"
00017
00018 #ifdef HAVE_PYTHON
00019
00020 PyMemberDef standard_type_members[] = {
00021 {(char *)"this", T_INT, offsetof(Dtool_PyInstDef,_ptr_to_object),READONLY, (char *)"C++ This if any"},
00022
00023
00024
00025 {(char *)"this_metatype", T_OBJECT, offsetof(Dtool_PyInstDef, _My_Type), READONLY, (char *)"The dtool meta object"},
00026 {NULL}
00027 };
00028
00029
00030
00031
00032
00033 bool DtoolCanThisBeAPandaInstance(PyObject *self)
00034 {
00035
00036 if(self->ob_type->tp_basicsize >= (int)sizeof(Dtool_PyInstDef))
00037 {
00038 Dtool_PyInstDef * pyself = (Dtool_PyInstDef *) self;
00039 if(pyself->_signature == PY_PANDA_SIGNATURE)
00040 return true;
00041 }
00042 return false;
00043 }
00044
00045
00046
00047
00048
00049
00050
00051 void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject * classdef, void ** answer)
00052 {
00053 if(DtoolCanThisBeAPandaInstance(self))
00054 *answer = ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_UpcastInterface(self,classdef);
00055 else
00056 answer = NULL;
00057 };
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 static void *
00069 attempt_coercion(PyObject *self, Dtool_PyTypedObject *classdef,
00070 PyObject **coerced) {
00071
00072 if (coerced != NULL) {
00073
00074
00075 PyObject *obj = PyObject_Call((PyObject *)classdef, self, NULL);
00076 if (obj == NULL) {
00077
00078 PyObject *make = PyObject_GetAttrString((PyObject *)classdef, "make");
00079 if (make != NULL) {
00080 PyErr_Clear();
00081 obj = PyObject_Call(make, self, NULL);
00082 Py_DECREF(make);
00083 }
00084 }
00085 if (obj != NULL) {
00086
00087
00088
00089 Dtool_PyTypedObject *my_type = ((Dtool_PyInstDef *)obj)->_My_Type;
00090 void *result = my_type->_Dtool_UpcastInterface(obj, classdef);
00091 if (result != NULL) {
00092
00093
00094
00095
00096 if ((*coerced) == NULL) {
00097 (*coerced) = PyList_New(0);
00098 }
00099 PyList_Append(*coerced, obj);
00100 Py_DECREF(obj);
00101 return result;
00102 }
00103
00104
00105 Py_DECREF(obj);
00106 }
00107
00108
00109
00110 PyErr_Clear();
00111 }
00112 return NULL;
00113 }
00114
00115
00116 void *
00117 DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef,
00118 int param, const string &function_name, bool const_ok,
00119 PyObject **coerced) {
00120 return DTOOL_Call_GetPointerThisClass(self, classdef,
00121 param, function_name, const_ok,
00122 coerced, true);
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 void *
00165 DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef,
00166 int param, const string &function_name, bool const_ok,
00167 PyObject **coerced, bool report_errors) {
00168 if (PyErr_Occurred()) {
00169 return NULL;
00170 }
00171 if (self != NULL) {
00172 if (DtoolCanThisBeAPandaInstance(self)) {
00173 Dtool_PyTypedObject *my_type = ((Dtool_PyInstDef *)self)->_My_Type;
00174 void *result = my_type->_Dtool_UpcastInterface(self, classdef);
00175 if (result != NULL) {
00176 if (const_ok || !((Dtool_PyInstDef *)self)->_is_const) {
00177 return result;
00178 }
00179
00180 if (report_errors) {
00181 ostringstream str;
00182 str << function_name << "() argument " << param << " may not be const";
00183 string msg = str.str();
00184 PyErr_SetString(PyExc_TypeError, msg.c_str());
00185 }
00186
00187 } else {
00188 if (report_errors) {
00189 ostringstream str;
00190 str << function_name << "() argument " << param << " must be ";
00191
00192
00193 PyObject *fname = PyObject_GetAttrString((PyObject *)classdef, "__name__");
00194 if (fname != (PyObject *)NULL) {
00195 str << PyString_AsString(fname);
00196 Py_DECREF(fname);
00197 } else {
00198 str << classdef->_name;
00199 }
00200
00201 PyObject *tname = PyObject_GetAttrString((PyObject *)self->ob_type, "__name__");
00202 if (tname != (PyObject *)NULL) {
00203 str << ", not " << PyString_AsString(tname);
00204 Py_DECREF(tname);
00205 } else {
00206 str << ", not " << my_type->_name;
00207 }
00208
00209 string msg = str.str();
00210 PyErr_SetString(PyExc_TypeError, msg.c_str());
00211 }
00212 }
00213
00214 } else {
00215
00216
00217 void *result = attempt_coercion(self, classdef, coerced);
00218 if (result != NULL) {
00219 return result;
00220 }
00221
00222
00223 if (report_errors) {
00224 ostringstream str;
00225 str << function_name << "() argument " << param << " must be ";
00226
00227 PyObject *fname = PyObject_GetAttrString((PyObject *)classdef, "__name__");
00228 if (fname != (PyObject *)NULL) {
00229 str << PyString_AsString(fname);
00230 Py_DECREF(fname);
00231 } else {
00232 str << classdef->_name;
00233 }
00234
00235 PyObject *tname = PyObject_GetAttrString((PyObject *)self->ob_type, "__name__");
00236 if (tname != (PyObject *)NULL) {
00237 str << ", not " << PyString_AsString(tname);
00238 Py_DECREF(tname);
00239 }
00240
00241 string msg = str.str();
00242 PyErr_SetString(PyExc_TypeError, msg.c_str());
00243 }
00244 }
00245 } else {
00246 if (report_errors) {
00247 PyErr_SetString(PyExc_TypeError, "Self Is Null");
00248 }
00249 }
00250
00251 return NULL;
00252 }
00253
00254 void * DTOOL_Call_GetPointerThis(PyObject *self)
00255 {
00256 if(self != NULL)
00257 {
00258 if(DtoolCanThisBeAPandaInstance(self))
00259 {
00260 Dtool_PyInstDef * pyself = (Dtool_PyInstDef *) self;
00261 return pyself->_ptr_to_object;
00262 }
00263 }
00264
00265 return NULL;
00266 };
00267
00268
00269
00270
00271
00272
00273
00274 PyObject * DTool_CreatePyInstanceTyped(void * local_this_in, Dtool_PyTypedObject & known_class_type, bool memory_rules, bool is_const, int RunTimeType)
00275 {
00276 if(local_this_in == NULL )
00277 {
00278
00279 PyErr_SetString(PyExc_TypeError, "C Function Return Null 'this'");
00280 return NULL;
00281 }
00282
00283
00284
00285 if(RunTimeType > 0)
00286 {
00287
00288
00289
00290 Dtool_PyTypedObject * target_class = Dtool_RuntimeTypeDtoolType(RunTimeType);
00291 if(target_class != NULL)
00292 {
00293
00294
00295
00296 void * new_local_this = target_class->_Dtool_DowncastInterface(local_this_in,&known_class_type);
00297 if(new_local_this != NULL)
00298 {
00299
00300
00301
00302 Dtool_PyInstDef * self = (Dtool_PyInstDef *) target_class->As_PyTypeObject().tp_new(&target_class->As_PyTypeObject(), NULL,NULL);
00303 if(self != NULL)
00304 {
00305 self->_ptr_to_object = new_local_this;
00306 self->_memory_rules = memory_rules;
00307 self->_is_const = is_const;
00308 self->_signature = PY_PANDA_SIGNATURE;
00309 self->_My_Type = target_class;
00310 return (PyObject *)self;
00311 }
00312 }
00313 }
00314 }
00315
00316
00317
00318
00319
00320 Dtool_PyInstDef * self = (Dtool_PyInstDef *) known_class_type.As_PyTypeObject().tp_new(&known_class_type.As_PyTypeObject(), NULL,NULL);
00321 if(self != NULL)
00322 {
00323 self->_ptr_to_object = local_this_in;
00324 self->_memory_rules = memory_rules;
00325 self->_is_const = is_const;
00326 self->_signature = PY_PANDA_SIGNATURE;
00327 self->_My_Type = &known_class_type;
00328 }
00329 return (PyObject *)self;
00330 };
00331
00332
00333
00334
00335
00336 PyObject * DTool_CreatePyInstance(void * local_this, Dtool_PyTypedObject & in_classdef, bool memory_rules, bool is_const)
00337 {
00338 if(local_this == NULL)
00339 {
00340 PyErr_SetString(PyExc_TypeError, "C Function Return Null 'this' ");
00341 return NULL;
00342 }
00343
00344 Dtool_PyTypedObject * classdef = &in_classdef;
00345 Dtool_PyInstDef * self = (Dtool_PyInstDef *) classdef->As_PyTypeObject().tp_new(&classdef->As_PyTypeObject(), NULL,NULL);
00346 if(self != NULL)
00347 {
00348 self->_ptr_to_object = local_this;
00349 self->_memory_rules = memory_rules;
00350 self->_is_const = is_const;
00351 self->_My_Type = classdef;
00352 }
00353 return (PyObject *)self;
00354 };
00355
00356
00357
00358
00359 int DTool_PyInit_Finalize(PyObject * self, void * This, Dtool_PyTypedObject *type, bool memory_rules, bool is_const)
00360 {
00361
00362
00363
00364 ((Dtool_PyInstDef *)self)->_My_Type = type;
00365 ((Dtool_PyInstDef *)self)->_ptr_to_object = This;
00366 ((Dtool_PyInstDef *)self)->_memory_rules = memory_rules;
00367 ((Dtool_PyInstDef *)self)->_is_const = is_const;
00368 return 0;
00369 }
00370
00371
00372
00373
00374
00375
00376
00377 void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap)
00378 {
00379 for(; in->ml_name != NULL; in++)
00380 {
00381 if(themap.find(in->ml_name) == themap.end())
00382 {
00383 themap[in->ml_name] = in;
00384 }
00385 }
00386 }
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396 void
00397 RegisterRuntimeClass(Dtool_PyTypedObject * otype, int class_id) {
00398 if (class_id == 0) {
00399 interrogatedb_cat.warning()
00400 << "Class " << otype->_name
00401 << " has a zero TypeHandle value; check that init_type() is called.\n";
00402
00403 } else if (class_id > 0) {
00404 RunTimeTypeDictionary &dict = GetRunTimeDictionary();
00405 pair<RunTimeTypeDictionary::iterator, bool> result =
00406 dict.insert(RunTimeTypeDictionary::value_type(class_id, otype));
00407 if (!result.second) {
00408
00409 Dtool_PyTypedObject *other_type = (*result.first).second;
00410 interrogatedb_cat.warning()
00411 << "Classes " << otype->_name << " and " << other_type->_name
00412 << " share the same TypeHandle value (" << class_id
00413 << "); check class definitions.\n";
00414
00415 } else {
00416 GetRunTimeTypeList().insert(class_id);
00417 otype->_Dtool_IsRunTimeCapable = true;
00418 }
00419 }
00420 };
00421
00422
00423
00424 Dtool_PyTypedObject * Dtool_RuntimeTypeDtoolType(int type)
00425 {
00426 RunTimeTypeDictionary::iterator di = GetRunTimeDictionary().find(type);
00427 if(di != GetRunTimeDictionary().end())
00428 return di->second;
00429 else
00430 {
00431 int type2 = get_best_parent_from_Set(type,GetRunTimeTypeList());
00432 di = GetRunTimeDictionary().find(type2);
00433 if(di != GetRunTimeDictionary().end())
00434 return di->second;
00435 }
00436 return NULL;
00437 };
00438
00439
00440 void Dtool_PyModuleInitHelper( LibrayDef *defs[], const char * modulename)
00441 {
00442
00443 MethodDefmap functions;
00444 for(int xx = 0; defs[xx] != NULL; xx++)
00445 Dtool_Accum_MethDefs(defs[xx]->_methods,functions);
00446
00447 PyMethodDef *newdef = new PyMethodDef[functions.size()+1];
00448 MethodDefmap::iterator mi;
00449 int offset = 0;
00450 for(mi = functions.begin(); mi != functions.end(); mi++, offset++)
00451 newdef[offset] = *mi->second;
00452 newdef[offset].ml_doc = NULL;
00453 newdef[offset].ml_name = NULL;
00454 newdef[offset].ml_meth = NULL;
00455 newdef[offset].ml_flags = 0;
00456
00457 PyObject * module = Py_InitModule((char *)modulename,newdef);
00458
00459 if(module == NULL)
00460 {
00461 PyErr_SetString(PyExc_TypeError, "Py_InitModule Returned NULL ???");
00462 return;
00463 }
00464
00465
00466
00467 for(int y = 0; defs[y] != NULL; y++)
00468 defs[y]->_constants(module);
00469
00470 PyModule_AddIntConstant(module,"Dtool_PyNativeInterface",1);
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480 PyObject * Dtool_BorrowThisReference(PyObject * self, PyObject * args )
00481 {
00482 PyObject *from_in = NULL;
00483 PyObject *to_in = NULL;
00484 if(PyArg_ParseTuple(args, "OO", &to_in, &from_in))
00485 {
00486
00487 if(DtoolCanThisBeAPandaInstance(from_in) && DtoolCanThisBeAPandaInstance(to_in))
00488 {
00489 Dtool_PyInstDef * from = (Dtool_PyInstDef *) from_in;
00490 Dtool_PyInstDef * to = (Dtool_PyInstDef *) to_in;
00491 if(from->_My_Type == to->_My_Type)
00492 {
00493 to->_memory_rules = false;
00494 to->_is_const = from->_is_const;
00495 to->_ptr_to_object = from->_ptr_to_object;
00496 return Py_BuildValue("");
00497 }
00498 PyErr_SetString(PyExc_TypeError, "Must Be Same Type??");
00499 }
00500 else
00501 PyErr_SetString(PyExc_TypeError, "One of these does not appear to be DTOOL Instance ??");
00502 }
00503 return (PyObject *) NULL;
00504 }
00505
00506
00507
00508 PyObject * Dtool_AddToDictionary(PyObject * self1, PyObject * args )
00509 {
00510
00511 PyObject * self;
00512 PyObject * subject;
00513 PyObject * key;
00514 if(PyArg_ParseTuple(args, "OSO", &self, &key, &subject))
00515 {
00516 PyObject * dict = ((PyTypeObject *)self)->tp_dict;
00517 if(dict == NULL && !PyDict_Check(dict))
00518 PyErr_SetString(PyExc_TypeError, "No dictionary On Object");
00519 else
00520 PyDict_SetItem(dict,key,subject);
00521
00522 }
00523 if(PyErr_Occurred())
00524 return (PyObject *)NULL;
00525 return Py_BuildValue("");
00526
00527 }
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572 int DTOOL_PyObject_Compare_old(PyObject *v1, PyObject *v2)
00573 {
00574
00575 if(PyType_IsSubtype(v1->ob_type, v2->ob_type))
00576 {
00577 void * v1_this = DTOOL_Call_GetPointerThis(v1);
00578 void * v2_this = DTOOL_Call_GetPointerThis(v2);
00579 if(v1_this != NULL && v2_this != NULL)
00580 {
00581 PyObject * func = PyObject_GetAttrString(v1, "compareTo");
00582 if (func == NULL)
00583 {
00584 PyErr_Clear();
00585 }
00586 else
00587 {
00588 PyObject * res = NULL;
00589 PyObject * args = Py_BuildValue("(O)", v2);
00590 if (args != NULL)
00591 {
00592 res = PyObject_Call(func, args, NULL);
00593 Py_DECREF(args);
00594 }
00595 Py_DECREF(func);
00596 PyErr_Clear();
00597
00598 if(res != NULL && PyInt_Check(res))
00599 {
00600 int answer = PyInt_AsLong(res);
00601 Py_DECREF(res);
00602 return answer;
00603 }
00604 if(res != NULL)
00605 Py_DECREF(res);
00606
00607 };
00608
00609
00610 if(v1_this < v2_this)
00611 return -1;
00612
00613 if(v1_this > v2_this)
00614 return 1;
00615 return 0;
00616 }
00617
00618 }
00619 if(v1 < v2)
00620 return -1;
00621 if(v1 > v2)
00622 return 1;
00623 return 0;
00624 }
00625
00626
00627
00628
00629 int DTOOL_PyObject_Compare(PyObject *v1, PyObject *v2)
00630 {
00631
00632 PyObject * func = PyObject_GetAttrString(v1, "compareTo");
00633 if (func == NULL)
00634 {
00635 PyErr_Clear();
00636 }
00637 else
00638 {
00639 PyObject * res = NULL;
00640 PyObject * args = Py_BuildValue("(O)", v2);
00641 if (args != NULL)
00642 {
00643 res = PyObject_Call(func, args, NULL);
00644 Py_DECREF(args);
00645 }
00646 Py_DECREF(func);
00647 PyErr_Clear();
00648
00649 if(res != NULL && PyInt_Check(res))
00650 {
00651 int answer = PyInt_AsLong(res);
00652 Py_DECREF(res);
00653
00654
00655 if (answer < 0) {
00656 return -1;
00657 } else if (answer > 0) {
00658 return 1;
00659 } else {
00660 return 0;
00661 }
00662 }
00663 if(res != NULL)
00664 Py_DECREF(res);
00665
00666 };
00667
00668
00669 void * v1_this = DTOOL_Call_GetPointerThis(v1);
00670 void * v2_this = DTOOL_Call_GetPointerThis(v2);
00671 if(v1_this != NULL && v2_this != NULL)
00672 {
00673 if(v1_this < v2_this)
00674 return -1;
00675
00676 if(v1_this > v2_this)
00677 return 1;
00678 return 0;
00679 }
00680
00681
00682 if(v1 < v2)
00683 return -1;
00684 if(v1 > v2)
00685 return 1;
00686 return 0;
00687 }
00688
00689
00690 PyObject *make_list_for_item(PyObject *self, const char *num_name,
00691 const char *element_name) {
00692 PyObject *num_result = PyObject_CallMethod(self, (char *)num_name, (char *)"()");
00693 if (num_result == NULL) {
00694 return NULL;
00695 }
00696 Py_ssize_t num_elements = PyInt_AsSsize_t(num_result);
00697 Py_DECREF(num_result);
00698
00699 PyObject *list = PyList_New(num_elements);
00700 for (int i = 0; i < num_elements; ++i) {
00701 PyObject *element = PyObject_CallMethod(self, (char *)element_name, (char *)"(i)", i);
00702 if (element == NULL) {
00703 Py_DECREF(list);
00704 return NULL;
00705 }
00706 PyList_SetItem(list, i, element);
00707 }
00708 return list;
00709 }
00710
00711
00712
00713
00714
00715
00716 PyObject *copy_from_make_copy(PyObject *self) {
00717 return PyObject_CallMethod(self, (char *)"makeCopy", (char *)"()");
00718 }
00719
00720
00721
00722
00723
00724
00725 PyObject *copy_from_copy_constructor(PyObject *self) {
00726 PyObject *this_class = PyObject_Type(self);
00727 if (this_class == NULL) {
00728 return NULL;
00729 }
00730
00731 PyObject *result = PyObject_CallFunction(this_class, (char *)"(O)", self);
00732 Py_DECREF(this_class);
00733 return result;
00734 }
00735
00736
00737
00738
00739
00740
00741
00742
00743 PyObject *map_deepcopy_to_copy(PyObject *self, PyObject *args) {
00744 return PyObject_CallMethod(self, (char *)"__copy__", (char *)"()");
00745 }
00746
00747
00748
00749
00750
00751
00752
00753 EXPCL_DTOOLCONFIG PyObject *
00754 PyLongOrInt_FromUnsignedLong(unsigned long value) {
00755 if ((long)value < 0) {
00756 return PyLong_FromUnsignedLong(value);
00757 } else {
00758 return PyInt_FromLong((long)value);
00759 }
00760 }
00761
00762
00763 #endif // HAVE_PYTHON