Adonthell  0.4
py_callback.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2001/2002 Kai Sterker <kai.sterker@gmail.com>
3  Part of the Adonthell Project <http://adonthell.nongnu.org>
4 
5  Adonthell is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  Adonthell is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with Adonthell. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 
20 /**
21  * @file py_callback.cc
22  * @author Kai Sterker <kai.sterker@gmail.com>
23  *
24  * @brief Defines the py_callback class.
25  *
26  *
27  */
28 
29 
30 #include "py_callback.h"
31 #include "python_class.h"
32 
33 // 'hack' to aid restoring of callbacks from file
34 PyObject *py_callback::instance = NULL;
35 
36 // default constructor
38 {
39  function = NULL;
40  arguments = NULL;
41 }
42 
43 // preferred constructor
44 py_callback::py_callback (PyObject *func, PyObject *args)
45 {
46  function = func;
47  arguments = args == Py_None ? NULL : args;
48  Py_XINCREF (function);
49  Py_XINCREF (arguments);
50 }
51 
52 // dtor
54 {
55  Py_XDECREF (function);
56  Py_XDECREF (arguments);
57 }
58 
59 // calls the python function without argument
61 {
62  PyObject *py_arg = arguments ? Py_BuildValue ("(O)",arguments) : NULL;
63  PyObject* val = make_call (py_arg);
64  Py_XDECREF (val);
65 }
66 
67 // calls the python function returning a boolean
69 {
70  int retval = 1;
71 
72  PyObject *py_arg = arguments ? Py_BuildValue ("(O)",arguments) : NULL;
73  PyObject* val = make_call (py_arg);
74 
75  if (val) retval = PyInt_AsLong (val);
76  Py_XDECREF (val);
77 
78  return retval != 0;
79 }
80 
81 // calls the python function with an integer as argument
83 {
84  PyObject *py_arg;
85 
86  if (arguments) py_arg = Py_BuildValue ("(i,O)", arg, arguments);
87  else py_arg = Py_BuildValue ("(i)", arg);
88 
89  PyObject * val = make_call (py_arg);
90  Py_XDECREF (val);
91 }
92 
93 // save callback to a file
94 void py_callback::put_state (ogzstream & file) const
95 {
96  std::string name = "";
97 
98  // get name of callback function
99  if (function) {
100  PyObject *p_name = PyObject_GetAttrString (function, "__name__");
101  if (PyString_Check (p_name)) name = python::as_string (p_name);
102  else fprintf (stderr, "*** error: py_callback::put_state: Failed to retrieve callback name!");
103 
104  // cleanup
105  Py_XDECREF (p_name);
106  }
107 
108  name >> file;
109 
110  // NOTE: extra arguments need to be a tuple containing only ints or strings.
111  if (arguments != NULL)
112  {
113  true >> file;
114  python::put_tuple (arguments, file);
115  }
116  else false >> file;
117 }
118 
119 // restore callback from a file
121 {
122  std::string name;
123  bool has_args;
124 
125  name << file;
126  has_args << file;
127 
128  // load arguments. No need to INCREF as get_tuple returns new instance.
129  if (has_args) arguments = python::get_tuple (file);
130 
131  // check that we have a valid instance that contains our callback
132  if (instance == NULL)
133  {
134  fprintf (stderr, "*** error: py_callback::get_state: Invalid instance!\n");
135  return false;
136  }
137 
138  // get our callback from the class or module. No need to INCREF
139  // as GetAttrString returns a new instance.
140  function = PyObject_GetAttrString (instance, (char *) name.c_str ());
141 
142  // sanity check
143  if (!PyCallable_Check (function))
144  {
145  fprintf (stderr, "*** error: py_callback::get_state: Setting callback '%s' failed!\n", name.c_str ());
146  return false;
147  }
148 
149  return true;
150 }
151 
152 // the actual python callback call
153 PyObject *py_callback::make_call (PyObject *args)
154 {
155  if (function == NULL) return NULL;
156 
157  PyObject * val = PyObject_CallObject (function, args);
158  Py_XDECREF (args);
159 
160 #ifdef PY_DEBUG
162 #endif
163 
164  return val;
165 }
py_callback::get_state
bool get_state(igzstream &in)
Restores the callback from a file.
Definition: py_callback.cc:120
igzstream
Class to read data from a Gzip compressed file.
Definition: fileops.h:135
py_callback::callback_func1
void callback_func1(int arg)
Calls the python function with an integer.
Definition: py_callback.cc:82
python::show_traceback
static void show_traceback(void)
Dumps any error information to stderr.
Definition: python_class.cc:107
python_class.h
Defines the python class. This file is named this way so it doesn't conflicts with Python....
py_callback::~py_callback
~py_callback()
Destructor.
Definition: py_callback.cc:53
ogzstream
Class to write data from a Gzip compressed file.
Definition: fileops.h:227
py_callback::put_state
void put_state(ogzstream &out) const
Saves the callback and it's arguments to file.
Definition: py_callback.cc:94
python::get_tuple
static PyObject * get_tuple(igzstream &file)
Loads a Python tuple previously saved with put_tuple ().
Definition: python_class.cc:134
python::put_tuple
static void put_tuple(PyObject *tuple, ogzstream &file)
Save a Python tuple into a file.
Definition: python_class.cc:167
py_callback::callback_func0ret
bool callback_func0ret()
Calls the python function and returns bool.
Definition: py_callback.cc:68
py_callback::py_callback
py_callback()
Default ctor,.
Definition: py_callback.cc:37
py_callback::instance
static PyObject * instance
When restoring a callback from file, instance has to point to the python instance (module or class) c...
Definition: py_callback.h:122
py_callback::callback_func0
void callback_func0()
Calls the python function without arguments.
Definition: py_callback.cc:60
py_callback.h
Declares the py_callback class.