+// Copyright (C) 2006-2015 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
//#define REFCNT
+//
#ifdef REFCNT
#define private public
#define protected public
#endif
#include "yacsconfig.h"
+#include "YACS_version.h"
#include "RuntimeSALOME.hxx"
#include "SALOMEDispatcher.hxx"
#include "Proc.hxx"
+#include "TypeCode.hxx"
#include "WhileLoop.hxx"
#include "ForLoop.hxx"
+#include "ForEachLoop.hxx"
+#include "SalomeOptimizerLoop.hxx"
#include "Bloc.hxx"
#include "InputPort.hxx"
#include "OutputPort.hxx"
+#include "PresetPorts.hxx"
#include "InputDataStreamPort.hxx"
#include "OutputDataStreamPort.hxx"
+#include "Switch.hxx"
#include "SalomeProc.hxx"
+#include "PyStdout.hxx"
+//Catalog Loaders
+#include "SessionCataLoader.hxx"
+
//Components
#include "CORBAComponent.hxx"
#include "SalomeComponent.hxx"
+#include "SalomeHPComponent.hxx"
#include "SalomePythonComponent.hxx"
#include "CppComponent.hxx"
#include "SalomeContainer.hxx"
#include "CppContainer.hxx"
+#include "SalomeHPContainer.hxx"
//Nodes
#include "PythonNode.hxx"
#include "CORBANode.hxx"
#include "XMLNode.hxx"
#include "CppNode.hxx"
-#include "TypeConversions.hxx"
+#include "PresetNode.hxx"
+#include "OutNode.hxx"
+#include "StudyNodes.hxx"
#include "SalomePythonNode.hxx"
+#include "DistributedPythonNode.hxx"
+
//CORBA proxy ports
#include "CORBACORBAConv.hxx"
#include "CORBAPythonConv.hxx"
#include "CORBACppConv.hxx"
#include "CORBANeutralConv.hxx"
+#include "TypeConversions.hxx"
//Python proxy ports
#include "PythonCORBAConv.hxx"
#include "PythonXMLConv.hxx"
#include "PythonCppConv.hxx"
#include "PythonNeutralConv.hxx"
+#include "PythonInitConv.hxx"
//Neutral proxy ports
#include "NeutralCORBAConv.hxx"
#include "NeutralPythonConv.hxx"
#include "NeutralXMLConv.hxx"
#include "NeutralCppConv.hxx"
+#include "NeutralInitConv.hxx"
//C++ proxy ports
#include "CppCORBAConv.hxx"
using namespace std;
using namespace YACS::ENGINE;
-void RuntimeSALOME::setRuntime(long flags) // singleton creation (not thread safe!)
+void RuntimeSALOME::setRuntime(long flags, int argc, char* argv[]) // singleton creation (not thread safe!)
{
if (! Runtime::_singleton)
{
- Runtime::_singleton = new RuntimeSALOME(flags);
+ RuntimeSALOME* r=new RuntimeSALOME(flags, argc, argv);
+ Runtime::_singleton = r;
+ r->initBuiltins();
}
DEBTRACE("RuntimeSALOME::setRuntime() done !");
}
RuntimeSALOME* YACS::ENGINE::getSALOMERuntime()
{
- assert(Runtime::_singleton);
+ YASSERT(Runtime::_singleton);
return dynamic_cast< RuntimeSALOME* >(Runtime::_singleton);
}
RuntimeSALOME::RuntimeSALOME()
{
- assert(0);
+ YASSERT(0);
}
-RuntimeSALOME::RuntimeSALOME(long flags)
+void RuntimeSALOME::initBuiltins()
+{
+ //Fill the builtin catalog with nodes specific to the runtime
+ std::map<std::string,TypeCode*>& typeMap=_builtinCatalog->_typeMap;
+ std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
+ std::map<std::string,ComposedNode*>& composednodeMap=_builtinCatalog->_composednodeMap;
+ std::map<std::string,ComponentDefinition*>& componentMap=_builtinCatalog->_componentMap;
+ nodeMap["PyFunction"]=new PyFuncNode("PyFunction");
+ nodeMap["PyScript"]=new PythonNode("PyScript");
+ nodeMap["CORBANode"]=new CORBANode("CORBANode");
+ nodeMap["XmlNode"]=new XmlNode("XmlNode");
+ nodeMap["SalomeNode"]=new SalomeNode("SalomeNode");
+ nodeMap["CppNode"]=new CppNode("CppNode");
+ nodeMap["SalomePythonNode"]=new SalomePythonNode("SalomePythonNode");
+ nodeMap["PresetNode"]=new PresetNode("PresetNode");
+ nodeMap["OutNode"]=new OutNode("OutNode");
+ nodeMap["StudyInNode"]=new StudyInNode("StudyInNode");
+ nodeMap["StudyOutNode"]=new StudyOutNode("StudyOutNode");
+ composednodeMap["OptimizerLoop"]=createOptimizerLoop("OptimizerLoop","","",true);
+ typeMap["dblevec"]= createSequenceTc("dblevec","dblevec",_tc_double);
+ typeMap["intvec"]= createSequenceTc("intvec","intvec",_tc_int);
+ typeMap["stringvec"]= createSequenceTc("stringvec","stringvec",_tc_string);
+ typeMap["boolvec"]= createSequenceTc("boolvec","boolvec",_tc_bool);
+ typeMap["seqdblevec"]= createSequenceTc("seqdblevec","seqdblevec",typeMap["dblevec"]);
+ typeMap["seqintvec"]= createSequenceTc("seqintvec","seqintvec",typeMap["intvec"]);
+ typeMap["seqstringvec"]= createSequenceTc("seqstringvec","seqstringvec",typeMap["stringvec"]);
+ typeMap["seqboolvec"]= createSequenceTc("seqboolvec","seqboolvec",typeMap["boolvec"]);
+ std::list<TypeCodeObjref *> ltc;
+ typeMap["pyobj"]= createInterfaceTc("python:obj:1.0","pyobj",ltc);
+ typeMap["seqpyobj"]= createSequenceTc("seqpyobj","seqpyobj",typeMap["pyobj"]);
+ composednodeMap["Bloc"]=createBloc("Bloc");
+ composednodeMap["Switch"]=createSwitch("Switch");
+ composednodeMap["WhileLoop"]=createWhileLoop("WhileLoop");
+ composednodeMap["ForLoop"]=createForLoop("ForLoop");
+ composednodeMap["ForEachLoop_double"]=createForEachLoop("ForEachLoop_double",Runtime::_tc_double);
+ composednodeMap["ForEachLoop_string"]=createForEachLoop("ForEachLoop_string",Runtime::_tc_string);
+ composednodeMap["ForEachLoop_int"]=createForEachLoop("ForEachLoop_int",Runtime::_tc_int);
+ composednodeMap["ForEachLoop_bool"]=createForEachLoop("ForEachLoop_bool",Runtime::_tc_bool);
+ composednodeMap["ForEachLoop_pyobj"]=createForEachLoop("ForEachLoop_pyobj",typeMap["pyobj"]);;
+ ENGINE::TypeCodeStruct *t = createStructTc("","Engines/dataref");
+ t->addMember("ref",_tc_string);
+ typeMap["dataref"]= t;
+}
+
+RuntimeSALOME::RuntimeSALOME(long flags, int argc, char* argv[])
{
// If all flags (apart the IsPyExt flags) are unset, force them to true
if ((flags - flags & RuntimeSALOME::IsPyExt) == 0)
_useCpp = flags & RuntimeSALOME::UseCpp;
_useXml = flags & RuntimeSALOME::UseXml;
+ /* Init libxml */
+ xmlInitParser();
+
if (_useCpp) _setOfImplementation.insert(CppNode::IMPL_NAME);
if (_usePython) _setOfImplementation.insert(PythonNode::IMPL_NAME);
if (_useCorba) _setOfImplementation.insert(CORBANode::IMPL_NAME);
if (_useXml) _setOfImplementation.insert(XmlNode::IMPL_NAME);
- init(flags);
+ init(flags, argc, argv);
}
RuntimeSALOME::~RuntimeSALOME()
{
+ DEBTRACE("RuntimeSALOME::~RuntimeSALOME");
+ // destroy catalog loader prototypes
+ std::map<std::string, CatalogLoader*>::const_iterator pt;
+ for(pt=_catalogLoaderFactoryMap.begin();pt!=_catalogLoaderFactoryMap.end();pt++)
+ {
+ delete (*pt).second;
+ }
}
//! CORBA and Python initialization
* bit1 (UseXml) true if python nodes are needed
* bit1 (UseCpp) true if C++ nodes are needed
* bit1 (UseSalome) true if Salome nodes are needed
+ * \param argc number of command line arguments (used to initialize the Python interpreter)
+ * \param argv command line arguments (used to initialize the Python interpreter)
*
*/
-void RuntimeSALOME::init(long flags)
+void RuntimeSALOME::init(long flags, int argc, char* argv[])
{
bool ispyext = flags & RuntimeSALOME::IsPyExt;
if (_useCorba)
{
+ PortableServer::POA_var root_poa;
+ PortableServer::POAManager_var pman;
+ CORBA::Object_var obj;
int nbargs = 0; char **args = 0;
_orb = CORBA::ORB_init (nbargs, args);
+ obj = _orb->resolve_initial_references("RootPOA");
+ root_poa = PortableServer::POA::_narrow(obj);
+ pman = root_poa->the_POAManager();
+ pman->activate();
+
#ifdef REFCNT
DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
#endif
- CORBA::Object_var obj = _orb->resolve_initial_references("DynAnyFactory");
+ obj = _orb->resolve_initial_references("DynAnyFactory");
_dynFactory = DynamicAny::DynAnyFactory::_narrow(obj);
}
// Initialize Python interpreter in embedded mode
if (!Py_IsInitialized())
{
+#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
+ Py_Initialize();
+#else
Py_InitializeEx(0); // do not install signal handlers
+#endif
+ if (argc > 0 && argv != NULL)
+ PySys_SetArgv(argc, argv);
+ else
+ {
+ int pyArgc = 1;
+ char* pyArgv[1];
+ char defaultName[] = "SALOME_YACS_RUNTIME";
+ pyArgv[0] = defaultName;
+ PySys_SetArgv(pyArgc, pyArgv);
+ }
PyEval_InitThreads(); /* Create (and acquire) the interpreter lock (for threads)*/
PyEval_SaveThread(); /* Release the thread state */
//here we do not have the Global Interpreter Lock
}
_bltins = PyEval_GetBuiltins(); /* borrowed ref */
-
+
if (_useCorba)
{
//init section
- PyObject* omnipy = PyImport_ImportModule((char*)"_omnipy");
- if (!omnipy)
+ _omnipy = PyImport_ImportModule((char*)"_omnipy");
+ if (!_omnipy)
{
PyErr_Print();
PyErr_SetString(PyExc_ImportError, (char*)"Cannot import _omnipy");
goto out;
}
- pyapi = PyObject_GetAttrString(omnipy, (char*)"API");
+ pyapi = PyObject_GetAttrString(_omnipy, (char*)"API");
if (!pyapi)
{
goto out;
Py_DECREF(pyapi);
res=PyRun_String("\n"
- "import sys\n"
- "sys.path.insert(0,'.')\n"
- "from omniORB import CORBA\n"
- "from omniORB import any\n"
- "orb = CORBA.ORB_init([], CORBA.ORB_ID)\n"
- "#print sys.getrefcount(orb)\n"
- "\n",
- Py_file_input,globals,globals );
+ "from math import *\n"
+ "import sys\n"
+ "sys.path.insert(0,'.')\n"
+ "from omniORB import CORBA\n"
+ "from omniORB import any\n"
+ "orb = CORBA.ORB_init([], CORBA.ORB_ID)\n"
+ "#print sys.getrefcount(orb)\n"
+ "try:\n"
+ " import SALOME\n"
+ "except:\n"
+ " pass\n"
+ "\n",
+ Py_file_input,globals,globals );
if(res == NULL)
{
PyErr_Print();
out:
PyGILState_Release(gstate); // Release the Global Interpreter Lock
}
+ if (_useCorba)
+ {
+ // initialize the catalogLoaderFactory map with the session one
+ _catalogLoaderFactoryMap["session"]=new SessionCataLoader;
+ }
}
void RuntimeSALOME::fini()
else
Py_DECREF(res);
}
+ std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
+ delete nodeMap["PyFunction"];
+ delete nodeMap["PyScript"];
+ delete nodeMap["SalomePythonNode"];
+ nodeMap.erase("PyFunction");
+ nodeMap.erase("PyScript");
+ nodeMap.erase("SalomePythonNode");
+
Py_Finalize();
#ifdef REFCNT
DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
}
}
+std::string RuntimeSALOME::getVersion() const
+{
+#ifdef YACS_DEVELOPMENT
+ return CORBA::string_dup(YACS_VERSION_STR"dev");
+#else
+ return CORBA::string_dup(YACS_VERSION_STR);
+#endif
+}
+
Proc* RuntimeSALOME::createProc(const std::string& name)
{
return new SalomeProc(name);
}
+TypeCode * RuntimeSALOME::createInterfaceTc(const std::string& id, const std::string& name,
+ std::list<TypeCodeObjref *> ltc)
+{
+ std::string myName;
+ if(id == "") myName = "IDL:" + name + ":1.0";
+ else myName = id;
+ return TypeCode::interfaceTc(myName.c_str(),name.c_str(),ltc);
+}
+
+TypeCode * RuntimeSALOME::createSequenceTc(const std::string& id,
+ const std::string& name,
+ TypeCode *content)
+{
+ return TypeCode::sequenceTc(id.c_str(),name.c_str(),content);
+};
+
+TypeCodeStruct * RuntimeSALOME::createStructTc(const std::string& id, const std::string& name)
+{
+ std::string myName;
+ if(id == "") myName = "IDL:" + name + ":1.0";
+ else myName = id;
+ return (TypeCodeStruct *)TypeCode::structTc(myName.c_str(),name.c_str());
+}
+
Bloc* RuntimeSALOME::createBloc(const std::string& name)
{
return new Bloc(name);
return new ForLoop(name);
}
+OptimizerLoop* RuntimeSALOME::createOptimizerLoop(const std::string& name,const std::string& algLib,const std::string& factoryName,
+ bool algInitOnFile, const std::string& kind, Proc * procForTypes)
+{
+ OptimizerLoop * ol = (kind == "base") ? new OptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes) :
+ new SalomeOptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes);
+ ol->edGetNbOfBranchesPort()->edInit(1);
+ return ol;
+}
+
+DataNode* RuntimeSALOME::createInDataNode(const std::string& kind,const std::string& name)
+{
+ DataNode* node;
+ if(kind == "" )
+ {
+ node = new PresetNode(name);
+ return node;
+ }
+ else if(kind == "study" )
+ {
+ return new StudyInNode(name);
+ }
+ std::string msg="DataNode kind ("+kind+") unknown";
+ throw Exception(msg);
+}
+
+DataNode* RuntimeSALOME::createOutDataNode(const std::string& kind,const std::string& name)
+{
+ if(kind == "" )
+ {
+ return new OutNode(name);
+ }
+ else if(kind == "study" )
+ {
+ return new StudyOutNode(name);
+ }
+
+ std::string msg="OutDataNode kind ("+kind+") unknown";
+ throw Exception(msg);
+}
+
InlineFuncNode* RuntimeSALOME::createFuncNode(const std::string& kind,const std::string& name)
{
InlineFuncNode* node;
node = new PyFuncNode(name);
return node;
}
+ if(kind == DistributedPythonNode::KIND)
+ return new DistributedPythonNode(name);
std::string msg="FuncNode kind ("+kind+") unknown";
throw Exception(msg);
}
return new SalomePythonComponent(name);
else if (kind == CppComponent::KIND)
return new CppComponent(name);
+ else if (kind == SalomeHPComponent::KIND)
+ return new SalomeHPComponent(name);
std::string msg="Component Instance kind ("+kind+") unknown";
throw Exception(msg);
}
Container *RuntimeSALOME::createContainer(const std::string& kind)
{
- if(kind == "" || kind == SalomeComponent::KIND)
+ if(kind == "" || kind == SalomeContainer::KIND)
return new SalomeContainer;
- else if (kind == CppComponent::KIND)
+ if(kind==SalomeHPContainer::KIND)
+ return new SalomeHPContainer;
+ else if (kind == CppContainer::KIND)
return new CppContainer;
std::string msg="Container kind ("+kind+") unknown";
throw Exception(msg);
* \param source : InputPort to be adapted
* \param impl : new implementation (C++, python, CORBA, XML, Neutral)
* \param type : data type provided by the InputPort
+ * \param init : indicates if the adapted InputPort will be used for initialization (value true) or not (value false)
*
* \return : adapted InputPort
*/
InputPort* RuntimeSALOME::adapt(InputPort* source,
const std::string& impl,
- TypeCode * type) throw (ConversionException)
+ TypeCode * type,bool init) throw (ConversionException)
{
string imp_source=source->getNode()->getImplementation();
if(imp_source == PythonNode::IMPL_NAME)
{
- return adapt((InputPyPort*)source,impl,type);
+ return adapt((InputPyPort*)source,impl,type,init);
}
else if(imp_source == CppNode::IMPL_NAME)
{
- return adapt((InputCppPort*)source,impl,type);
+ return adapt((InputCppPort*)source,impl,type,init);
}
else if(imp_source == CORBANode::IMPL_NAME)
{
- return adapt((InputCorbaPort*)source,impl,type);
+ return adapt((InputCorbaPort*)source,impl,type,init);
}
else if(imp_source == XmlNode::IMPL_NAME)
{
- return adapt((InputXmlPort*)source,impl,type);
+ return adapt((InputXmlPort*)source,impl,type,init);
}
else if(imp_source == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
{
- return adaptNeutral(source,impl,type);
+ return adaptNeutral(source,impl,type,init);
}
else
{
}
}
+//! Adapter function for InPropertyPort
+/*!
+ * \param source : InPropertyPort to be adapted
+ * \param impl : new implementation (C++, python, CORBA, XML, Neutral)
+ * \param type : data type provided by the InPropertyPort
+ * \param init : indicates if the adapted InPropertyPort will be used for initialization (value true) or not (value false)
+ *
+ * \return : adapted InputPort
+ */
+InputPort* RuntimeSALOME::adapt(InPropertyPort* source,
+ const std::string& impl,
+ TypeCode * type,bool init) throw (ConversionException)
+{
+ return adaptNeutral((InputPort *)source,impl,type,init);
+}
+
//! Adapt a Neutral input port to a Corba output port
/*!
* \param inport : Neutral input port to adapt to Corba type type
}
//non convertible type
stringstream msg;
- msg << "Cannot connect Neutral InputPort to OutputCorbaPort : " ;
- msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+ msg << "Cannot connect Corba output port with type: " << type->id() ;
+ msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
}
//non convertible type
stringstream msg;
- msg << "Cannot connect Neutral InputPort to OutputPyPort : " ;
- msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+ msg << "Cannot connect Python output port with type: " << type->id() ;
+ msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
}
//non convertible type
stringstream msg;
- msg << "Cannot connect Neutral InputPort to OutputXmlPort : " ;
- msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+ msg << "Cannot connect Xml output port with type: " << type->id() ;
+ msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
}
//non convertible type
stringstream msg;
- msg << "Cannot connect Neutral " << inport->edGetType()->getKindRepr()
- << " InputPort to " << type->getKindRepr() << " OutputCppPort : " ;
- msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+ msg << "Cannot connect Cpp output port with type: " << type->id() ;
+ msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
* \param source : Neutral input port to adapt to implementation impl and type type
* \param impl : output port implementation (C++, Python, Corba, Xml or Neutral)
* \param type : output port supported type
+ * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
* \return the adaptated port
*/
InputPort* RuntimeSALOME::adaptNeutral(InputPort* source,
const std::string& impl,
- TypeCode * type) throw (ConversionException)
+ TypeCode * type,bool init) throw (ConversionException)
{
if(impl == CppNode::IMPL_NAME)
{
{
return adaptNeutralToCorba(source,type);
}
- else if(impl == XmlNode::IMPL_NAME)
+ else if(impl == XmlNode::IMPL_NAME )
{
return adaptNeutralToXml(source,type);
}
else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
{
- return new ProxyPort(source);
+ if(init)
+ return new NeutralInit(source);
+ else
+ return new ProxyPort(source);
}
stringstream msg;
msg << "Cannot connect InputPort : unknown implementation " << impl;
}
//output type is not convertible
stringstream msg;
- msg << "Cannot connect InputXmlPort to Corba output port " ;
- msg << type->id() << " != " << inport->edGetType()->id();
- msg << " ("__FILE__ << ":" << __LINE__ << ")";
+ msg << "Cannot connect Corba output port with type: " << type->id() ;
+ msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
}
//non convertible type
stringstream msg;
- msg << "Cannot connect Xml InputPort to OutputPyPort : " ;
- msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+ msg << "Cannot connect Python output port with type: " << type->id() ;
+ msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
}
//non convertible type
stringstream msg;
- msg << "Cannot connect Xml InputPort to OutputCppPort : " ;
- msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+ msg << "Cannot connect Cpp output port with type: " << type->id() ;
+ msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
throw ConversionException(msg.str());
}
+//! Adapt a XML input port to a Xml output port
+/*!
+ * \param inport : input port to adapt to Xml type type
+ * \param type : output port type
+ * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
+ * \return an adaptated input port of type Xmlxxxx
+ */
+InputPort* RuntimeSALOME::adaptXmlToXml(InputXmlPort* inport,
+ TypeCode * type,bool init) throw (ConversionException)
+{
+ if(init)
+ return new ProxyPort(inport);
+
+ if(inport->edGetType()->isAdaptable(type))
+ return new ProxyPort(inport);
+
+ stringstream msg;
+ msg << "Cannot connect Xml output port with type: " << type->id() ;
+ msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
+ throw ConversionException(msg.str());
+}
+
//! Adapt an Xml input port to an output port which implementation is given by impl
/*!
* \param source : input port to adapt to implementation impl and type type
* \param impl : output port implementation (C++, Python or Corba)
* \param type : output port supported type
+ * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
* \return the adaptated port
*/
InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
const std::string& impl,
- TypeCode * type) throw (ConversionException)
+ TypeCode * type,bool init) throw (ConversionException)
{
if(impl == CORBANode::IMPL_NAME)
{
{
return adaptXmlToCpp(source,type);
}
- else if(impl == XmlNode::IMPL_NAME)
+ else if(impl == XmlNode::IMPL_NAME )
{
- return new ProxyPort(source);
+ return adaptXmlToXml(source,type,init);
}
else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
{
}
//outport data can not be converted
stringstream msg;
- msg << "Cannot connect 2 CorbaPort with non convertible types: " ;
- msg << type->id() << " != " << inport->edGetType()->id();
+ msg << "Cannot connect Corba output port with type: " << type->id() ;
+ msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
else
{
stringstream msg;
- msg << "Cannot connect InputPyPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
- msg << " " << __FILE__ << ":" <<__LINE__;
+ msg << "Cannot connect Python output port with type: " << type->id() ;
+ msg << " to CORBA input port " << inport->getName() << " with incompatible objref type: " << inport->edGetType()->id();
+ msg << " (" << __FILE__ << ":" <<__LINE__ << ")";
throw ConversionException(msg.str());
}
}
}
// Adaptation not possible
stringstream msg;
- msg << "Cannot connect InputCorbaPort to Python output " ;
- msg << __FILE__ << ":" <<__LINE__;
+ msg << "Cannot connect Python output port with type: " << type->id() ;
+ msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
}
//output type is not convertible
stringstream msg;
- msg << "Cannot connect InputCorbaPort with OutputXmlPort : " ;
- msg << __FILE__ << ":" <<__LINE__;
+ msg << "Cannot connect Xml output port with type: " << type->id() ;
+ msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
}
//output type is not convertible
stringstream msg;
- msg << "Cannot connect InputCorbaPort with OutputCppPort : " ;
- msg << __FILE__ << ":" <<__LINE__;
+ msg << "Cannot connect Cpp output port with type: " << type->id() ;
+ msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
throw ConversionException(msg.str());
}
}
+ else if(inport->edGetType()->kind() == Struct)
+ {
+ if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaStruct(inport);
+ }
// Adaptation not possible
stringstream msg;
- msg << "Cannot connect InputCorbaPort to Neutral output " ;
- msg << __FILE__ << ":" <<__LINE__;
+ msg << "Cannot connect Neutral output port with type: " << type->id() ;
+ msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
* \param source : input port to adapt to implementation impl and type type
* \param impl : output port implementation (C++, Python or Corba)
* \param type : outport data type
+ * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
* \return an adaptator port which type depends on impl
*/
InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
const std::string& impl,
- TypeCode * type) throw (ConversionException)
+ TypeCode * type,bool init) throw (ConversionException)
{
if(impl == CppNode::IMPL_NAME)
{
}
else if(impl == CORBANode::IMPL_NAME)
{
- return adaptCorbaToCorba(source,type);
+ if(init)
+ return adaptCorbaToCorba(source,type);
+ else
+ return adaptCorbaToCorba(source,type);
}
- else if(impl == XmlNode::IMPL_NAME)
+ else if(impl == XmlNode::IMPL_NAME )
{
return adaptCorbaToXml(source,type);
}
* Only check, it's possible.
* \param inport : InputPort to adapt to Python type type
* \param type : outport data type
+ * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
* \return an adaptator port of type InputPyPort
*/
InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
- TypeCode * type) throw (ConversionException)
+ TypeCode * type,bool init) throw (ConversionException)
{
+ if(init)
+ return new PyInit(inport);
+
if(isAdaptablePyObjectPyObject(type,inport->edGetType()))
{
//output data is convertible to input type
}
//output data is not convertible to input type
stringstream msg;
- msg << "Cannot connect 2 Python Port with non convertible types: " ;
- msg << type->id() << " != " << inport->edGetType()->id();
+ msg << "Cannot connect Python output port with type: " << type->id() ;
+ msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
}
//output type is not convertible
stringstream msg;
- msg << "Cannot connect InputPythonPort with OutputCppPort : " ;
- msg << __FILE__ << ":" <<__LINE__;
+ msg << "Cannot connect Cpp output port with type: " << type->id() ;
+ msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
throw ConversionException(msg.str());
}
}
+ else if(inport->edGetType()->kind() == Struct)
+ {
+ if(isAdaptablePyObjectNeutral(type,inport->edGetType())) return new NeutralPyStruct(inport);
+ }
+
// Adaptation not possible
stringstream msg;
- msg << "Cannot connect InputPyPort to Neutral output " ;
- msg << "Output typeid: " << type->id() << " Input typeid: " << inport->edGetType()->id();
- msg << " ("__FILE__ << ":" << __LINE__ << ")";
+ msg << "Cannot connect Neutral output port with type: " << type->id() ;
+ msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
}
// Adaptation not possible
stringstream msg;
- msg << "Cannot connect InputPyPort to Corba output " ;
- msg << __FILE__ << ":" << __LINE__;
+ msg << "Cannot connect Corba output port with type: " << type->id() ;
+ msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("__FILE__ << ":" << __LINE__ << ")";
+#endif
throw ConversionException(msg.str());
}
}
//non convertible type
stringstream msg;
- msg << "Cannot connect InputPyPort with OutputXmlPort : " ;
- msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+ msg << "Cannot connect Xml output port with type: " << type->id() ;
+ msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
* \param source : input port to adapt to implementation impl and type type
* \param impl : output port implementation (C++, Python or Corba)
* \param type : output port type
+ * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
* \return adaptated input port
*/
InputPort* RuntimeSALOME::adapt(InputPyPort* source,
const std::string& impl,
- TypeCode * type) throw (ConversionException)
+ TypeCode * type,bool init) throw (ConversionException)
{
if(impl == CppNode::IMPL_NAME)
{
}
else if(impl == PythonNode::IMPL_NAME)
{
- return adaptPythonToPython(source,type);
+ return adaptPythonToPython(source,type,init);
}
else if(impl == CORBANode::IMPL_NAME)
{
}
//output type is not convertible
stringstream msg;
- msg << "Cannot connect InputCppPort to Corba output port " ;
- msg << type->id() << " != " << inport->edGetType()->id();
- msg << " ("__FILE__ << ":" << __LINE__ << ")";
+ msg << "Cannot connect Corba output port with type: " << type->id() ;
+ msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
}
//output type is not convertible
stringstream msg;
- msg << "Cannot connect InputCppPort with OutputPythonPort : " ;
- msg << __FILE__ << ":" <<__LINE__;
+ msg << "Cannot connect Python output port with type: " << type->id() ;
+ msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
}
//non convertible type
stringstream msg;
- msg << "Cannot connect Cpp InputPort to OutputCppPort : " ;
- msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+ msg << "Cannot connect Cpp output port with type: " << type->id() ;
+ msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
}
//non convertible type
stringstream msg;
- msg << "Cannot connect Cpp InputPort to OutputNeutralPort : " ;
- msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+ msg << "Cannot connect Neutral output port with type: " << type->id() ;
+ msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
InputPort* RuntimeSALOME::adaptCppToXml(InputCppPort* inport,
TypeCode * type) throw (ConversionException)
{
- DEBTRACE("RuntimeSALOME::adaptCppToXml(InputCppPort* inport" );
- if(isAdaptableCppXml(type,inport->edGetType()))
- {
+ DEBTRACE("RuntimeSALOME::adaptCppToXml(InputCppPort* inport" );
+ if(isAdaptableCppXml(type,inport->edGetType()))
+ {
//convertible type
return new XmlCpp(inport);
- }
- //non convertible type
- stringstream msg;
- msg << "Cannot connect InputCppPort with OutputXmlPort : " ;
- msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+ }
+ //non convertible type
+ stringstream msg;
+ msg << "Cannot connect Xml output port with type: " << type->id() ;
+ msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+ msg << " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
throw ConversionException(msg.str());
}
* \param source : input port to adapt to implementation impl and type type
* \param impl : output port implementation (C++, Python or Corba)
* \param type : output port supported type
+ * \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
* \return the adaptated port
*/
InputPort* RuntimeSALOME::adapt(InputCppPort* source,
const std::string& impl,
- TypeCode * type) throw (ConversionException)
+ TypeCode * type,bool init) throw (ConversionException)
{
DEBTRACE("RuntimeSALOME::adapt(InputCppPort* source)");
if(impl == CORBANode::IMPL_NAME)
return _dynFactory;
}
+PyObject * RuntimeSALOME::get_omnipy()
+{
+ return _omnipy;
+}
+
omniORBpyAPI* RuntimeSALOME::getApi()
{
return _api;
}
+void* RuntimeSALOME::convertNeutral(TypeCode * type, Any *data)
+{
+ if(data)
+ return (void *)convertNeutralPyObject(type,data);
+ else
+ {
+ Py_INCREF(Py_None);
+ return (void *)Py_None;
+ }
+}
+
+std::string RuntimeSALOME::convertNeutralAsString(TypeCode * type, Any *data)
+{
+ PyObject* ob;
+ if(data)
+ {
+ // The call to PyGILState_Ensure was moved here because there was also
+ // a crash when calling convertNeutralPyObject with a sequence of pyobj.
+ // see also the comment below.
+ PyGILState_STATE gstate = PyGILState_Ensure();
+ ob=convertNeutralPyObject(type,data);
+ std::string s=convertPyObjectToString(ob);
+
+ // Note (Renaud Barate, 8 jan 2013): With Python 2.7, this call to Py_DECREF causes a crash
+ // (SIGSEGV) when ob is a sequence and the call is not protected with the global interpreter
+ // lock. I thus added the call to PyGILState_Ensure / PyGILState_Release. It worked fine in
+ // Python 2.6 without this call. If anyone finds the real reason of this bug and another fix,
+ // feel free to change this code.
+ //PyGILState_STATE gstate = PyGILState_Ensure();
+ Py_DECREF(ob);
+ PyGILState_Release(gstate);
+ return s;
+ }
+ else
+ {
+ return "None";
+ }
+}
+
+std::string RuntimeSALOME::convertPyObjectToString(PyObject* ob)
+{
+ return YACS::ENGINE::convertPyObjectToString(ob);
+}
+
+PyObject* RuntimeSALOME::convertStringToPyObject(const std::string& s)
+{
+ PyObject *mainmod;
+ PyObject *globals;
+ PyObject* ob;
+ PyGILState_STATE gstate = PyGILState_Ensure();
+ mainmod = PyImport_AddModule("__main__");
+ globals = PyModule_GetDict(mainmod);
+ PyObject* d = PyDict_New();
+ //PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
+ ob= PyRun_String( s.c_str(), Py_eval_input, globals, d);
+ Py_DECREF(d);
+ if(ob==NULL)
+ {
+ //exception
+ std::string error;
+ PyObject* new_stderr = newPyStdOut(error);
+ PySys_SetObject((char *)"stderr", new_stderr);
+ PyErr_Print();
+ PySys_SetObject((char *)"stderr", PySys_GetObject((char *)"__stderr__"));
+ Py_DECREF(new_stderr);
+ PyGILState_Release(gstate);
+ throw Exception(error);
+ }
+ PyGILState_Release(gstate);
+ return ob;
+}