]> SALOME platform Git repositories - modules/yacs.git/blob - src/runtime/SalomePythonNode.cxx
Salome HOME
mergefrom branch BR_V511_PR tag mergeto_trunk_03feb09
[modules/yacs.git] / src / runtime / SalomePythonNode.cxx
1 //  Copyright (C) 2006-2008  CEA/DEN, EDF R&D
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #include "RuntimeSALOME.hxx"
20 #include "SalomePythonComponent.hxx"
21 #include "SalomePythonNode.hxx"
22 #include "PythonNode.hxx"
23 #include "PythonPorts.hxx"
24 #include "CORBANode.hxx"
25 #include "TypeCode.hxx"
26
27 #include <iostream>
28 #include <sstream>
29
30 using namespace YACS::ENGINE;
31 using namespace std;
32
33 const char SalomePythonNode::PLACEMENT_VAR_NAME_IN_INTERP[]="__container__from__YACS__";
34
35 SalomePythonNode::SalomePythonNode(const SalomePythonNode& other, ComposedNode *father):ServiceInlineNode(other,father),_pyfunc(0),_context(0)
36 {
37   //Not a bug : just because port point of view this is like PythonNode.
38   _implementation = PythonNode::IMPL_NAME;
39   PyGILState_STATE gstate = PyGILState_Ensure();
40   _context=PyDict_New();
41   if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
42     {
43       stringstream msg;
44       msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__;
45       PyGILState_Release(gstate);
46       throw Exception(msg.str());
47     }
48   PyGILState_Release(gstate);
49 }
50
51 SalomePythonNode::SalomePythonNode(const std::string& name): ServiceInlineNode(name),_pyfunc(0)
52 {
53
54   //Not a bug : just because port point of view this is like PythonNode.
55   _implementation = PythonNode::IMPL_NAME;
56   PyGILState_STATE gstate = PyGILState_Ensure();
57   _context=PyDict_New();
58   if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
59     {
60       stringstream msg;
61       msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__;
62       PyGILState_Release(gstate);
63       throw Exception(msg.str());
64     }
65   PyGILState_Release(gstate);
66 }
67
68 void SalomePythonNode::load()
69 {
70   ServiceInlineNode::load();
71   cerr << "---------------SalomePythonNode::load function---------------" << endl;
72   list<OutputPort *>::iterator iter;
73   string value2Export=((SalomePythonComponent*)_component)->getStringValueToExportInInterp();
74   PyObject* ob=PyString_FromString(value2Export.c_str());
75   PyDict_SetItemString(_context,PLACEMENT_VAR_NAME_IN_INTERP,ob);
76   for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
77     {
78       OutputPyPort *p=(OutputPyPort *)*iter;
79       cerr << "port name: " << p->getName() << endl;
80       cerr << "port kind: " << p->edGetType()->kind() << endl;
81     }
82   cerr <<  _script << endl;
83   PyGILState_STATE gstate = PyGILState_Ensure();
84   PyObject *res=PyRun_String(_script.c_str(),Py_file_input,_context,_context);
85   if(res == NULL)
86     {
87       PyErr_Print();
88       PyGILState_Release(gstate);
89       throw Exception("Error during execution");
90       return;
91     }
92   Py_DECREF(res);
93   _pyfunc=PyDict_GetItemString(_context,_method.c_str());
94   if(_pyfunc == NULL)
95     {
96       PyErr_Print();
97       PyGILState_Release(gstate);
98       throw Exception("Error during execution");
99     }
100   cerr << "---------------End SalomePythonNode::load function---------------" << endl;
101   PyGILState_Release(gstate);
102 }
103
104 void SalomePythonNode::execute()
105 {
106   cerr << "++++++++++++++ SalomePythonNode::execute: " << getName() << " ++++++++++++++++++++" << endl;
107   int pos=0;
108   PyObject* ob;
109   if(!_pyfunc)throw Exception("SalomePythonNode badly loaded");
110   PyGILState_STATE gstate = PyGILState_Ensure();
111   
112   cerr << "---------------SalomePythonNode::inputs---------------" << endl;
113   PyObject* args = PyTuple_New(getNumberOfInputPorts()) ;
114   list<InputPort *>::iterator iter2;
115   for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
116     {
117       InputPyPort *p=(InputPyPort *)*iter2;
118       cerr << "port name: " << p->getName() << endl;
119       cerr << "port kind: " << p->edGetType()->kind() << endl;
120       ob=p->getPyObj();
121       PyObject_Print(ob,stderr,Py_PRINT_RAW);
122       cerr << endl;
123       cerr << "ob refcnt: " << ob->ob_refcnt << endl;
124       Py_INCREF(ob);
125       PyTuple_SetItem(args,pos,ob);
126       cerr << "ob refcnt: " << ob->ob_refcnt << endl;
127       pos++;
128     }
129   cerr << "---------------End SalomePythonNode::inputs---------------" << endl;
130
131   cerr << "----------------SalomePythonNode::calculation---------------" << endl;
132   PyObject_Print(_pyfunc,stderr,Py_PRINT_RAW);
133   cerr << endl;
134   PyObject_Print(args,stderr,Py_PRINT_RAW);
135   cerr << endl;
136   PyObject* result = PyObject_CallObject( _pyfunc , args ) ;
137   Py_DECREF(args);
138   if(result == NULL)
139     {
140       PyErr_Print();
141       PyGILState_Release(gstate);
142       throw Exception("Error during execution");
143     }
144   cerr << "----------------End SalomePythonNode::calculation---------------" << endl;
145
146   cerr << "-----------------SalomePythonNode::outputs-----------------" << endl;
147   int nres=1;
148   if(result == Py_None)
149     nres=0;
150   else if(PyTuple_Check(result))
151     nres=PyTuple_Size(result);
152
153   if(getNumberOfOutputPorts() != nres)
154     {
155       Py_DECREF(result);
156       PyGILState_Release(gstate);
157       throw Exception("Number of output arguments : Mismatch between definition and execution");
158     }
159
160   pos=0;
161   PyObject_Print(result,stderr,Py_PRINT_RAW);
162   cerr << endl;
163   list<OutputPort *>::iterator iter;
164   try
165     {
166       for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
167         {
168           OutputPyPort *p=(OutputPyPort *)*iter;
169           cerr << "port name: " << p->getName() << endl;
170           cerr << "port kind: " << p->edGetType()->kind() << endl;
171           cerr << "port pos : " << pos << endl;
172           if(PyTuple_Check(result))ob=PyTuple_GetItem(result,pos) ;
173           else ob=result;
174           cerr << "ob refcnt: " << ob->ob_refcnt << endl;
175           PyObject_Print(ob,stderr,Py_PRINT_RAW);
176           cerr << endl;
177           p->put(ob);
178           pos++;
179         }
180     }
181   catch(ConversionException)
182     {
183       Py_DECREF(result);
184       PyGILState_Release(gstate);
185       throw;
186     }
187   cerr << "-----------------End SalomePythonNode::outputs-----------------" << endl;
188
189   Py_DECREF(result);
190   PyGILState_Release(gstate);
191   cerr << "++++++++++++++ End SalomePythonNode::execute: " << getName() << " ++++++++++++++++++++" << endl;
192 }
193
194 std::string SalomePythonNode::getKind() const
195 {
196   //This not a bug !!! Returns SalomeNode::KIND to be managed by SalomeContainer.
197   return SalomeNode::KIND;
198 }
199
200 Node *SalomePythonNode::simpleClone(ComposedNode *father, bool editionOnly) const
201 {
202   return new SalomePythonNode(*this,father);
203 }
204
205 ServiceNode *SalomePythonNode::createNode(const std::string &name)
206 {
207   ServiceNode* node=new SalomePythonNode(name);
208   node->setComponent(_component);
209   return node;
210 }
211
212 //! Create a new node of same type with a given name
213 SalomePythonNode* SalomePythonNode::cloneNode(const std::string& name)
214 {
215   SalomePythonNode* n=new SalomePythonNode(name);
216   n->setScript(_script);
217   n->setMethod(_method);
218   list<InputPort *>::iterator iter;
219   for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++)
220     {
221       InputPyPort *p=(InputPyPort *)*iter;
222       n->edAddInputPort(p->getName(),p->edGetType());
223     }
224   list<OutputPort *>::iterator iter2;
225   for(iter2 = _setOfOutputPort.begin(); iter2 != _setOfOutputPort.end(); iter2++)
226     {
227       OutputPyPort *p=(OutputPyPort *)*iter2;
228       n->edAddOutputPort(p->getName(),p->edGetType());
229     }
230   return n;
231 }