00001 // Author: Wim Lavrijsen, Aug 2007 00002 00003 // Bindings 00004 #include "PyROOT.h" 00005 #include "TPyDispatcher.h" 00006 00007 // ROOT 00008 #include "TObject.h" 00009 00010 // Standard 00011 #include <stdarg.h> 00012 00013 00014 //______________________________________________________________________________ 00015 // Python callback dispatcher 00016 // ========================== 00017 // 00018 // The TPyDispatcher class acts as a functor that can be used for TFn's and GUIs 00019 // to install callbacks from CINT. 00020 00021 00022 //- data --------------------------------------------------------------------- 00023 ClassImp(TPyDispatcher) 00024 00025 00026 //- constructors/destructor -------------------------------------------------- 00027 TPyDispatcher::TPyDispatcher( PyObject* callable ) : fCallable( 0 ) 00028 { 00029 // Construct a TPyDispatcher from a callable python object. Applies python 00030 // object reference counting. 00031 Py_XINCREF( callable ); 00032 fCallable = callable; 00033 } 00034 00035 //____________________________________________________________________________ 00036 TPyDispatcher::TPyDispatcher( const TPyDispatcher& other ) : TObject ( other ) 00037 { 00038 // Copy constructor. Applies python object reference counting. 00039 Py_XINCREF( other.fCallable ); 00040 fCallable = other.fCallable; 00041 } 00042 00043 //____________________________________________________________________________ 00044 TPyDispatcher& TPyDispatcher::operator=( const TPyDispatcher& other ) 00045 { 00046 // Assignment operator. Applies python object reference counting. 00047 if ( this != &other ) { 00048 this->TObject::operator=( other ); 00049 00050 Py_XDECREF( fCallable ); 00051 Py_XINCREF( other.fCallable ); 00052 fCallable = other.fCallable; 00053 } 00054 00055 return *this; 00056 } 00057 00058 //____________________________________________________________________________ 00059 TPyDispatcher::~TPyDispatcher() { 00060 // Destructor. Reference counting for the held python object is in effect. 00061 Py_XDECREF( fCallable ); 00062 } 00063 00064 00065 //- public members ----------------------------------------------------------- 00066 PyObject* TPyDispatcher::DispatchVA( const char* format, ... ) 00067 { 00068 // Dispatch the arguments to the held callable python object, using format to 00069 // interpret the types of the arguments. Note that format is in python style, 00070 // not in C printf style. See: http://docs.python.org/api/arg-parsing.html . 00071 PyObject* args = 0; 00072 00073 if ( format ) { 00074 va_list va; 00075 va_start( va, format ); 00076 00077 args = Py_VaBuildValue( (char*)format, va ); 00078 00079 va_end( va ); 00080 00081 if ( ! args ) { 00082 PyErr_Print(); 00083 return 0; 00084 } 00085 00086 if ( ! PyTuple_Check( args ) ) { // if only one arg ... 00087 PyObject* t = PyTuple_New( 1 ); 00088 PyTuple_SET_ITEM( t, 0, args ); 00089 args = t; 00090 } 00091 00092 } 00093 00094 PyObject* result = PyObject_CallObject( fCallable, args ); 00095 Py_XDECREF( args ); 00096 00097 if ( ! result ) { 00098 PyErr_Print(); 00099 return 0; 00100 } 00101 00102 return result; 00103 }