Logo ROOT   6.16/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 --------------------------------------------------
29TPyDispatcher::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 -----------------------------------------------------------
71PyObject* 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
112PyObject* 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
169PyObject* 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
249PyObject* 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}
#define PyBytes_FromString
Definition: PyROOT.h:71
int Int_t
Definition: RtypesCore.h:41
const Bool_t kFALSE
Definition: RtypesCore.h:88
#define ClassImp(name)
Definition: Rtypes.h:363
_object PyObject
Definition: TPyArg.h:20
A doubly linked list.
Definition: TList.h:44
Mother of all ROOT objects.
Definition: TObject.h:37
TObject & operator=(const TObject &rhs)
TObject assignment operator.
Definition: TObject.h:271
The most important graphics class in the ROOT system.
Definition: TPad.h:29
TPyDispatcher & operator=(const TPyDispatcher &)
Assignment operator. Applies python object reference counting.
PyObject * DispatchVA1(const char *clname, void *obj, const char *format,...)
~TPyDispatcher()
Destructor. Reference counting for the held python object is in effect.
TPyDispatcher(PyObject *callable)
PyObject * Dispatch()
Definition: TPyDispatcher.h:65
PyObject * fCallable
PyObject * DispatchVA(const char *format=0,...)
Class describing a PROOF worker server.
Definition: TSlave.h:46
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:50
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
TCppScope_t GetScope(const std::string &scope_name)
Definition: Cppyy.cxx:193
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)
static constexpr double pi