ROOT logo
// Author: Wim Lavrijsen, Aug 2007

// Bindings
#include "PyROOT.h"
#include "TPyDispatcher.h"

// ROOT
#include "TObject.h"

// Standard
#include <stdarg.h>


//______________________________________________________________________________
//                         Python callback dispatcher
//                         ==========================
//
// The TPyDispatcher class acts as a functor that can be used for TFn's and GUIs
// to install callbacks from CINT.


//- data ---------------------------------------------------------------------
ClassImp(TPyDispatcher)


//- constructors/destructor --------------------------------------------------
TPyDispatcher::TPyDispatcher( PyObject* callable ) : fCallable( 0 )
{
// Construct a TPyDispatcher from a callable python object. Applies python
// object reference counting.
   Py_XINCREF( callable );
   fCallable = callable;
}

//____________________________________________________________________________
TPyDispatcher::TPyDispatcher( const TPyDispatcher& other ) : TObject ( other )
{
// Copy constructor. Applies python object reference counting.
   Py_XINCREF( other.fCallable );
   fCallable = other.fCallable;
}

//____________________________________________________________________________
TPyDispatcher& TPyDispatcher::operator=( const TPyDispatcher& other )
{
// Assignment operator. Applies python object reference counting.
   if ( this != &other ) {
      this->TObject::operator=( other );

      Py_XDECREF( fCallable );
      Py_XINCREF( other.fCallable );
      fCallable = other.fCallable;
   }

   return *this;
}

//____________________________________________________________________________
TPyDispatcher::~TPyDispatcher() {
// Destructor. Reference counting for the held python object is in effect.
   Py_XDECREF( fCallable );
}


//- public members -----------------------------------------------------------
PyObject* TPyDispatcher::DispatchVA( const char* format, ... )
{
// Dispatch the arguments to the held callable python object, using format to
// interpret the types of the arguments. Note that format is in python style,
// not in C printf style. See: http://docs.python.org/api/arg-parsing.html .
   PyObject* args = 0;

   if ( format ) {
      va_list va;
      va_start( va, format );

      args = Py_VaBuildValue( (char*)format, va );

      va_end( va );

      if ( ! args ) {
         PyErr_Print();
         return 0;
      }

      if ( ! PyTuple_Check( args ) ) {    // if only one arg ...
         PyObject* t = PyTuple_New( 1 );
         PyTuple_SET_ITEM( t, 0, args );
         args = t;
      }

   }

   PyObject* result = PyObject_CallObject( fCallable, args );
   Py_XDECREF( args );

   if ( ! result ) {
      PyErr_Print();
      return 0;
   }

   return result;
}
 TPyDispatcher.cxx:1
 TPyDispatcher.cxx:2
 TPyDispatcher.cxx:3
 TPyDispatcher.cxx:4
 TPyDispatcher.cxx:5
 TPyDispatcher.cxx:6
 TPyDispatcher.cxx:7
 TPyDispatcher.cxx:8
 TPyDispatcher.cxx:9
 TPyDispatcher.cxx:10
 TPyDispatcher.cxx:11
 TPyDispatcher.cxx:12
 TPyDispatcher.cxx:13
 TPyDispatcher.cxx:14
 TPyDispatcher.cxx:15
 TPyDispatcher.cxx:16
 TPyDispatcher.cxx:17
 TPyDispatcher.cxx:18
 TPyDispatcher.cxx:19
 TPyDispatcher.cxx:20
 TPyDispatcher.cxx:21
 TPyDispatcher.cxx:22
 TPyDispatcher.cxx:23
 TPyDispatcher.cxx:24
 TPyDispatcher.cxx:25
 TPyDispatcher.cxx:26
 TPyDispatcher.cxx:27
 TPyDispatcher.cxx:28
 TPyDispatcher.cxx:29
 TPyDispatcher.cxx:30
 TPyDispatcher.cxx:31
 TPyDispatcher.cxx:32
 TPyDispatcher.cxx:33
 TPyDispatcher.cxx:34
 TPyDispatcher.cxx:35
 TPyDispatcher.cxx:36
 TPyDispatcher.cxx:37
 TPyDispatcher.cxx:38
 TPyDispatcher.cxx:39
 TPyDispatcher.cxx:40
 TPyDispatcher.cxx:41
 TPyDispatcher.cxx:42
 TPyDispatcher.cxx:43
 TPyDispatcher.cxx:44
 TPyDispatcher.cxx:45
 TPyDispatcher.cxx:46
 TPyDispatcher.cxx:47
 TPyDispatcher.cxx:48
 TPyDispatcher.cxx:49
 TPyDispatcher.cxx:50
 TPyDispatcher.cxx:51
 TPyDispatcher.cxx:52
 TPyDispatcher.cxx:53
 TPyDispatcher.cxx:54
 TPyDispatcher.cxx:55
 TPyDispatcher.cxx:56
 TPyDispatcher.cxx:57
 TPyDispatcher.cxx:58
 TPyDispatcher.cxx:59
 TPyDispatcher.cxx:60
 TPyDispatcher.cxx:61
 TPyDispatcher.cxx:62
 TPyDispatcher.cxx:63
 TPyDispatcher.cxx:64
 TPyDispatcher.cxx:65
 TPyDispatcher.cxx:66
 TPyDispatcher.cxx:67
 TPyDispatcher.cxx:68
 TPyDispatcher.cxx:69
 TPyDispatcher.cxx:70
 TPyDispatcher.cxx:71
 TPyDispatcher.cxx:72
 TPyDispatcher.cxx:73
 TPyDispatcher.cxx:74
 TPyDispatcher.cxx:75
 TPyDispatcher.cxx:76
 TPyDispatcher.cxx:77
 TPyDispatcher.cxx:78
 TPyDispatcher.cxx:79
 TPyDispatcher.cxx:80
 TPyDispatcher.cxx:81
 TPyDispatcher.cxx:82
 TPyDispatcher.cxx:83
 TPyDispatcher.cxx:84
 TPyDispatcher.cxx:85
 TPyDispatcher.cxx:86
 TPyDispatcher.cxx:87
 TPyDispatcher.cxx:88
 TPyDispatcher.cxx:89
 TPyDispatcher.cxx:90
 TPyDispatcher.cxx:91
 TPyDispatcher.cxx:92
 TPyDispatcher.cxx:93
 TPyDispatcher.cxx:94
 TPyDispatcher.cxx:95
 TPyDispatcher.cxx:96
 TPyDispatcher.cxx:97
 TPyDispatcher.cxx:98
 TPyDispatcher.cxx:99
 TPyDispatcher.cxx:100
 TPyDispatcher.cxx:101
 TPyDispatcher.cxx:102
 TPyDispatcher.cxx:103