Logo ROOT   6.21/01
Reference Guide
TPyDispatcher.cxx
Go to the documentation of this file.
1 // Author: Wim Lavrijsen, Aug 2007
2 
3 // Bindings
4 #include "PyROOT.h"
5 #include "TPyDispatcher.h"
6 #include "RootWrapper.h"
7 
8 // ROOT
9 #include "TClass.h"
10 #include "TObject.h"
11 
12 // Standard
13 #include <stdarg.h>
14 
15 
16 //______________________________________________________________________________
17 // Python callback dispatcher
18 // ==========================
19 //
20 // The TPyDispatcher class acts as a functor that can be used for TFn's and GUIs
21 // to install callbacks from CINT.
22 
23 
24 //- data ---------------------------------------------------------------------
26 
27 
28 //- constructors/destructor --------------------------------------------------
29 TPyDispatcher::TPyDispatcher( PyObject* callable ) : fCallable( 0 )
30 {
31 // Construct a TPyDispatcher from a callable python object. Applies python
32 // object reference counting.
33  Py_XINCREF( callable );
34  fCallable = callable;
35 }
36 
37 ////////////////////////////////////////////////////////////////////////////////
38 /// Copy constructor. Applies python object reference counting.
39 
41 {
42  Py_XINCREF( other.fCallable );
43  fCallable = other.fCallable;
44 }
45 
46 ////////////////////////////////////////////////////////////////////////////////
47 /// Assignment operator. Applies python object reference counting.
48 
50 {
51  if ( this != &other ) {
52  this->TObject::operator=( other );
53 
54  Py_XDECREF( fCallable );
55  Py_XINCREF( other.fCallable );
56  fCallable = other.fCallable;
57  }
58 
59  return *this;
60 }
61 
62 ////////////////////////////////////////////////////////////////////////////////
63 /// Destructor. Reference counting for the held python object is in effect.
64 
66  Py_XDECREF( fCallable );
67 }
68 
69 
70 //- public members -----------------------------------------------------------
71 PyObject* TPyDispatcher::DispatchVA( const char* format, ... )
72 {
73 // Dispatch the arguments to the held callable python object, using format to
74 // interpret the types of the arguments. Note that format is in python style,
75 // not in C printf style. See: https://docs.python.org/2/c-api/arg.html .
76  PyObject* args = 0;
77 
78  if ( format ) {
79  va_list va;
80  va_start( va, format );
81 
82  args = Py_VaBuildValue( (char*)format, va );
83 
84  va_end( va );
85 
86  if ( ! args ) {
87  PyErr_Print();
88  return 0;
89  }
90 
91  if ( ! PyTuple_Check( args ) ) { // if only one arg ...
92  PyObject* t = PyTuple_New( 1 );
93  PyTuple_SET_ITEM( t, 0, args );
94  args = t;
95  }
96 
97  }
98 
99  PyObject* result = PyObject_CallObject( fCallable, args );
100  Py_XDECREF( args );
101 
102  if ( ! result ) {
103  PyErr_Print();
104  return 0;
105  }
106 
107  return result;
108 }
109 
110 ////////////////////////////////////////////////////////////////////////////////
111 
112 PyObject* TPyDispatcher::DispatchVA1( const char* clname, void* obj, const char* format, ... )
113 {
114  PyObject* pyobj = PyROOT::BindCppObject( obj, Cppyy::GetScope( clname ), kFALSE /* isRef */ );
115  if ( ! pyobj ) {
116  PyErr_Print();
117  return 0;
118  }
119 
120  PyObject* args = 0;
121 
122  if ( format ) {
123  va_list va;
124  va_start( va, format );
125 
126  args = Py_VaBuildValue( (char*)format, va );
127 
128  va_end( va );
129 
130  if ( ! args ) {
131  PyErr_Print();
132  return 0;
133  }
134 
135  if ( ! PyTuple_Check( args ) ) { // if only one arg ...
136  PyObject* t = PyTuple_New( 2 );
137  PyTuple_SET_ITEM( t, 0, pyobj );
138  PyTuple_SET_ITEM( t, 1, args );
139  args = t;
140  } else {
141  PyObject* t = PyTuple_New( PyTuple_GET_SIZE( args ) + 1 );
142  PyTuple_SET_ITEM( t, 0, pyobj );
143  for ( int i = 0; i < PyTuple_GET_SIZE( args ); i++ ) {
144  PyObject* item = PyTuple_GET_ITEM( args, i );
145  Py_INCREF( item );
146  PyTuple_SET_ITEM( t, i+1, item );
147  }
148  Py_DECREF( args );
149  args = t;
150  }
151  } else {
152  args = PyTuple_New( 1 );
153  PyTuple_SET_ITEM( args, 0, pyobj );
154  }
155 
156  PyObject* result = PyObject_CallObject( fCallable, args );
157  Py_XDECREF( args );
158 
159  if ( ! result ) {
160  PyErr_Print();
161  return 0;
162  }
163 
164  return result;
165 }
166 
167 ////////////////////////////////////////////////////////////////////////////////
168 
169 PyObject* TPyDispatcher::Dispatch( TPad* selpad, TObject* selected, Int_t event )
170 {
171  PyObject* args = PyTuple_New( 3 );
172  PyTuple_SET_ITEM( args, 0, PyROOT::BindCppObject( selpad, Cppyy::GetScope( "TPad" ) ) );
173  PyTuple_SET_ITEM( args, 1, PyROOT::BindCppObject( selected, Cppyy::GetScope( "TObject" ) ) );
174  PyTuple_SET_ITEM( args, 2, PyInt_FromLong( event ) );
175 
176  PyObject* result = PyObject_CallObject( fCallable, args );
177  Py_XDECREF( args );
178 
179  if ( ! result ) {
180  PyErr_Print();
181  return 0;
182  }
183 
184  return result;
185 }
186 
187 ////////////////////////////////////////////////////////////////////////////////
188 
190 {
191  PyObject* args = PyTuple_New( 4 );
192  PyTuple_SET_ITEM( args, 0, PyInt_FromLong( event ) );
193  PyTuple_SET_ITEM( args, 1, PyInt_FromLong( x ) );
194  PyTuple_SET_ITEM( args, 2, PyInt_FromLong( y ) );
195  PyTuple_SET_ITEM( args, 3, PyROOT::BindCppObject( selected, Cppyy::GetScope( "TObject" ) ) );
196 
197  PyObject* result = PyObject_CallObject( fCallable, args );
198  Py_XDECREF( args );
199 
200  if ( ! result ) {
201  PyErr_Print();
202  return 0;
203  }
204 
205  return result;
206 }
207 
208 ////////////////////////////////////////////////////////////////////////////////
209 
211 {
212  PyObject* args = PyTuple_New( 3 );
213  PyTuple_SET_ITEM( args, 0, PyROOT::BindCppObject( pad, Cppyy::GetScope( "TVirtualPad" ) ) );
214  PyTuple_SET_ITEM( args, 1, PyROOT::BindCppObject( obj, Cppyy::GetScope( "TObject" ) ) );
215  PyTuple_SET_ITEM( args, 2, PyInt_FromLong( event ) );
216 
217  PyObject* result = PyObject_CallObject( fCallable, args );
218  Py_XDECREF( args );
219 
220  if ( ! result ) {
221  PyErr_Print();
222  return 0;
223  }
224 
225  return result;
226 }
227 
228 ////////////////////////////////////////////////////////////////////////////////
229 
231 {
232  PyObject* args = PyTuple_New( 2 );
233  PyTuple_SET_ITEM( args, 0, PyROOT::BindCppObject( item, Cppyy::GetScope( "TGListTreeItem" ) ) );
234  PyTuple_SET_ITEM( args, 1, PyROOT::BindCppObject( data, Cppyy::GetScope( "TDNDData" ) ) );
235 
236  PyObject* result = PyObject_CallObject( fCallable, args );
237  Py_XDECREF( args );
238 
239  if ( ! result ) {
240  PyErr_Print();
241  return 0;
242  }
243 
244  return result;
245 }
246 
247 ////////////////////////////////////////////////////////////////////////////////
248 
249 PyObject* TPyDispatcher::Dispatch( const char* name, const TList* attr )
250 {
251  PyObject* args = PyTuple_New( 2 );
252  PyTuple_SET_ITEM( args, 0, PyBytes_FromString( name ) );
253  PyTuple_SET_ITEM( args, 1, PyROOT::BindCppObject( (void*)attr, Cppyy::GetScope( "TList" ) ) );
254 
255  PyObject* result = PyObject_CallObject( fCallable, args );
256  Py_XDECREF( args );
257 
258  if ( ! result ) {
259  PyErr_Print();
260  return 0;
261  }
262 
263  return result;
264 }
265 
266 ////////////////////////////////////////////////////////////////////////////////
267 
269 {
270  PyObject* args = PyTuple_New( 2 );
271  PyTuple_SET_ITEM( args, 0, PyROOT::BindCppObject( slave, Cppyy::GetScope( "TSlave" ) ) );
272  PyTuple_SET_ITEM( args, 1, PyROOT::BindCppObject( pi, Cppyy::GetScope( "TProofProgressInfo" ) ) );
273 
274  PyObject* result = PyObject_CallObject( fCallable, args );
275  Py_XDECREF( args );
276 
277  if ( ! result ) {
278  PyErr_Print();
279  return 0;
280  }
281 
282  return result;
283 }
TPyDispatcher & operator=(const TPyDispatcher &)
Assignment operator. Applies python object reference counting.
#define PyBytes_FromString
Definition: PyROOT.h:71
PyObject * DispatchVA(const char *format=0,...)
TPyDispatcher(PyObject *callable)
int Int_t
Definition: RtypesCore.h:41
Double_t x[n]
Definition: legend1.C:17
TObject & operator=(const TObject &rhs)
TObject assignment operator.
Definition: TObject.h:268
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:49
A doubly linked list.
Definition: TList.h:44
PyObject * Dispatch()
Definition: TPyDispatcher.h:65
The most important graphics class in the ROOT system.
Definition: TPad.h:29
const Bool_t kFALSE
Definition: RtypesCore.h:88
#define ClassImp(name)
Definition: Rtypes.h:365
TCppScope_t GetScope(const std::string &scope_name)
Definition: Cppyy.cxx:197
Double_t y[n]
Definition: legend1.C:17
Mother of all ROOT objects.
Definition: TObject.h:37
static constexpr double pi
PyObject * DispatchVA1(const char *clname, void *obj, const char *format,...)
~TPyDispatcher()
Destructor. Reference counting for the held python object is in effect.
Class describing a PROOF worker server.
Definition: TSlave.h:46
PyObject * BindCppObject(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, Bool_t isRef=kFALSE)
if the object is a null pointer, return a typed one (as needed for overloading)
PyObject * fCallable
char name[80]
Definition: TGX11.cxx:109
_object PyObject
Definition: TPyArg.h:20