Salome HOME
31e0c0cf2a25ce9da5aa3a93e380f2c5867315fd
[modules/superv.git] / src / GraphExecutor / DataFlowExecutor_PyDynInvoke.cxx
1 using namespace std;
2 //=============================================================================
3 // File      : DataFlowExecutor_PyDynInvoke.cxx
4 // Created   : 2003
5 // Author    : Jean Rahuel, CEA
6 // Project   : SALOME
7 // $Header:
8 //=============================================================================
9
10 #include <stdarg.h>
11 #include <map>
12
13 #include "DataFlowExecutor_InNode.hxx"
14
15 using namespace CORBA ;
16
17 static PyObject * MyPyObjRef = NULL ;
18 static PyObject * MyPyObjIor = NULL ;
19 static PyObject * MyPyRunMethod = NULL ;
20
21 static PyMethodDef MethodPyRunMethod[] = {
22   { "RunMethod", PyRunMethod, METH_VARARGS },
23   { NULL,        NULL }
24 };
25
26 bool GraphExecutor::InNode::InitPython() {
27   cdebug_in << "InitPython" << endl ;
28
29   PyObject * Module = Py_InitModule( "InitPyRunMethod" , MethodPyRunMethod ) ;
30   PyObject * Dictionnary = PyModule_GetDict( Module ) ;
31 //  InitPyDynInvokeError = PyErr_NewException( "InitPyDynInvokeError" , NULL , NULL ) ;
32 //  PyDict_SetItemString( Dictionnary , InitPyDynInvokeError ) ;
33   cdebug << ThreadNo() << "Py_Initialized() " << endl ;
34
35   string aPyFunc ;
36   aPyFunc = "print 'InitPyRunMethod'\n" ;
37   aPyFunc += "import InitPyRunMethod\n" ;
38   aPyFunc += "print 'sys'\n" ;
39   aPyFunc += "import sys\n" ;
40   aPyFunc += "print 'CORBA'\n" ;
41   aPyFunc += "import CORBA\n" ;
42   aPyFunc += "print 'omniORB'\n" ;
43   aPyFunc += "import omniORB\n" ;
44   aPyFunc += "print 'PyObjRef'\n" ;
45   aPyFunc += "def PyObjRef( IORObjStr ) :\n" ;
46 //  aPyFunc += "    print 'PyObjRef',IORObjStr\n" ;
47   aPyFunc += "    orb = CORBA.ORB_init( sys.argv , CORBA.ORB_ID )\n" ;
48   aPyFunc += "    objref = orb.string_to_object( IORObjStr )\n" ;
49 //  aPyFunc += "    print IORObjStr,objref\n" ;
50 //  aPyFunc += "    return objref,objref\n" ;
51   aPyFunc += "    return objref\n" ;
52   aPyFunc += "InitPyRunMethod.RunMethod( PyObjRef )\n" ;
53   if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
54     cdebug << ThreadNo() << " PyRun_SimpleString ERROR " << endl << aPyFunc << endl ;
55     return false ;
56   }
57   MyPyObjRef = MyPyRunMethod ;
58
59   aPyFunc = "import InitPyRunMethod\n" ;
60   aPyFunc += "import sys\n" ;
61   aPyFunc += "import CORBA\n" ;
62   aPyFunc += "import omniORB\n" ;
63   aPyFunc += "def PyObjIor( ObjRef ) :\n" ;
64 //  aPyFunc += "    print 'PyObjIor',ObjRef\n" ;
65   aPyFunc += "    orb = CORBA.ORB_init( sys.argv , CORBA.ORB_ID )\n" ;
66 //  aPyFunc += "    print 'PyObjIor',orb\n" ;
67   aPyFunc += "    objIor = orb.object_to_string( ObjRef )\n" ;
68 //  aPyFunc += "    print 'PyObjIor',ObjRef,objIor\n" ;
69   aPyFunc += "    return objIor\n" ;
70   aPyFunc += "InitPyRunMethod.RunMethod( PyObjIor )\n" ;
71   if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
72     cdebug << ThreadNo() << " PyRun_SimpleString ERROR " << endl << aPyFunc << endl ;
73     return false ;
74   }
75   MyPyObjIor = MyPyRunMethod ;
76
77   cdebug_out << "InitPython" << endl ;
78   return true ;
79 }
80
81 PyObject * GraphExecutor::InNode::InitPyDynInvoke(
82                                   char * PyFuncName ,
83                                   const SUPERV::ListOfStrings * aPythonFunction ) {
84   bool RetVal = true ;
85   string aPyFunc ;
86
87   cdebug_in << "InitPyDynInvoke '" << PyFuncName << "' length "
88             << (*aPythonFunction).length() << endl ;
89
90   if ( (*aPythonFunction).length() ) {
91     int i ;
92     aPyFunc += "import InitPyRunMethod\n" ;
93     for ( i = 0 ; i < (*aPythonFunction).length() ; i++ ) {
94       aPyFunc += (*aPythonFunction)[ i ] ;
95       aPyFunc += "\n" ;
96     }
97     aPyFunc += "InitPyRunMethod.RunMethod( " ;
98     aPyFunc += PyFuncName ;
99     aPyFunc += " )\n" ;
100     cdebug << "InitPyDynInvoke PyRun_SimpleString " << endl << aPyFunc << endl ;
101     if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
102       cdebug << ThreadNo() << " PyRun_SimpleString ERROR " << endl << aPyFunc << endl ;
103       RetVal = false ;
104     }
105     else {
106       PyFuncRunned( true ) ;
107 //      _MyPyRunMethod = MyPyRunMethod ; // To mutex
108       cdebug << ThreadNo() << "PyRun_SimpleString( " << (*aPythonFunction)[ 0 ]
109              << " )" << endl ;
110     }
111     cdebug_out << "InitPyDynInvoke" << endl ;
112     if ( RetVal ) {
113       return MyPyRunMethod ;
114     }
115   }
116
117   return NULL ;
118 }
119
120 extern "C" PyObject * PyRunMethod( PyObject * dummy , PyObject * Args ) {
121 //  cout << "PyRunMethod -->" << endl ;
122   PyObject * Result = NULL ;
123   PyObject * Temp = NULL ;
124   if ( PyArg_ParseTuple( Args , "O:set_callback" , & Temp ) ) {
125 //    cout << "PyArg_ParsedTuple" << endl ;
126     if ( !PyCallable_Check( Temp ) ) {
127 //      PyErr_SetString( PyExc_TypeError , "PyRunMethod must be callable" ) ;
128 //      cout << "PyRunMethod must be callable" << endl ;
129       return NULL ;
130     }
131     Py_XINCREF( Temp ) ;
132     Py_XDECREF( MyPyRunMethod ) ;
133     MyPyRunMethod = Temp ;
134     Py_INCREF( Py_None ) ;
135     Result = Py_None ;
136   }
137 //  cout << "<-- PyRunMethod" << endl ;
138   return Result ;
139 }
140
141 bool GraphExecutor::InNode::PyDynInvoke( PyObject * MyPyRunMethod ,
142                                          const char *method , 
143                                          ServicesAnyData * inParams , int nInParams ,
144                                          ServicesAnyData * outParams , int nOutParams ) {
145   int i ;
146
147   bool RetVal = true ;
148
149   int n_in  = nInParams ;
150   int n_out = nOutParams ;
151   const char * sname;
152
153   cdebug_in << "GraphExecutor::InNode::PyDynInvoke " << method << endl ;
154
155   CORBA::Any data ;
156
157   PyObject * ArgsList = NULL ;
158   PyObject * ArgValue ;
159   PyObject * ArgResult ;
160   PyObject * Result ;
161   PyObject * MyPyObjRefList = NULL ;
162   PyObject * ResultObj = NULL ;
163   PyObject * MyPyObjIorList = NULL ;
164   PyObject * ResultIor = NULL ;
165
166   ArgsList = PyTuple_New( n_in ) ;
167   CORBA::Object_ptr ObjRef ;
168   char * IORObjRef ;
169
170   for ( i = 0 ; i < n_in ; i++ ) {
171     data = inParams[i].Value ;
172     sname = inParams[i].Name.c_str() ;
173     switch ( data.type()->kind() ) {
174     case CORBA::tk_string : {
175       char * t ;
176       data >>= t ;
177       ArgValue = Py_BuildValue( "s" , t ) ;
178       PyTuple_SetItem( ArgsList , i , ArgValue ) ;
179       cdebug << "ArgIn" << i << " : " << sname << " Value " << t << " (string) "
180              << ArgsList->ob_refcnt << endl ;
181       break ;
182     }
183     case CORBA::tk_double : {
184       double d ;
185       data >>= d ;
186       ArgValue = Py_BuildValue( "d" , d ) ;
187       PyTuple_SetItem( ArgsList , i , ArgValue ) ;
188       cdebug << "ArgIn" << i << " : " << sname << " Value " << d << " (double) " 
189              << ArgsList->ob_refcnt << endl ;
190       break ;
191     }
192     case CORBA::tk_long : {
193       long l ;
194       data >>= l ;
195       ArgValue = Py_BuildValue( "l" , l ) ;
196       PyTuple_SetItem( ArgsList , i , ArgValue ) ;
197       cdebug << "ArgIn" << i << " : " << sname << " Value " << l
198              << " (long) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << endl ;
199       break ;
200     }
201     case CORBA::tk_objref : {
202       MyPyObjRefList = PyTuple_New( 1 ) ;
203       PyObject * ObjValue ;
204       data >>= ObjRef ;
205       IORObjRef = ObjectToString( ObjRef ) ;
206       ObjValue = Py_BuildValue( "s" , IORObjRef ) ;
207       PyTuple_SetItem( MyPyObjRefList , 0 , ObjValue ) ;
208       cdebug << "ArgIn" << i << " : " << sname << " Value " << IORObjRef << " (objref) "
209              << MyPyObjRefList->ob_refcnt << endl ;
210       ResultObj = PyEval_CallObject( MyPyObjRef , MyPyObjRefList ) ;
211       cdebug << "MyPyObjRefList->ob_refcnt" << MyPyObjRefList->ob_refcnt << " "
212              << "ResultObj->ob_refcnt" << ResultObj->ob_refcnt << endl ;
213       PyObject_Print( ResultObj , stdout , 0 ) ;
214       PyTuple_SetItem( ArgsList , i , ResultObj ) ;
215       cdebug << "ArgIn" << i << " : " << sname << " Value  (objref) ArgsList->ob_refcnt"
216              << ArgsList->ob_refcnt << " ResultObj->ob_refcnt" << ResultObj->ob_refcnt
217              << endl ;
218       break ;
219     }
220     default : {
221       cdebug << "ArgIn" << i << " : " << sname << " Value " << "(other ERROR)" << endl ;
222     }
223     }
224   }
225
226   Result = PyEval_CallObject( MyPyRunMethod , ArgsList ) ;
227   cdebug << "ArgsList->ob_refcnt" << ArgsList->ob_refcnt << endl ;
228
229   if ( Result == NULL ) {
230     cdebug_out << "GraphExecutor::InNode::PyDynInvoke Error Result == NULL" << endl ;
231     RetVal = false ;
232   }
233   else {
234     for ( i = 0 ; i < n_out ; i++ ) {
235       data = outParams[i].Value ;
236       sname = outParams[i].Name.c_str() ;
237       switch ( data.type()->kind() ) {
238       case CORBA::tk_string : {
239         char * t ;
240         ArgValue = PyTuple_GetItem( Result , i ) ;
241         if ( ArgValue == NULL ) {
242           ArgValue = Result ;
243         }
244         t = PyString_AsString( ArgValue ) ;
245         data <<= t ;
246         cdebug << "ArgOut" << i << " : " << sname << " Value " << t << " (string)"
247                << endl ;
248         break ;
249       }
250       case CORBA::tk_double : {
251         double d ;
252         ArgValue = PyTuple_GetItem( Result , i ) ;
253         if ( ArgValue == NULL ) {
254           ArgValue = Result ;
255         }
256         d = PyFloat_AsDouble( ArgValue ) ;
257         data <<= d ;
258         cdebug << "ArgOut" << i << " : " << sname << " Value " << d << " (double)"
259                << endl ;
260         break ;
261       }
262       case CORBA::tk_long : {
263         long l ;
264         ArgValue = PyTuple_GetItem( Result , i ) ;
265         if ( ArgValue == NULL ) {
266           ArgValue = Result ;
267         }
268         l = PyInt_AsLong( ArgValue ) ;
269         data <<= l ;
270         cdebug << "ArgOut" << i << " : " << sname << " Value " << l << " (long)" << endl ;
271         break ;
272       }
273       case CORBA::tk_objref : {
274         MyPyObjIorList = PyTuple_New( 1 ) ;
275         PyObject * ObjIor = PyTuple_GetItem( Result , i ) ;
276         if ( ObjIor == NULL ) {
277           ObjIor = Result ;
278         }
279         Py_INCREF( ObjIor ) ;
280         PyObject_Print( ObjIor , stdout , 0 ) ;
281         PyTuple_SetItem( MyPyObjIorList , 0 , ObjIor ) ;
282         Py_DECREF( ObjIor ) ;
283         ResultIor = PyEval_CallObject( MyPyObjIor , MyPyObjIorList ) ;
284 //        ObjRef = PyCObject_AsVoidPtr( ArgValue ) ;
285 //        ObjRef = (CORBA::Object_ptr ) PyLong_AsVoidPtr( ArgValue ) ;
286         char * IOR = NULL ;
287 //        ArgValue = PyTuple_GetItem( Result , i ) ;
288         if ( ResultIor ) {
289           IOR = PyString_AsString( ResultIor ) ;
290           ObjRef = StringToObject( IOR ) ;
291           data <<= ObjRef ;
292           IORObjRef = ObjectToString( ObjRef ) ;
293           cdebug << "ArgOut" << i << " : " << sname << " Value " << "(object reference) "
294                  << IORObjRef << endl ;
295         }
296         else {
297           cdebug_out << "GraphExecutor::InNode::PyDynInvoke Error ResultIor == NULL"
298                      << endl ;
299           RetVal = false ;
300         }
301         break ;
302       }
303       default : {
304         cdebug << "ArgOut" << i << " : " << sname << " Value " << "(other ERROR)" << endl ;
305       }
306       }
307       outParams[i].Value = data ;
308     }
309
310     if ( MyPyObjIorList ) {
311       int cnt = MyPyObjIorList->ob_refcnt ;
312       while ( cnt ) {
313         cnt = MyPyObjIorList->ob_refcnt - 1 ;
314         Py_DECREF( MyPyObjIorList ) ;
315         Py_DECREF( ResultIor ) ;
316         cdebug << "MyPyObjIorList->ob_refcnt" << MyPyObjIorList->ob_refcnt << " "
317                << "ResultIor->ob_refcnt" << ResultIor->ob_refcnt << endl ;
318       }
319     }
320     Py_DECREF( Result ) ;
321   }
322
323   Py_DECREF( ArgsList ) ;
324   if ( MyPyObjRefList ) {
325     int cnt = MyPyObjRefList->ob_refcnt ;
326     while ( cnt ) {
327       cnt = MyPyObjRefList->ob_refcnt - 1 ;
328       Py_DECREF( MyPyObjRefList ) ;
329       Py_DECREF( ResultObj ) ;
330       cdebug << "MyPyObjRefList->ob_refcnt" << MyPyObjRefList->ob_refcnt << " "
331              << "ResultObj->ob_refcnt" << ResultObj->ob_refcnt << endl ;
332     }
333   }
334
335   cdebug_out << "GraphExecutor::InNode::PyDynInvoke " << method << endl ;
336
337   return RetVal ;
338
339 }