GNU Radio 3.7.2 C++ API
pycallback_object.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2012 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #include <iostream>
27 #include <pythread.h>
28 #include <boost/format.hpp>
29 
30 enum pyport_t {
33 };
34 
35 class Instance
36 {
37 public:
39  {
41  }
42  static Ice::CommunicatorPtr get_swig_communicator()
43  {
44  return get_application()->communicator();
45  }
46 };
47 
49 
50 // a simple to-PMT converter template class-function
51 template <class myType> class pmt_assist
52 {
53 public:
54  static pmt::pmt_t make(myType _val)
55  {
56  return pmt::mp(_val);
57  }
58 };
59 
60 /* template specializations for vectors that cant use pmt::mp() */
61 template<>
62 pmt::pmt_t pmt_assist<std::vector<float> >::make(std::vector<float> _val)
63 {
64  return pmt::init_f32vector(_val.size(), &_val[0]);
65 }
66 
67 template<>
68 pmt::pmt_t pmt_assist<std::vector<gr_complex> >::make(std::vector<gr_complex> _val)
69 {
70  return pmt::init_c32vector(_val.size(), &_val[0]);
71 }
72 
73 template <class myType> class pycallback_object
74 {
75 public:
76  pycallback_object(std::string name, std::string functionbase,
77  std::string units, std::string desc,
78  myType min, myType max, myType deflt,
79  DisplayType dtype) :
80  d_callback(NULL),
81  d_functionbase(functionbase), d_units(units), d_desc(desc),
82  d_min(min), d_max(max), d_deflt(deflt), d_dtype(dtype),
83  d_name(name), d_id(pycallback_object_count++)
84  {
85  d_callback = NULL;
86  setup_rpc();
87  }
88 
90  {
91  d_rpc_vars.push_back(s);
92  }
93 
94  myType get() {
95  myType rVal = d_deflt;
96  if(d_callback == NULL) {
97  printf("WARNING: pycallback_object get() called without py callback set!\n");
98  return rVal;
99  }
100  else {
101  // obtain PyGIL
102  PyGILState_STATE state = PyGILState_Ensure();
103 
104  PyObject *func;
105  //PyObject *arglist;
106  PyObject *result;
107 
108  func = (PyObject *) d_callback; // Get Python function
109  //arglist = Py_BuildValue(""); // Build argument list
110  result = PyEval_CallObject(func,NULL); // Call Python
111  //result = PyEval_CallObject(func,arglist); // Call Python
112  //Py_DECREF(arglist); // Trash arglist
113  if(result) { // If no errors, return double
114  rVal = pyCast(result);
115  }
116  Py_XDECREF(result);
117 
118  // release PyGIL
119  PyGILState_Release(state);
120  return rVal;
121  }
122  }
123 
124  void set_callback(PyObject *cb)
125  {
126  d_callback = cb;
127  }
128 
129  void setup_rpc()
130  {
131 #ifdef GR_CTRLPORT
134  (boost::format("%s%d") % d_name % d_id).str() , d_functionbase.c_str(),
137  d_units.c_str(), d_desc.c_str(), RPC_PRIVLVL_MIN, d_dtype)));
138 #endif /* GR_CTRLPORT */
139  }
140 
141 private:
142  PyObject* d_callback;
143  std::string d_functionbase, d_units, d_desc;
144  myType d_min, d_max, d_deflt;
145  DisplayType d_dtype;
146 
147  /* This is a fall-through converter in case someone tries to call pyCast on an
148  * object type for which there isn't a template specialization (located below
149  * this class) function. This function should never get called, and it is
150  * unknown if changing the return type from myType to 'void' will break
151  * something. */
152  myType pyCast(PyObject* obj) {
153  printf("TYPE NOT IMPLEMENTED!\n");
154  assert(0);
155  };
156 
157  std::vector<boost::any> d_rpc_vars; // container for all RPC variables
158  std::string d_name;
159  int d_id;
160 };
161 
162 
163 // template specialization conversion functions
164 // get data out of the PyObject and into the real world
165 template<>
166 std::string pycallback_object<std::string>::pyCast(PyObject* obj)
167 {
168  return std::string(PyString_AsString(obj));
169 }
170 
171 template<>
172 double pycallback_object<double>::pyCast(PyObject* obj)
173 {
174  return PyFloat_AsDouble(obj);
175 }
176 
177 template<>
178 float pycallback_object<float>::pyCast(PyObject* obj)
179 {
180  return (float)PyFloat_AsDouble(obj);
181 }
182 
183 template<>
184 int pycallback_object<int>::pyCast(PyObject* obj)
185 {
186  return PyInt_AsLong(obj);
187 }
188 
189 template<>
190 std::vector<float> pycallback_object<std::vector<float> >::pyCast(PyObject* obj)
191 {
192  int size = PyObject_Size(obj);
193  std::vector<float> rval(size);
194  for(int i=0; i<size; i++) {
195  rval[i] = (float)PyFloat_AsDouble(PyList_GetItem(obj, i));
196  }
197  return rval;
198 }
199 
200 template<>
201 std::vector<gr_complex> pycallback_object<std::vector<gr_complex> >::pyCast(PyObject* obj)
202 {
203  int size = PyObject_Size(obj);
204  std::vector<gr_complex> rval(size);
205  for(int i=0; i<size; i++){ rval[i] = \
206  gr_complex((float)PyComplex_RealAsDouble(PyList_GetItem(obj, i)),
207  (float)PyComplex_ImagAsDouble(PyList_GetItem(obj, i)));
208  }
209  return rval;
210 }
211 // TODO: add more template specializations as needed!
static boost::shared_ptr< ice_application_common > get_application()
Definition: pycallback_object.h:38
Definition: pycallback_object.h:32
pycallback_object(std::string name, std::string functionbase, std::string units, std::string desc, myType min, myType max, myType deflt, DisplayType dtype)
Definition: pycallback_object.h:76
float min(float a, float b)
int pycallback_object_count
Definition: pycallback_object.h:48
void setup_rpc()
Definition: pycallback_object.h:129
static pmt::pmt_t make(myType _val)
Definition: pycallback_object.h:54
pyport_t
Definition: pycallback_object.h:30
Definition: rpccallbackregister_base.h:48
Definition: pycallback_object.h:73
Definition: rpcregisterhelpers.h:557
std::complex< float > gr_complex
Definition: gr_complex.h:27
static boost::shared_ptr< ice_application_common > Instance()
void set_callback(PyObject *cb)
Definition: pycallback_object.h:124
PMT_API pmt_t init_f32vector(size_t k, const float *data)
PMT_API pmt_t init_c32vector(size_t k, const std::complex< float > *data)
VOLK_API $kern pname $kern name
A function pointer to the dispatcher implementation.
Definition: pycallback_object.h:31
void add_rpc_variable(rpcbasic_sptr s)
Definition: pycallback_object.h:89
boost::intrusive_ptr< pmt_base > pmt_t
typedef for shared pointer (transparent reference counting). See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
Definition: pmt.h:56
Definition: pycallback_object.h:51
static pmt_t mp(const std::string &s)
Make pmt symbol.
Definition: pmt_sugar.h:36
Definition: pycallback_object.h:35
myType get()
Definition: pycallback_object.h:94
uint32_t DisplayType
Definition: rpccallbackregister_base.h:29