Adonthell 0.4
|
00001 /* 00002 $Id: py_callback.cc,v 1.11 2004/02/02 06:38:01 ksterker Exp $ 00003 00004 Copyright (C) 2001/2002 Kai Sterker <kaisterker@linuxgames.com> 00005 Part of the Adonthell Project http://adonthell.linuxgames.com 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License. 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY. 00011 00012 See the COPYING file for more details. 00013 */ 00014 00015 00016 /** 00017 * @file py_callback.cc 00018 * @author Kai Sterker <kaisterker@linuxgames.com> 00019 * 00020 * @brief Defines the py_callback class. 00021 * 00022 * 00023 */ 00024 00025 00026 #include "py_callback.h" 00027 #include "python_class.h" 00028 00029 // 'hack' to aid restoring of callbacks from file 00030 PyObject *py_callback::instance = NULL; 00031 00032 // default constructor 00033 py_callback::py_callback () 00034 { 00035 function = NULL; 00036 arguments = NULL; 00037 } 00038 00039 // preferred constructor 00040 py_callback::py_callback (PyObject *func, PyObject *args) 00041 { 00042 function = func; 00043 arguments = args; 00044 Py_XINCREF (function); 00045 Py_XINCREF (arguments); 00046 } 00047 00048 // dtor 00049 py_callback::~py_callback () 00050 { 00051 Py_XDECREF (function); 00052 Py_XDECREF (arguments); 00053 } 00054 00055 // calls the python function without argument 00056 void py_callback::callback_func0 () 00057 { 00058 PyObject *py_arg = arguments ? Py_BuildValue ("(O)",arguments) : NULL; 00059 PyObject* val = make_call (py_arg); 00060 Py_XDECREF (val); 00061 } 00062 00063 // calls the python function returning a boolean 00064 bool py_callback::callback_func0ret () 00065 { 00066 int retval = 1; 00067 00068 PyObject *py_arg = arguments ? Py_BuildValue ("(O)",arguments) : NULL; 00069 PyObject* val = make_call (py_arg); 00070 00071 if (val) retval = PyInt_AsLong (val); 00072 Py_XDECREF (val); 00073 00074 return retval != 0; 00075 } 00076 00077 // calls the python function with an integer as argument 00078 void py_callback::callback_func1 (int arg) 00079 { 00080 PyObject *py_arg; 00081 00082 if (arguments) py_arg = Py_BuildValue ("(i,O)", arg, arguments); 00083 else py_arg = Py_BuildValue ("(i)", arg); 00084 00085 PyObject * val = make_call (py_arg); 00086 Py_XDECREF (val); 00087 } 00088 00089 // save callback to a file 00090 void py_callback::put_state (ogzstream & file) const 00091 { 00092 std::string name = ""; 00093 00094 // get name of callback function 00095 if (function) { 00096 PyObject *p_name = PyObject_GetAttrString (function, "__name__"); 00097 if (PyString_Check (p_name)) name = PyString_AsString (p_name); 00098 else fprintf (stderr, "*** error: py_callback::put_state: Failed to retrieve callback name!"); 00099 00100 // cleanup 00101 Py_XDECREF (p_name); 00102 } 00103 00104 name >> file; 00105 00106 // NOTE: extra arguments need to be a tuple containing only ints or strings. 00107 if (arguments != NULL) 00108 { 00109 true >> file; 00110 python::put_tuple (arguments, file); 00111 } 00112 else false >> file; 00113 } 00114 00115 // restore callback from a file 00116 bool py_callback::get_state (igzstream & file) 00117 { 00118 std::string name; 00119 bool has_args; 00120 00121 name << file; 00122 has_args << file; 00123 00124 // load arguments. No need to INCREF as get_tuple returns new instance. 00125 if (has_args) arguments = python::get_tuple (file); 00126 00127 // check that we have a valid instance that contains our callback 00128 if (instance == NULL) 00129 { 00130 fprintf (stderr, "*** error: py_callback::get_state: Invalid instance!\n"); 00131 return false; 00132 } 00133 00134 // get our callback from the class or module. No need to INCREF 00135 // as GetAttrString returns a new instance. 00136 function = PyObject_GetAttrString (instance, (char *) name.c_str ()); 00137 00138 // sanity check 00139 if (!PyCallable_Check (function)) 00140 { 00141 fprintf (stderr, "*** error: py_callback::get_state: Setting callback '%s' failed!\n", name.c_str ()); 00142 return false; 00143 } 00144 00145 return true; 00146 } 00147 00148 // the actual python callback call 00149 PyObject *py_callback::make_call (PyObject *args) 00150 { 00151 if (function == NULL) return NULL; 00152 00153 PyObject * val = PyObject_CallObject (function, args); 00154 Py_XDECREF (args); 00155 00156 #ifdef PY_DEBUG 00157 python::show_traceback (); 00158 #endif 00159 00160 return val; 00161 }