• Main Page
  • Related Pages
  • Classes
  • Files
  • File List
  • File Members

py_callback.cc

Go to the documentation of this file.
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 }

Generated on Mon Sep 12 2011 for Adonthell by  doxygen 1.7.1