Imported Upstream version 3.2.2
[debian/gnuradio] / gnuradio-core / src / lib / general / gr_feval.i
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2006 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
24 /*
25  * N.B., this is a _very_ non-standard SWIG .i file
26  *
27  * It contains a bunch of magic that is required to ensure that when
28  * these classes are used as base classes for python code,
29  * everything works when calling back from C++ into Python.
30  *
31  * The gist of the problem is that our C++ code is usually not holding
32  * the Python Global Interpreter Lock (GIL).  Thus if we invoke a
33  * "director" method from C++, we'll end up in Python not holding the
34  * GIL.  Disaster (SIGSEGV) will result.  To avoid this we insert a
35  * "shim" that grabs and releases the GIL.
36  *
37  * If you don't understand SWIG "directors" or the Python GIL,
38  * don't bother trying to understand what's going on in here.
39  *
40  * [We could eliminate a bunch of this hair by requiring SWIG 1.3.29
41  * or later and some additional magic declarations, but many systems
42  * aren't shipping that version yet.  Thus we kludge...]
43  */
44
45
46 // Enable SWIG directors for these classes
47 %feature("director") gr_py_feval_dd;
48 %feature("director") gr_py_feval_cc;
49 %feature("director") gr_py_feval_ll;
50 %feature("director") gr_py_feval;
51
52 %feature("nodirector") gr_py_feval_dd::calleval;
53 %feature("nodirector") gr_py_feval_cc::calleval;
54 %feature("nodirector") gr_py_feval_ll::calleval;
55 %feature("nodirector") gr_py_feval::calleval;
56
57
58 %rename(feval_dd) gr_py_feval_dd;
59 %rename(feval_cc) gr_py_feval_cc;
60 %rename(feval_ll) gr_py_feval_ll;
61 %rename(feval)    gr_py_feval;
62
63 //%exception {
64 //  try { $action }
65 //  catch (Swig::DirectorException &e) { std::cerr << e.getMessage();  SWIG_fail; }
66 //}
67
68 %{
69
70 // class that ensures we acquire and release the Python GIL
71
72 class ensure_py_gil_state {
73   PyGILState_STATE      d_gstate;
74 public:
75   ensure_py_gil_state()  { d_gstate = PyGILState_Ensure(); }
76   ~ensure_py_gil_state() { PyGILState_Release(d_gstate); }
77 };
78
79 %}
80
81 /*
82  * These are the real C++ base classes, however we don't want these exposed.
83  */
84 %ignore gr_feval_dd;
85 class gr_feval_dd
86 {
87 protected:
88   virtual double eval(double x);
89
90 public:
91   gr_feval_dd() {}
92   virtual ~gr_feval_dd();
93
94   virtual double calleval(double x);
95 };
96
97 %ignore gr_feval_cc;
98 class gr_feval_cc
99 {
100 protected:
101   virtual gr_complex eval(gr_complex x);
102
103 public:
104   gr_feval_cc() {}
105   virtual ~gr_feval_cc();
106
107   virtual gr_complex calleval(gr_complex x);
108 };
109
110 %ignore gr_feval_ll;
111 class gr_feval_ll
112 {
113 protected:
114   virtual long eval(long x);
115   
116 public:
117   gr_feval_ll() {}
118   virtual ~gr_feval_ll();
119
120   virtual long calleval(long x);
121 };
122
123 %ignore gr_feval;
124 class gr_feval
125 {
126 protected:
127   virtual void eval();
128   
129 public:
130   gr_feval() {}
131   virtual ~gr_feval();
132
133   virtual void calleval();
134 };
135
136 /*
137  * These are the ones to derive from in Python.  They have the magic shim
138  * that ensures that we're holding the Python GIL when we enter Python land...
139  */
140
141 %inline %{
142
143 class gr_py_feval_dd : public gr_feval_dd
144 {
145  public:
146   double calleval(double x)
147   {
148     ensure_py_gil_state _lock;
149     return eval(x);
150   }
151 };
152
153 class gr_py_feval_cc : public gr_feval_cc
154 {
155  public:
156   gr_complex calleval(gr_complex x)
157   {
158     ensure_py_gil_state _lock;
159     return eval(x);
160   }
161 };
162
163 class gr_py_feval_ll : public gr_feval_ll
164 {
165  public:
166   long calleval(long x)
167   {
168     ensure_py_gil_state _lock;
169     return eval(x);
170   }
171 };
172
173 class gr_py_feval : public gr_feval
174 {
175  public:
176   void calleval()
177   {
178     ensure_py_gil_state _lock;
179     eval();
180   }
181 };
182
183 %}
184
185
186
187 // examples / test cases
188
189 %rename(feval_dd_example) gr_feval_dd_example;
190 double gr_feval_dd_example(gr_feval_dd *f, double x);
191
192 %rename(feval_cc_example) gr_feval_cc_example;
193 gr_complex gr_feval_cc_example(gr_feval_cc *f, gr_complex x);
194
195 %rename(feval_ll_example) gr_feval_ll_example;
196 long gr_feval_ll_example(gr_feval_ll *f, long x);
197
198 %rename(feval_example) gr_feval_example;
199 void gr_feval_example(gr_feval *f);