Salome HOME
NRI : Merge from V1_2.
[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 += "    print 'PyObjRef orb',orb\n" ;
49   aPyFunc += "    objref = orb.string_to_object( IORObjStr )\n" ;
50   aPyFunc += "    print 'PyObjRef IORObjStr objref',IORObjStr,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',orb\n" ;
67   aPyFunc += "    objIor = orb.object_to_string( ObjRef )\n" ;
68   aPyFunc += "    print 'PyObjIor ObjRef objIor',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 << ThreadNo() << "GraphExecutor::InNode::PyDynInvoke " << method << " " << n_in
154             << " InArgs " << n_out << " OutArgs" << endl ;
155
156   CORBA::Any data ;
157
158   PyObject * ArgsList = NULL ;
159   PyObject * ArgValue = NULL ;
160   PyObject * ArgResult = NULL ;
161   PyObject * Result = NULL ;
162   PyObject * MyPyObjRefList = NULL ;
163   PyObject * ResultObj = NULL ;
164   PyObject * MyPyObjIorList = NULL ;
165   PyObject * ResultIor = NULL ;
166
167   ArgsList = PyTuple_New( n_in ) ;
168   CORBA::Object_ptr ObjRef ;
169   char * IORObjRef ;
170
171   for ( i = 0 ; i < n_in ; i++ ) {
172     data = inParams[i].Value ;
173     sname = inParams[i].Name.c_str() ;
174     switch ( data.type()->kind() ) {
175     case CORBA::tk_string : {
176       char * t ;
177       data >>= t ;
178       ArgValue = Py_BuildValue( "s" , t ) ;
179       PyTuple_SetItem( ArgsList , i , ArgValue ) ;
180       cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << t << " (string) "
181              << ArgsList->ob_refcnt << endl ;
182       break ;
183     }
184     case CORBA::tk_double : {
185       double d ;
186       data >>= d ;
187       ArgValue = Py_BuildValue( "d" , d ) ;
188       PyTuple_SetItem( ArgsList , i , ArgValue ) ;
189       cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << d << " (double) " 
190              << ArgsList->ob_refcnt << endl ;
191       break ;
192     }
193     case CORBA::tk_long : {
194       long l ;
195       data >>= l ;
196       ArgValue = Py_BuildValue( "l" , l ) ;
197       PyTuple_SetItem( ArgsList , i , ArgValue ) ;
198       cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << l
199              << " (long) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << endl ;
200       break ;
201     }
202     case CORBA::tk_objref : {
203       MyPyObjRefList = PyTuple_New( 1 ) ;
204       PyObject * ObjValue ;
205       data >>= ObjRef ;
206       IORObjRef = ObjectToString( ObjRef ) ;
207       ObjValue = Py_BuildValue( "s" , IORObjRef ) ;
208       PyTuple_SetItem( MyPyObjRefList , 0 , ObjValue ) ;
209       cdebug << "ArgIn" << i << " : " << sname << method << " " << " Value " << IORObjRef << " (objref) "
210              << MyPyObjRefList->ob_refcnt << endl ;
211       ResultObj = PyEval_CallObject( MyPyObjRef , MyPyObjRefList ) ;
212       cdebug << "MyPyObjRefList->ob_refcnt" << MyPyObjRefList->ob_refcnt << " "
213              << "ResultObj->ob_refcnt" << ResultObj->ob_refcnt << endl ;
214       PyObject_Print( ResultObj , stdout , 0 ) ;
215       PyTuple_SetItem( ArgsList , i , ResultObj ) ;
216       cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value  (objref) ArgsList->ob_refcnt"
217              << ArgsList->ob_refcnt << " ResultObj->ob_refcnt" << ResultObj->ob_refcnt
218              << endl ;
219       break ;
220     }
221     default : {
222       cdebug << "ArgIn" << i << " : " << sname << " Value " << "(other ERROR)" << endl ;
223     }
224     }
225   }
226
227   Result = PyEval_CallObject( MyPyRunMethod , ArgsList ) ;
228   cdebug << "ArgsList->ob_refcnt" << ArgsList->ob_refcnt << endl ;
229
230   if ( Result == NULL ) {
231     cdebug_out << "GraphExecutor::InNode::PyDynInvoke Error Result == NULL" << endl ;
232     RetVal = false ;
233   }
234   else {
235     for ( i = 0 ; i < n_out ; i++ ) {
236       data = outParams[i].Value ;
237       sname = outParams[i].Name.c_str() ;
238       switch ( data.type()->kind() ) {
239       case CORBA::tk_string : {
240         char * t ;
241         ArgValue = PyTuple_GetItem( Result , i ) ;
242         if ( ArgValue == NULL ) {
243           ArgValue = Result ;
244         }
245         if ( !PyString_Check( ArgValue ) ) {
246           cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (string)" << endl ;
247         }
248         t = PyString_AsString( ArgValue ) ;
249         data <<= t ;
250         cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << t << " (string)"
251                << endl ;
252         break ;
253       }
254       case CORBA::tk_double : {
255         double d ;
256         ArgValue = PyTuple_GetItem( Result , i ) ;
257         if ( !PyFloat_Check( ArgValue ) ) {
258           cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (double)" << endl ;
259         }
260         if ( ArgValue == NULL ) {
261           ArgValue = Result ;
262         }
263         d = PyFloat_AsDouble( ArgValue ) ;
264         data <<= d ;
265         cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << d << " (double)"
266                << endl ;
267         break ;
268       }
269       case CORBA::tk_long : {
270         long l ;
271         ArgValue = PyTuple_GetItem( Result , i ) ;
272         if ( ArgValue == NULL ) {
273           ArgValue = Result ;
274         }
275         if ( !PyInt_Check( ArgValue ) ) {
276           cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (long)" << endl ;
277         }
278         l = PyInt_AsLong( ArgValue ) ;
279         data <<= l ;
280         cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << l << " (long)" << endl ;
281         break ;
282       }
283       case CORBA::tk_objref : {
284         MyPyObjIorList = PyTuple_New( 1 ) ;
285         PyObject * ObjIor = PyTuple_GetItem( Result , i ) ;
286         if ( ObjIor == NULL ) {
287           ObjIor = Result ;
288         }
289         cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << "(object reference) "<< endl ;
290         cout << "ArgOut" << i << " : " << sname << " " << method << " Value " << "(object reference) : " ;
291         Py_INCREF( ObjIor ) ;
292         PyObject_Print( ObjIor , stdout , 0 ) ;
293         PyTuple_SetItem( MyPyObjIorList , 0 , ObjIor ) ;
294         Py_DECREF( ObjIor ) ;
295         ResultIor = PyEval_CallObject( MyPyObjIor , MyPyObjIorList ) ;
296 //        ObjRef = PyCObject_AsVoidPtr( ArgValue ) ;
297 //        ObjRef = (CORBA::Object_ptr ) PyLong_AsVoidPtr( ArgValue ) ;
298         char * IOR = NULL ;
299 //        ArgValue = PyTuple_GetItem( Result , i ) ;
300         if ( ResultIor ) {
301           IOR = PyString_AsString( ResultIor ) ;
302           ObjRef = StringToObject( IOR ) ;
303           data <<= ObjRef ;
304           IORObjRef = ObjectToString( ObjRef ) ;
305           cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << "(object reference) "
306                  << IORObjRef << endl ;
307         }
308         else {
309           cdebug_out << "GraphExecutor::InNode::PyDynInvoke Error ResultIor == NULL"
310                      << method << " " << endl ;
311           RetVal = false ;
312         }
313         break ;
314       }
315       default : {
316         cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << "(other ERROR)" << endl ;
317       }
318       }
319       outParams[i].Value = data ;
320     }
321
322     if ( MyPyObjIorList ) {
323       int cnt = MyPyObjIorList->ob_refcnt ;
324       while ( cnt > 0 ) {
325         cnt = MyPyObjIorList->ob_refcnt - 1 ;
326         Py_DECREF( MyPyObjIorList ) ;
327         cdebug << "MyPyObjIorList->ob_refcnt" << MyPyObjIorList->ob_refcnt << endl ;
328       }
329     }
330     if ( ResultIor ) {
331       int cnt = ResultIor->ob_refcnt ;
332       while ( cnt > 0 ) {
333         cnt = ResultIor->ob_refcnt - 1 ;
334         Py_DECREF( ResultIor ) ;
335         cdebug << "ResultIor->ob_refcnt" << ResultIor->ob_refcnt << endl ;
336       }
337     }
338     Py_DECREF( Result ) ;
339   }
340
341   Py_DECREF( ArgsList ) ;
342   if ( MyPyObjRefList ) {
343     int cnt = MyPyObjRefList->ob_refcnt ;
344     while ( cnt > 0 ) {
345       cnt = MyPyObjRefList->ob_refcnt - 1 ;
346       Py_DECREF( MyPyObjRefList ) ;
347       cdebug << "MyPyObjRefList->ob_refcnt" << MyPyObjRefList->ob_refcnt << endl ;
348     }
349   }
350   if ( ResultObj ) {
351     int cnt = ResultObj->ob_refcnt ;
352     while ( cnt > 0 ) {
353       cnt = ResultObj->ob_refcnt - 1 ;
354       Py_DECREF( ResultObj ) ;
355       cdebug << "ResultObj->ob_refcnt" << ResultObj->ob_refcnt << endl ;
356     }
357   }
358
359   cdebug_out << "GraphExecutor::InNode::PyDynInvoke " << method << endl ;
360
361   return RetVal ;
362
363 }