00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "pythonCallbackObject.h"
00016
00017 #ifdef HAVE_PYTHON
00018 #include "py_panda.h"
00019 #include "thread.h"
00020 #include "callbackData.h"
00021
00022 TypeHandle PythonCallbackObject::_type_handle;
00023
00024 #ifndef CPPPARSER
00025 IMPORT_THIS struct Dtool_PyTypedObject Dtool_TypedObject;
00026 #endif
00027
00028
00029
00030
00031
00032
00033 PythonCallbackObject::
00034 PythonCallbackObject(PyObject *function) {
00035 _function = Py_None;
00036 Py_INCREF(_function);
00037
00038 set_function(function);
00039
00040 #ifndef SIMPLE_THREADS
00041
00042
00043 #ifdef WITH_THREAD // This symbol defined within Python.h
00044 PyEval_InitThreads();
00045 #endif
00046 #endif
00047 }
00048
00049
00050
00051
00052
00053
00054 PythonCallbackObject::
00055 ~PythonCallbackObject() {
00056 Py_DECREF(_function);
00057 }
00058
00059
00060
00061
00062
00063
00064
00065
00066 void PythonCallbackObject::
00067 set_function(PyObject *function) {
00068 Py_DECREF(_function);
00069 _function = function;
00070 Py_INCREF(_function);
00071 if (_function != Py_None && !PyCallable_Check(_function)) {
00072 nassert_raise("Invalid function passed to PythonCallbackObject");
00073 }
00074 }
00075
00076
00077
00078
00079
00080
00081 PyObject *PythonCallbackObject::
00082 get_function() {
00083 Py_INCREF(_function);
00084 return _function;
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 void PythonCallbackObject::
00096 do_callback(CallbackData *cbdata) {
00097 #if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
00098
00099 PyGILState_STATE gstate;
00100 gstate = PyGILState_Ensure();
00101 #endif
00102
00103 do_python_callback(cbdata);
00104
00105 #if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
00106 PyGILState_Release(gstate);
00107 #endif
00108 }
00109
00110
00111
00112
00113
00114
00115
00116
00117 void PythonCallbackObject::
00118 do_python_callback(CallbackData *cbdata) {
00119 nassertv(cbdata != NULL);
00120
00121
00122
00123 PyObject *pycbdata =
00124 DTool_CreatePyInstanceTyped(cbdata, Dtool_TypedObject,
00125 false, false, cbdata->get_type_index());
00126 PyObject *args = Py_BuildValue("(O)", pycbdata);
00127 Py_DECREF(pycbdata);
00128
00129 PyObject *result =
00130 Thread::get_current_thread()->call_python_func(_function, args);
00131 Py_DECREF(args);
00132
00133 if (result == (PyObject *)NULL) {
00134 util_cat.error()
00135 << "Exception occurred in " << *this << "\n";
00136 } else {
00137 Py_DECREF(result);
00138 }
00139 }
00140
00141 #endif // HAVE_PYTHON