1 // Copyright (C) 2006-2016 CEA/DEN, EDF R&D
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, or (at your option) any later version.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "PythonPorts.hxx"
21 #include "TypeConversions.hxx"
22 #include "TypeCode.hxx"
24 #include "ConversionException.hxx"
30 #include "YacsTrace.hxx"
32 using namespace YACS::ENGINE;
35 void releasePyObj(PyObject* data)
37 DEBTRACE( "data refcnt: " << data->ob_refcnt );
38 if (PyObject_HasAttrString(data, (char*)"_is_a"))
40 PyObject *result = PyObject_CallMethod(data, (char*)"_is_a", (char*)"s",(char*)"IDL:SALOME/GenericObj:1.0");
41 if(result && PyLong_Check(result))
43 if(PyLong_AS_LONG(result))
45 PyObject* o=PyObject_CallMethod(data, (char*)"Destroy", (char*)"");
55 throw ConversionException("Corba object does not exist: you have perhaps forgotten to call Register on a GenericObj");
67 throw ConversionException("Corba object does not exist: you have perhaps forgotten to call Register on a GenericObj");
72 void registerPyObj(PyObject* data)
74 if (PyObject_HasAttrString(data, (char*)"_is_a"))
76 PyObject *result = PyObject_CallMethod(data, (char*)"_is_a", (char*)"s",(char*)"IDL:SALOME/GenericObj:1.0");
77 if(result && PyLong_Check(result))
79 if(PyLong_AS_LONG(result))
81 PyObject* o= PyObject_CallMethod(data, (char*)"Register", (char*)"") ;
91 throw ConversionException("Corba object does not exist: you have perhaps forgotten to call Register on a GenericObj");
103 throw ConversionException("Corba object does not exist: you have perhaps forgotten to call Register on a GenericObj");
108 InputPyPort::InputPyPort(const std::string& name, Node *node, TypeCode * type)
109 : InputPort(name, node, type)
110 , DataPort(name, node, type)
117 Py_INCREF(_initData);
119 InputPyPort::~InputPyPort()
121 PyGILState_STATE gstate = PyGILState_Ensure();
122 DEBTRACE( "_data refcnt: " << _data->ob_refcnt );
123 DEBTRACE( "_initData refcnt: " << _initData->ob_refcnt );
124 // Release or not release : all GenericObj are deleted when the input port is deleted
127 Py_XDECREF(_initData);
128 PyGILState_Release(gstate);
131 InputPyPort::InputPyPort(const InputPyPort& other, Node *newHelder):InputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder)
133 _initData=other._initData;
134 Py_INCREF(_initData);
137 _isEmpty=other._isEmpty;
140 bool InputPyPort::edIsManuallyInitialized() const
142 return _initData!=Py_None;
145 void InputPyPort::edRemoveManInit()
147 Py_XDECREF(_initData);
149 Py_INCREF(_initData);
154 InputPort::edRemoveManInit();
157 void InputPyPort::put(const void *data) throw(ConversionException)
159 put((PyObject *)data);
162 void InputPyPort::put(PyObject *data) throw(ConversionException)
164 InterpreterUnlocker l;
170 registerPyObj(_data);
172 DEBTRACE( "_data refcnt: " << _data->ob_refcnt );
175 InputPort *InputPyPort::clone(Node *newHelder) const
177 return new InputPyPort(*this,newHelder);
180 PyObject * InputPyPort::getPyObj() const
185 void *InputPyPort::get() const throw(YACS::Exception)
187 return (void*) _data;
190 std::string InputPyPort::getAsString()
193 //protect _data against modification or delete in another thread
194 PyObject* data=_data;
196 ret = convertPyObjectToString(data);
201 std::string InputPyPort::getHumanRepr()
205 PyObject *ret(PyObject_Str(_data));
209 char *val(PyBytes_AsString(ret));
216 bool InputPyPort::isEmpty()
221 //! Save the current data value for further reinitialization of the port
225 void InputPyPort::exSaveInit()
227 // Interpreter lock seems necessary when deleting lists in Python 2.7
228 PyGILState_STATE gstate = PyGILState_Ensure();
229 Py_XDECREF(_initData);
230 PyGILState_Release(gstate);
232 Py_INCREF(_initData);
233 DEBTRACE( "_initData.ob refcnt: " << _initData->ob_refcnt );
234 DEBTRACE( "_data.ob refcnt: " << _data->ob_refcnt );
237 //! Restore the saved data value to current data value
239 * If no data has been saved (_initData == 0) don't restore
241 void InputPyPort::exRestoreInit()
243 if(!_initData)return;
248 DEBTRACE( "_initData.ob refcnt: " << _initData->ob_refcnt );
249 DEBTRACE( "_data.ob refcnt: " << _data->ob_refcnt );
252 std::string InputPyPort::dump()
254 if( _data == Py_None)
255 return "<value>None</value>";
257 InterpreterUnlocker l;
258 if (edGetType()->kind() != YACS::ENGINE::Objref)
259 return convertPyObjectXml(edGetType(), _data);
260 if (! _stringRef.empty())
263 return convertPyObjectXml(edGetType(), _data);
266 // msg << "Cannot retreive init reference string for port " << _name
267 // << " on node " << _node->getName();
268 // throw Exception(msg.str());
272 std::string InputPyPort::valToStr()
274 int isString = PyBytes_Check(getPyObj());
275 //DEBTRACE("isString=" << isString);
276 PyObject *strPyObj = PyObject_Str(getPyObj());
277 //DEBTRACE(PyString_Size(strPyObj));
278 string val = PyBytes_AsString(strPyObj);
280 val = "\"" + val + "\"";
286 void InputPyPort::valFromStr(std::string valstr)
291 OutputPyPort::OutputPyPort(const std::string& name, Node *node, TypeCode * type)
292 : OutputPort(name, node, type), DataPort(name, node, type), Port(node)
297 OutputPyPort::~OutputPyPort()
299 PyGILState_STATE gstate = PyGILState_Ensure();
300 DEBTRACE( "_data refcnt: " << _data->ob_refcnt );
301 // Release or not release : all GenericObj are deleted when the output port is deleted
304 PyGILState_Release(gstate);
307 OutputPyPort::OutputPyPort(const OutputPyPort& other, Node *newHelder):OutputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder),
313 void OutputPyPort::put(const void *data) throw(ConversionException)
315 put((PyObject *)data);
318 void OutputPyPort::put(PyObject *data) throw(ConversionException)
321 DEBTRACE( "OutputPyPort::put.ob refcnt: " << data->ob_refcnt );
323 PyObject_Print(data,stderr,Py_PRINT_RAW);
330 //no registerPyObj : we steal the output reference of the node
331 DEBTRACE( "OutputPyPort::put.ob refcnt: " << data->ob_refcnt );
332 OutputPort::put(data);
335 OutputPort *OutputPyPort::clone(Node *newHelder) const
337 return new OutputPyPort(*this,newHelder);
340 PyObject * OutputPyPort::get() const
345 PyObject * OutputPyPort::getPyObj() const
350 std::string OutputPyPort::getAsString()
353 //protect _data against modification or delete in another thread
354 PyObject* data=_data;
356 ret = convertPyObjectToString(data);
361 std::string OutputPyPort::dump()
363 if( _data == Py_None)
364 return "<value>None</value>";
365 InterpreterUnlocker l;
366 string xmldump = convertPyObjectXml(edGetType(), _data);
370 std::string OutputPyPort::valToStr()
372 PyObject *strPyObj = PyObject_Str(getPyObj());
373 string val = PyBytes_AsString(strPyObj);
378 void OutputPyPort::valFromStr(std::string valstr)