]> SALOME platform Git repositories - modules/yacs.git/commitdiff
Salome HOME
Merge branch 'V8_3_BR' into ngr/python3_dev
authorGilles DAVID <gilles-g.david@edf.fr>
Tue, 30 May 2017 13:40:11 +0000 (15:40 +0200)
committerGilles DAVID <gilles-g.david@edf.fr>
Tue, 30 May 2017 13:40:11 +0000 (15:40 +0200)
27 files changed:
CMakeLists.txt
doc/conf.py.in
doc/sources/footer.html
src/engine/ComposedNode.cxx
src/engine/Executor.cxx
src/engine/ForEachLoop.cxx
src/engine/ForEachLoop.hxx
src/engine/Proc.hxx
src/evalyfx/YACSEvalSeqAny.cxx
src/evalyfx/YACSEvalSeqAny.hxx
src/evalyfx/YACSEvalSession.cxx
src/pmml/doc/doxygen/static/footer.html
src/py2yacs/CMakeLists.txt
src/py2yacs/Test/Py2yacsTest.cxx
src/py2yacs/py2yacs.cxx
src/py2yacs/py2yacs.hxx
src/runtime/CMakeLists.txt
src/runtime/TypeConversions.hxx
src/runtime/VisitorSalomeSaveState.cxx [new file with mode: 0644]
src/runtime/VisitorSalomeSaveState.hxx [new file with mode: 0644]
src/runtime_swig/CMakeLists.txt
src/runtime_swig/SALOMERuntime.i
src/yacsloader/CMakeLists.txt
src/yacsloader/LoadState.cxx
src/yacsloader/LoadState.hxx
src/yacsloader/driver.cxx
src/yacsloader_swig/Test/testSaveLoadRun.py

index 7ca44301d9cb52b4bd2e0aa42b8eab29a107f67f..55a06dc22e1f3ac3f685f072fd0386dee4e1ec35 100644 (file)
@@ -33,7 +33,7 @@ ENDIF(WIN32)
 STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC)
 
 SET(${PROJECT_NAME_UC}_MAJOR_VERSION 8)
-SET(${PROJECT_NAME_UC}_MINOR_VERSION 2)
+SET(${PROJECT_NAME_UC}_MINOR_VERSION 3)
 SET(${PROJECT_NAME_UC}_PATCH_VERSION 0)
 SET(${PROJECT_NAME_UC}_VERSION
   ${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION})
index 9373fc139dd17642049c1c6ec6dfd7b83405648c..c0d7d0f0b267983621b58040ddddcdd5316c3e1e 100644 (file)
@@ -41,7 +41,7 @@ master_doc = 'index'
 
 # General information about the project.
 project = 'yacs'
-copyright = '2007-2016 CEA/DEN, EDF R&D.'
+copyright = '2007-2017 CEA/DEN, EDF R&D.'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
index c3274d1943ff8cfe6402224f7ec6cb9892a885c5..124c1f41416219185c42a457b18f515e574a0e40 100755 (executable)
@@ -4,7 +4,7 @@
   <ul>
     $navpath
     <li class="footer">
-      Copyright &copy; 2006-2016  CEA/DEN, EDF R&amp;D<br>
+      Copyright &copy; 2006-2017  CEA/DEN, EDF R&amp;D<br>
     </li>
   </ul>
 </div>
index 0fa2bf8733ebe66efb8a9b94ce518ffc74abee98..e27e72da6f26f18cdf03653757558aea777090da 100644 (file)
@@ -241,7 +241,7 @@ std::vector<Task *> ComposedNode::getNextTasks(bool& isMore)
  * Calls ComposedNode::updateStateFrom to update state from task to root node
  */
 void ComposedNode::notifyFrom(const Task *sender, //* I : task emitting event
-                              YACS::Event event,   //* I : event emitted
+                              YACS::Event event,  //* I : event emitted
                               const Executor *execInst
                               )
 {
@@ -1376,7 +1376,7 @@ OutputDataStreamPort *ComposedNode::getOutputDataStreamPort(const std::string& n
  * Called by ComposedNode::notifyFrom
  */
 YACS::Event ComposedNode::updateStateFrom(Node *node,        //* I : node emitting event
-                                          YACS::Event event,  //* I : event emitted
+                                          YACS::Event event, //* I : event emitted
                                           const Executor *execInst
                                           )
 {
index d559230355590a8c16f1147376c84106424800ab..c5e7c7b45e71cd4ae6e6c5d21ee318fe42f46c29 100644 (file)
@@ -651,6 +651,7 @@ bool Executor::saveState(const std::string& xmlFile)
   DEBTRACE("Executor::saveState() in " << xmlFile);
   bool result = false;
   try {
+    YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
     YACS::ENGINE::VisitorSaveState vst(_root);
     vst.openFileDump(xmlFile.c_str());
     _root->accept(&vst);
index 54535a140d33a0fc73d74d506e73d1821ecdb437..838bfb338fb4c6e00c5b4bc58598214db93a10a0 100644 (file)
@@ -318,6 +318,14 @@ ForEachLoopPassedData::ForEachLoopPassedData(const std::vector<unsigned int>& pa
     }
 }
 
+ForEachLoopPassedData::ForEachLoopPassedData(const ForEachLoopPassedData& copy)
+: _passedIds(copy._passedIds),
+  _passedOutputs(copy._passedOutputs),
+  _nameOfOutputs(copy._nameOfOutputs),
+  _flagsIds(copy._flagsIds)
+{
+}
+
 ForEachLoopPassedData::~ForEachLoopPassedData()
 {
   for(std::vector<SequenceAny *>::iterator it=_passedOutputs.begin();it!=_passedOutputs.end();it++)
@@ -878,6 +886,7 @@ YACS::Event ForEachLoop::updateStateOnFailedEventFrom(Node *node, const Executor
 {
   unsigned int id;
   DynParaLoop::TypeOfNode ton(getIdentityOfNotifyerNode(node,id));
+  // TODO: deal with keepgoing without the dependency to Executor
   if(ton!=WORK_NODE || !execInst->getKeepGoingProperty())
     return DynParaLoop::updateStateOnFailedEventFrom(node,execInst);
   else
@@ -1173,7 +1182,9 @@ std::vector<unsigned int> ForEachLoop::getPassedResults(Executor *execut, std::v
     return std::vector<unsigned int>();
   if(_execOutGoingPorts.empty())
     return std::vector<unsigned int>();
-  std::size_t sz(_execVals.size()); outputs.resize(sz); nameOfOutputs.resize(sz);
+  std::size_t sz(_execVals.size());
+  outputs.resize(sz);
+  nameOfOutputs.resize(sz);
   const std::vector<AnyInputPort *>& ports(_execOutGoingPorts[0]);
   for(std::size_t i=0;i<sz;i++)
     {
@@ -1211,3 +1222,52 @@ int ForEachLoop::getFEDeltaBetween(OutPort *start, InPort *end)
     ret--;
   return ret;
 }
+
+/*!
+ * This method is used to obtain the values already processed by the ForEachLoop.
+ * A new ForEachLoopPassedData object is returned. You have to delete it.
+ */
+ForEachLoopPassedData* ForEachLoop::getProcessedData()const
+{
+  std::vector<SequenceAny *> outputs;
+  std::vector<std::string> nameOfOutputs;
+  if(_execVals.empty() || _execOutGoingPorts.empty())
+    return new ForEachLoopPassedData(std::vector<unsigned int>(), outputs, nameOfOutputs);
+  std::size_t sz(_execVals.size());
+  outputs.resize(sz);
+  nameOfOutputs.resize(sz);
+  const std::vector<AnyInputPort *>& ports(_execOutGoingPorts[0]);
+  for(std::size_t i=0;i<sz;i++)
+    {
+      outputs[i]=_execVals[i]->removeUnsetItemsFromThis();
+      nameOfOutputs[i]=ports[i]->getName();
+    }
+  return new ForEachLoopPassedData(_execVals[0]->getSetItems(), outputs, nameOfOutputs);
+}
+
+void ForEachLoop::setProcessedData(ForEachLoopPassedData* processedData)
+{
+  if(_passedData)
+    delete _passedData;
+  _passedData = processedData;
+}
+
+/*!
+ * \param portName : "interceptorized" name of port.
+ */
+const YACS::ENGINE::TypeCode* ForEachLoop::getOutputPortType(const std::string& portName)const
+{
+  const YACS::ENGINE::TypeCode* ret=NULL;
+  vector<AnySplitOutputPort *>::const_iterator it;
+  for(it=_outGoingPorts.begin();it!=_outGoingPorts.end() && ret==NULL;it++)
+  {
+    std::string originalPortName(getPortName(*it));
+    //InterceptorizeNameOfPort(originalPortName);
+    DEBTRACE("ForEachLoop::getOutputPortType compare " << portName << " == " << originalPortName);
+    if(originalPortName == portName)
+    {
+      ret = (*it)->edGetType()->contentType();
+    }
+  }
+  return ret;
+}
index 7c1968d38eca47298b28895e43f192aed1679dc7..54aa83aae4a5936818183c7e784a87a9f5ba8862 100644 (file)
@@ -127,6 +127,7 @@ namespace YACS
     {
     public:
       ForEachLoopPassedData(const std::vector<unsigned int>& passedIds, const std::vector<SequenceAny *>& passedOutputs, const std::vector<std::string>& nameOfOutputs);
+      ForEachLoopPassedData(const ForEachLoopPassedData& copy);
       ~ForEachLoopPassedData();
       void init();
       void checkCompatibilyWithNb(int nbOfElts) const;
@@ -136,6 +137,10 @@ namespace YACS
       int toAbsIdNot(int localId) const;
       int getNumberOfElementsToDo() const;
       void assignAlreadyDone(const std::vector<SequenceAny *>& execVals) const;
+      const std::vector<unsigned int>& getIds()const {return _passedIds;}
+      const std::vector<SequenceAny *>& getOutputs()const {return _passedOutputs;}
+      const std::vector<std::string>& getOutputNames()const {return _nameOfOutputs;}
+      //const std::vector<bool>& getFlags()const {return _flagsIds;}
     private:
       std::vector<unsigned int> _passedIds;
       std::vector<SequenceAny *> _passedOutputs;
@@ -197,9 +202,12 @@ namespace YACS
       int getNbOfElementsToBeProcessed() const;
       static int getFEDeltaBetween(OutPort *start, InPort *end);
 #ifndef SWIG
+      ForEachLoopPassedData* getProcessedData()const;
+      void setProcessedData(ForEachLoopPassedData* processedData);
       std::vector<unsigned int> getPassedResults(Executor *execut, std::vector<SequenceAny *>& outputs, std::vector<std::string>& nameOfOutputs) const;
       void assignPassedResults(const std::vector<unsigned int>& passedIds, const std::vector<SequenceAny *>& passedOutputs, const std::vector<std::string>& nameOfOutputs);
 #endif
+     const TypeCode* getOutputPortType(const std::string& portName)const;
     protected:
       Node *simpleClone(ComposedNode *father, bool editionOnly=true) const;
       void checkLinkPossibility(OutPort *start, const std::list<ComposedNode *>& pointsOfViewStart,
index f2a7ea96c34b0ed8b1db6baf53466a82dc2d33cd..95cc82d5700c1c0350482f8cbefdc6ab7543d46c 100644 (file)
@@ -98,6 +98,8 @@ namespace YACS
       virtual void setEdition(bool edition);
       virtual void modified();
       virtual void saveSchema(const std::string& xmlSchemaFile);
+      //! deprecated. See VisitorSalomeSaveState and schemaSaveState in order
+      //! to deal with the execution state of ForEachLoop.
       virtual void saveState(const std::string& xmlStateFile);
     protected:
       void removeContainers();
index 0f0730494580efbbabc187625dd61ee28c5dce9e..e0d0e647d77b55b9043a1e94da06079b87e79c4a 100644 (file)
@@ -34,14 +34,6 @@ YACSEvalSeqAny *YACSEvalSeqAny::BuildEmptyFromType(const std::string& dataType)
     throw YACS::Exception("YACSEvalSeqAny::BuildEmptyFromType : Only int and double are actualy managed !");
 }
 
-template<class T>
-std::size_t YACSEvalSeqAnyInternal<T>::size() const
-{
-  if(!_arr)
-    throw YACS::Exception("YACSEvalSeqAnyDouble<T>::size : empty array !");
-  return _arr->size();
-}
-
 YACSEvalSeqAnyDouble::YACSEvalSeqAnyDouble(const std::vector<double>& arr):_arr(0)
 {
   std::vector<double> *zeArr(new std::vector<double>(arr));
index 195319e0c156b4fa846d107ab7df58899193ed13..b766131c68283e86616a54012fe8983fb4a85c7e 100644 (file)
@@ -94,4 +94,12 @@ private:
   YACSEvalSeqAnyInternal<int> *_arr;
 };
 
+template<class T>
+std::size_t YACSEvalSeqAnyInternal<T>::size() const
+{
+  if(!_arr)
+    throw YACS::Exception("YACSEvalSeqAnyDouble<T>::size : empty array !");
+  return _arr->size();
+}
+
 #endif
index 02886cbfb99409ec76f3604b633a10aa353b4319..e8039658e6e0b20036abbc86577b5842ec8f4cab 100644 (file)
@@ -36,13 +36,8 @@ const char YACSEvalSession::NSPORT_VAR_NAME[]="NSPORT";
 
 YACSEvalSession::YACSEvalSession():_isAttached(false),_isLaunched(false),_isForcedPyThreadSaved(false),_port(-1),_salomeInstanceModule(0),_salomeInstance(0),_internal(new YACSEvalSessionInternal)
 {
-  if(!Py_IsInitialized())
-    Py_Initialize();
-  //
-  {
-    YACS::ENGINE::AutoGIL gal;
-    _salomeInstanceModule=PyImport_ImportModule(const_cast<char *>("salome_instance"));
-  }
+  YACS::ENGINE::AutoGIL gal;
+  _salomeInstanceModule=PyImport_ImportModule(const_cast<char *>("salome_instance"));
 }
 
 YACSEvalSession::~YACSEvalSession()
index 91afd6cc8ab252063767ab204030ae63dd6ee52b..7cf11feba01a088027958a2e4c7639c64f7adb19 100755 (executable)
@@ -4,7 +4,7 @@
   <ul>
     $navpath
     <li class="footer">
-      Copyright &copy; 2007-2016  CEA/DEN, EDF R&amp;D, OPEN CASCADE<br>
+      Copyright &copy; 2007-2017  CEA/DEN, EDF R&amp;D, OPEN CASCADE<br>
       Copyright &copy; 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&amp;D, LEG, PRINCIPIA R&amp;D, BUREAU VERITAS<br>
     </li>
   </ul>
index 76db23ac82f1863b6c646c9f89bd06506c658f55..e6eb48a0e8a2ea11fbb881fa1b33dfe88176b72b 100644 (file)
@@ -29,6 +29,7 @@ INCLUDE_DIRECTORIES(
 
 ADD_DEFINITIONS(
   ${PYTHON_DEFINITIONS}
+  ${OMNIORB_DEFINITIONS}
   )
 
 IF(SALOME_BUILD_TESTS)
index 835baf195d0b1a2b6500884440127eb45dc444bb..3c42da566b5d062a5586edbd994bae8e3bc2def1 100644 (file)
@@ -168,7 +168,7 @@ void Py2yacsTest::t3()
                          "  print(b)\n"
                          "  print(c)\n";
   const char* input_ports[] = {"a", "b", "c"};
-  const char* output_ports[] = {};
+  const char** output_ports;
   verifyCorrectPycode(code_py, "f1", 3, input_ports, 0, output_ports);
 }
 
@@ -178,7 +178,7 @@ void Py2yacsTest::t4()
                          "  print('toto')\n"
                          "  return\n";
   const char* input_ports[] = {"a", "b", "c"};
-  const char* output_ports[] = {};
+  const char** output_ports;
   verifyCorrectPycode(code_py, "f1", 0, input_ports, 0, output_ports);
 }
 
index 3f244aa7435d1491c88444daec7dc11fcbe757be..fcd711ced91368389fe01e56048086aba85c681b 100644 (file)
@@ -75,7 +75,7 @@ static
 std::string copyList(PyObject *pyList, std::list<std::string>& cppList)
 {
   std::string error="";
-  if(not PyList_Check(pyList))
+  if(!PyList_Check(pyList))
   {
     error = "Not a python list.\n";
     //throw Py2yacsException("Not a python list.");
@@ -86,7 +86,7 @@ std::string copyList(PyObject *pyList, std::list<std::string>& cppList)
     for(Py_ssize_t i=0; i<n; i++)
     {
       PyObject *elem = PyList_GetItem(pyList,i);
-      if(not PyUnicode_Check(elem))
+      if(!PyUnicode_Check(elem))
       {
         std::stringstream message;
         message << "List element number " << i << " is not a string.\n";
@@ -157,7 +157,7 @@ PyObject* checkAndGetAttribute(PyObject *p,
                                std::string& error)
 {
   PyObject *pAttribute = PyObject_GetAttrString(p, attribute);
-  if(not pAttribute)
+  if(!pAttribute)
   {
     error += "Attribute '";
     error += attribute;
@@ -183,7 +183,7 @@ void Py2yacs::load(const std::string& python_code)
     pModule = PyImport_Import(pValue);
     Py_DECREF(pValue);
 
-    if (not pModule)
+    if (!pModule)
     {
       errorMessage  = getPyErrorText();
       errorMessage += "\nFailed to load ";
@@ -202,11 +202,11 @@ void Py2yacs::load(const std::string& python_code)
         
         pValue = PyObject_CallObject(pFunc, pArgs);
         Py_DECREF(pArgs);
-        if (not pValue)
+        if (!pValue)
             errorMessage = getPyErrorText();
         else
         {
-          if (not PyTuple_Check(pValue))
+          if (!PyTuple_Check(pValue))
           {
             errorMessage += "Parsing function should return a tuple of two string lists.\n";
           }
@@ -216,7 +216,7 @@ void Py2yacs::load(const std::string& python_code)
             errorMessage += "Parsing function should return two string lists.\n";
           }
           PyObject *pyList = PyTuple_GetItem(pValue, 0);
-          if(not PyList_Check(pyList))
+          if(!PyList_Check(pyList))
           {
             errorMessage += "The first returned value of the parsing function"
                             " should be a python list.\n";
@@ -231,7 +231,7 @@ void Py2yacs::load(const std::string& python_code)
               
               if(pAttribute = checkAndGetAttribute(fpy, "name", errorMessage))
               {
-                if(not PyUnicode_Check(pAttribute))
+                if(!PyUnicode_Check(pAttribute))
                 {
                   errorMessage += "Attribute 'name' should be a string.\n";
                   Py_DECREF(pAttribute);
@@ -281,7 +281,7 @@ void Py2yacs::load(const std::string& python_code)
       Py_DECREF(pModule);
     }
     
-    if(not errorMessage.empty())
+    if(!errorMessage.empty())
       throw Py2yacsException(errorMessage);
     // Py_Finalize();
 }
@@ -296,7 +296,7 @@ void Py2yacs::save(const std::string& file_path,
 
 YACS::ENGINE::Proc* Py2yacs::createProc(const std::string& python_function)const
 {
-  if(not _global_errors.empty())
+  if(!_global_errors.empty())
   {
     std::string error_message = "The python script contains errors.\n";
     std::list<std::string>::const_iterator it;
@@ -307,7 +307,7 @@ YACS::ENGINE::Proc* Py2yacs::createProc(const std::string& python_function)const
   
   // find function properties
   std::list<FunctionProperties>::const_iterator fn_prop = _functions.begin();
-  while(fn_prop != _functions.end() and fn_prop->_name != python_function)
+  while(fn_prop != _functions.end() && fn_prop->_name != python_function)
     fn_prop++;
   
   if(fn_prop == _functions.end())
@@ -315,7 +315,7 @@ YACS::ENGINE::Proc* Py2yacs::createProc(const std::string& python_function)const
     throw Py2yacsException(std::string("Function not found: ")+python_function);
   }
   
-  if(not fn_prop->_errors.empty())
+  if(!fn_prop->_errors.empty())
   {
     std::string error_message = "Function contains errors.\n";
     std::list<std::string>::const_iterator it;
@@ -333,7 +333,7 @@ YACS::ENGINE::Proc* Py2yacs::createProc(const std::string& python_function)const
       it!=fn_prop->_output_ports.end();
       it++)
   {
-    if (not first)
+    if (!first)
       fn_call << ",";
     first = false;
     fn_call << *it;
@@ -344,7 +344,7 @@ YACS::ENGINE::Proc* Py2yacs::createProc(const std::string& python_function)const
       it != fn_prop->_input_ports.end();
       it++)
   {
-    if (not first)
+    if (!first)
       fn_call << ",";
     first = false;
     fn_call << *it;
@@ -375,4 +375,4 @@ YACS::ENGINE::Proc* Py2yacs::createProc(const std::string& python_function)const
     node->edAddOutputPort(*it, tc_double);
   
   return schema;
-}
+}
\ No newline at end of file
index b0ca9c40924cc9b82f4d8df9dd8e22d4f2f9092e..ee052cdf31e8d86102538d43b4dd7686059e84da 100644 (file)
 #ifndef _PY2YACS_H_
 #define _PY2YACS_H_
 
+#ifdef WIN32
+#  if defined py2yacslib_EXPORTS
+#    define PY2YACSLIB_EXPORT __declspec( dllexport )
+#  else
+#    define PY2YACSLIB_EXPORT __declspec( dllimport )
+#  endif
+#else
+#  define PY2YACSLIB_EXPORT
+#endif
+
+
 #include <string>
 #include <list>
 #include <exception>
 
-class Py2yacsException: std::exception
+class PY2YACSLIB_EXPORT Py2yacsException: std::exception
 {
   public:
     Py2yacsException(const std::string& what);
@@ -41,7 +52,7 @@ namespace YACS
   };
 };
 
-struct FunctionProperties
+struct PY2YACSLIB_EXPORT FunctionProperties
 {
   public:
     std::string _name;
@@ -55,7 +66,7 @@ struct FunctionProperties
  *  This class converts a string containing a python script to a yacs schema
  *  containing a python script node.
  */
-class Py2yacs
+class PY2YACSLIB_EXPORT Py2yacs
 {
   public:
     Py2yacs();
index 86cdb00c0cfba739b00874e72763d459af2f5736..5fcb9c6b41412b548cb6ad180830434ec1e435ef 100644 (file)
@@ -145,6 +145,7 @@ SET(YACSRuntimeSALOME_HEADERS
   SalomeOptimizerLoop.hxx
   DistributedPythonNode.hxx
   PyOptimizerAlg.hxx
+  VisitorSalomeSaveState.hxx
   )
 
 # --- sources ---
@@ -211,6 +212,7 @@ SET(YACSRuntimeSALOME_SOURCES
   PyStdout.cxx                   
   SalomeOptimizerLoop.cxx        
   PyOptimizerAlg.cxx             
+  VisitorSalomeSaveState.cxx
   )
 
 # --- rules ---
index 2d3c3079ca03c8705d040f55a7946be8ff9a529c..7fc3dc1eb8a8e2b788955e908c5aa76354473f18 100644 (file)
@@ -57,45 +57,47 @@ namespace YACS
     class TypeCode;
     class Any;
 
-    CORBA::TypeCode_ptr getCorbaTC(const TypeCode *t);
+    YACSRUNTIMESALOME_EXPORT CORBA::TypeCode_ptr getCorbaTC(const TypeCode *t);
 
-    int isAdaptableCorbaPyObject(const TypeCode * t1, const TypeCode * t2);
-    int isAdaptableCorbaNeutral(const TypeCode * t1, const TypeCode * t2);
-    int isAdaptableCorbaCorba(const TypeCode * t1, const TypeCode * t2);
+    YACSRUNTIMESALOME_EXPORT int isAdaptableCorbaPyObject(const TypeCode * t1, const TypeCode * t2);
+    YACSRUNTIMESALOME_EXPORT int isAdaptableCorbaNeutral(const TypeCode * t1, const TypeCode * t2);
+    YACSRUNTIMESALOME_EXPORT int isAdaptableCorbaCorba(const TypeCode * t1, const TypeCode * t2);
 
-    int isAdaptableNeutralCorba(const TypeCode * t1, const TypeCode * t2);
-    int isAdaptableNeutralNeutral(const TypeCode * t1, const TypeCode * t2);
-    int isAdaptableNeutralXml(const TypeCode * t1, const TypeCode * t2);
-    int isAdaptableNeutralPyObject(const TypeCode * t1, const TypeCode * t2);
+    YACSRUNTIMESALOME_EXPORT int isAdaptableNeutralCorba(const TypeCode * t1, const TypeCode * t2);
+    YACSRUNTIMESALOME_EXPORT int isAdaptableNeutralNeutral(const TypeCode * t1, const TypeCode * t2);
+    YACSRUNTIMESALOME_EXPORT int isAdaptableNeutralXml(const TypeCode * t1, const TypeCode * t2);
+    YACSRUNTIMESALOME_EXPORT int isAdaptableNeutralPyObject(const TypeCode * t1, const TypeCode * t2);
 
-    int isAdaptablePyObjectPyObject(const TypeCode * t1, const TypeCode * t2);
-    int isAdaptablePyObjectCorba(const TypeCode * t1, const TypeCode * t2);
-    int isAdaptablePyObjectNeutral(const TypeCode * t1, const TypeCode * t2);
+    YACSRUNTIMESALOME_EXPORT int isAdaptablePyObjectPyObject(const TypeCode * t1, const TypeCode * t2);
+    YACSRUNTIMESALOME_EXPORT int isAdaptablePyObjectCorba(const TypeCode * t1, const TypeCode * t2);
+    YACSRUNTIMESALOME_EXPORT int isAdaptablePyObjectNeutral(const TypeCode * t1, const TypeCode * t2);
 
-    int isAdaptableXmlNeutral(const TypeCode *t1,const TypeCode *t2);
-    int isAdaptableXmlCorba(const TypeCode *t1, const TypeCode *t2);
+    YACSRUNTIMESALOME_EXPORT int isAdaptableXmlNeutral(const TypeCode *t1,const TypeCode *t2);
+    YACSRUNTIMESALOME_EXPORT int isAdaptableXmlCorba(const TypeCode *t1, const TypeCode *t2);
 
-    PyObject *convertCorbaPyObject(const TypeCode * t,CORBA::Any* ob);
-    CORBA::Any *convertCorbaCorba(const TypeCode * t,CORBA::Any* ob);
-    YACS::ENGINE::Any *convertCorbaNeutral(const TypeCode *t,CORBA::Any* ob);
-    std::string convertCorbaXml(const TypeCode * t,CORBA::Any* ob);
+    YACSRUNTIMESALOME_EXPORT PyObject *convertCorbaPyObject(const TypeCode * t,CORBA::Any* ob);
+    YACSRUNTIMESALOME_EXPORT PyObject *convertCorbaPyObject(const TypeCode * t,CORBA::Any* ob);
+    YACSRUNTIMESALOME_EXPORT PyObject *convertCorbaPyObject(const TypeCode * t,CORBA::Any* ob);
+    YACSRUNTIMESALOME_EXPORT CORBA::Any *convertCorbaCorba(const TypeCode * t,CORBA::Any* ob);
+    YACSRUNTIMESALOME_EXPORT YACS::ENGINE::Any *convertCorbaNeutral(const TypeCode *t,CORBA::Any* ob);
+    YACSRUNTIMESALOME_EXPORT std::string convertCorbaXml(const TypeCode * t,CORBA::Any* ob);
 
-    CORBA::Any *convertPyObjectCorba(const TypeCode *t,PyObject *ob);
+    YACSRUNTIMESALOME_EXPORT CORBA::Any *convertPyObjectCorba(const TypeCode *t,PyObject *ob);
     YACSRUNTIMESALOME_EXPORT std::string convertPyObjectXml(const TypeCode * t,PyObject* ob);
-    YACS::ENGINE::Any *convertPyObjectNeutral(const TypeCode *t,PyObject* ob);
-    PyObject* convertPyObjectPyObject(const TypeCode *t,PyObject *ob);
-    std::string convertPyObjectToString(PyObject* ob);
-    bool checkPyObject(const TypeCode *t,PyObject* ob);
-
-    PyObject *convertXmlPyObject(const TypeCode * t,xmlDocPtr doc,xmlNodePtr cur );
-    PyObject *convertXmlStrPyObject(const TypeCode * t,std::string data );
-    CORBA::Any *convertXmlCorba(const TypeCode * t,xmlDocPtr doc,xmlNodePtr cur );
-    YACS::ENGINE::Any *convertXmlNeutral(const TypeCode * t,xmlDocPtr doc,xmlNodePtr cur );
-
-    PyObject *convertNeutralPyObject(const TypeCode * t,YACS::ENGINE::Any* ob);
-    std::string convertNeutralXml(const TypeCode * t,YACS::ENGINE::Any* ob);
-    CORBA::Any *convertNeutralCorba(const TypeCode *t,YACS::ENGINE::Any *ob);
-    YACS::ENGINE::Any *convertNeutralNeutral(const TypeCode *t, YACS::ENGINE::Any* ob);
+    YACSRUNTIMESALOME_EXPORT YACS::ENGINE::Any *convertPyObjectNeutral(const TypeCode *t,PyObject* ob);
+    YACSRUNTIMESALOME_EXPORT PyObject* convertPyObjectPyObject(const TypeCode *t,PyObject *ob);
+    YACSRUNTIMESALOME_EXPORT std::string convertPyObjectToString(PyObject* ob);
+    YACSRUNTIMESALOME_EXPORT bool checkPyObject(const TypeCode *t,PyObject* ob);
+
+    YACSRUNTIMESALOME_EXPORT PyObject *convertXmlPyObject(const TypeCode * t,xmlDocPtr doc,xmlNodePtr cur );
+    YACSRUNTIMESALOME_EXPORT PyObject *convertXmlStrPyObject(const TypeCode * t,std::string data );
+    YACSRUNTIMESALOME_EXPORT CORBA::Any *convertXmlCorba(const TypeCode * t,xmlDocPtr doc,xmlNodePtr cur );
+    YACSRUNTIMESALOME_EXPORT YACS::ENGINE::Any *convertXmlNeutral(const TypeCode * t,xmlDocPtr doc,xmlNodePtr cur );
+
+    YACSRUNTIMESALOME_EXPORT PyObject *convertNeutralPyObject(const TypeCode * t,YACS::ENGINE::Any* ob);
+    YACSRUNTIMESALOME_EXPORT std::string convertNeutralXml(const TypeCode * t,YACS::ENGINE::Any* ob);
+    YACSRUNTIMESALOME_EXPORT CORBA::Any *convertNeutralCorba(const TypeCode *t,YACS::ENGINE::Any *ob);
+    YACSRUNTIMESALOME_EXPORT YACS::ENGINE::Any *convertNeutralNeutral(const TypeCode *t, YACS::ENGINE::Any* ob);
   }
 
 }
diff --git a/src/runtime/VisitorSalomeSaveState.cxx b/src/runtime/VisitorSalomeSaveState.cxx
new file mode 100644 (file)
index 0000000..e6b3d7e
--- /dev/null
@@ -0,0 +1,123 @@
+// 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
+//
+
+#include "VisitorSalomeSaveState.hxx"
+#include "TypeConversions.hxx"
+#include "ForEachLoop.hxx"
+#include "Proc.hxx"
+#include "Executor.hxx"
+#include "AutoLocker.hxx"
+
+#include "YacsTrace.hxx"
+
+using namespace YACS::ENGINE;
+
+VisitorSalomeSaveState::VisitorSalomeSaveState(ComposedNode *root)
+:VisitorSaveState(root)
+{
+}
+
+VisitorSalomeSaveState::~VisitorSalomeSaveState()
+{
+}
+
+void VisitorSalomeSaveState::visitForEachLoop(ForEachLoop *node)
+{
+  node->ComposedNode::accept(this);
+  if (!_out) throw Exception("No file open for dump state");
+  std::string name = _root->getName();
+  if (static_cast<ComposedNode*>(node) != _root) name = _root->getChildName(node);
+  DEBTRACE("VisitorSaveState::visitForEachLoop ------ " << name);
+  _out << "  <node type='forEachLoop'>" << std::endl;
+  _out << "    <name>" << name << "</name>" << std::endl;
+  _out << "    <state>" << _nodeStateName[node->getState()] << "</state>" << std::endl;
+//  VisitorSaveState::visitForEachLoop(node);
+  std::list<InputPort *> setOfInputPort = node->getLocalInputPorts();
+  std::list<InputPort *>::iterator iter;
+  for(iter = setOfInputPort.begin(); iter != setOfInputPort.end(); iter++)
+  {
+    _out << "    <inputPort>" << std::endl;
+    _out << "      <name>" << (*iter)->getName() << "</name>" << std::endl;
+    try
+      {
+        _out << "      ";
+        _out << (*iter)->dump();
+      }
+    catch (YACS::Exception &e)
+      {
+        DEBTRACE("caught YACS:Exception: " << e.what());
+        _out << "<value><error><![CDATA[" << e.what() << "]]></error></value>" << std::endl;
+      }
+    _out << "    </inputPort>" << std::endl;
+  }
+  
+  StatesForNode state = node->getState();
+  if(YACS::LOADED == state ||
+    YACS::ACTIVATED == state ||
+    YACS::SUSPENDED == state ||
+    YACS::EXECFAILED == state ||
+    YACS::PAUSE == state ||
+    YACS::TORECONNECT == state ||
+    YACS::INTERNALERR == state ||
+    YACS::FAILED == state ||
+    YACS::ERROR == state)
+  {
+    ForEachLoopPassedData* processedData = node->getProcessedData();
+    if(processedData)
+    {
+      const std::vector<unsigned int>& processedIndexes = processedData->getIds();
+      std::vector<SequenceAny *>::const_iterator it_outputs;
+      std::vector<std::string>::const_iterator it_names;
+      
+      for(it_outputs = processedData->getOutputs().begin(), it_names = processedData->getOutputNames().begin();
+          it_names != processedData->getOutputNames().end();
+          it_outputs++, it_names++)
+      {
+        _out << "    <loopOutputPort>" << std::endl;
+        _out << "      <name>" << (*it_names) << "</name>" << std::endl;
+        for(unsigned int i = 0; i < (*it_outputs)->size(); i++)
+        {
+          AnyPtr value = (*(*it_outputs))[i];
+          _out << "      <sample><index>" << processedIndexes[i]<< "</index>";
+          if(value)
+            _out << convertNeutralXml(value->getType(), value);
+          else
+            _out << "<value>None</value>";
+          _out << "      </sample>" << std::endl;
+        }
+        _out << "    </loopOutputPort>" << std::endl;
+      }
+      
+      delete processedData;
+      processedData = NULL;
+    }
+  }
+  _out << "  </node>" << std::endl;
+}
+
+void YACS::ENGINE::schemaSaveState(Proc* proc,
+                                  Executor* exec,
+                                  const std::string& xmlSchemaFile)
+{
+  YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&(exec->getTheMutexForSchedulerUpdate()));
+  VisitorSalomeSaveState vss(proc);
+  vss.openFileDump(xmlSchemaFile);
+  proc->accept(&vss);
+  vss.closeFileDump();
+}
diff --git a/src/runtime/VisitorSalomeSaveState.hxx b/src/runtime/VisitorSalomeSaveState.hxx
new file mode 100644 (file)
index 0000000..ceb4afd
--- /dev/null
@@ -0,0 +1,44 @@
+// 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
+//
+
+#ifndef VISITORSALOMESAVESTATE_HXX
+#define VISITORSALOMESAVESTATE_HXX
+
+#include "VisitorSaveState.hxx"
+#include "YACSRuntimeSALOMEExport.hxx"
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Executor;
+    class YACSRUNTIMESALOME_EXPORT VisitorSalomeSaveState : public VisitorSaveState
+    {
+      public:
+      VisitorSalomeSaveState(ComposedNode *root);
+      virtual ~VisitorSalomeSaveState();
+      virtual void visitForEachLoop(ForEachLoop *node);
+    };
+
+    YACSLIBENGINE_EXPORT void schemaSaveState(Proc* proc,
+                                              Executor* exec,
+                                              const std::string& xmlSchemaFile);
+  }
+}
+#endif // VISITORSALOMESAVESTATE_HXX
index ef7d9c195ab491007550c15a3b3bce64d4813d2d..2349fd6711fd87c1f1fa2e40325ec3eb62a7679e 100644 (file)
@@ -93,6 +93,7 @@ SET(SWIGINCLUDES
   ${PROJECT_SOURCE_DIR}/src/runtime/CORBAPorts.hxx
   ${PROJECT_SOURCE_DIR}/src/runtime/TypeConversions.hxx
   ${PROJECT_SOURCE_DIR}/src/runtime/SalomeOptimizerLoop.hxx
+  ${PROJECT_SOURCE_DIR}/src/runtime/VisitorSalomeSaveState.hxx
   )
 SET(SWIG_MODULE_SALOMERuntime_EXTRA_DEPS 
     ${PROJECT_SOURCE_DIR}/src/engine_swig/pilot.i 
index db43272d647ea4bab76356a6e97c30869bf9db6f..4aab32a826056ecd1b4d6aadf0cce1a19a3d62f5 100644 (file)
 #include "TypeConversions.hxx"
 #include "TypeCode.hxx"
 #include "VisitorSaveSalomeSchema.hxx"
+#include "VisitorSalomeSaveState.hxx"
 #include "SalomeOptimizerLoop.hxx"
 #include "DistributedPythonNode.hxx"
 #include "PyOptimizerAlg.hxx"
 #include "PyStdout.hxx"
+#include "ExecutorSwig.hxx"
 #include <sstream>
 %}
 
 %include "SalomeOptimizerLoop.hxx"
 %include "DistributedPythonNode.hxx"
 
+namespace YACS
+{
+  namespace ENGINE
+  {
+    void schemaSaveState(Proc* proc,
+                         Executor* exec,
+                         const std::string& xmlSchemaFile);
+  }
+}
+
+
 %extend YACS::ENGINE::OutputPresetPort
 {
   void setDataPy(PyObject *ob)
index 91901249cbd872ce75be020b269da5e394f73bf1..1754ea07142bbc3a865ef03190e66f69ad841409 100644 (file)
@@ -74,6 +74,7 @@ SET(YACSloader_LIBRARIES
   ${OMNIORB_LIBRARIES}
   ${LIBXML2_LIBRARIES}
   YACSlibEngine
+  YACSRuntimeSALOME
   )
 SET(_link_LIBRARIES
   YACSloader
index faaa1a5fdd5ea162fa6bc29f97458f028418758f..6e6e3faeee93592e1e4810f428481e4c2abb2d8e 100644 (file)
@@ -27,6 +27,9 @@
 #include "Runtime.hxx"
 #include "InputPort.hxx"
 #include "ElementaryNode.hxx"
+#include "ForEachLoop.hxx"
+#include "Any.hxx"
+#include "TypeConversions.hxx"
 
 #include <iostream>
 #include <string>
@@ -231,6 +234,7 @@ public:
 void nodeParser::init(const xmlChar** p, xmlParserBase* father)
 {
   DEBTRACE("nodeParser::init()");
+  _loopSamples.clear();
   _state = XMLINNODE;
   _father = father;
   _stackState.push(_state);
@@ -250,6 +254,12 @@ void nodeParser::onStart (const XML_Char* elem, const xmlChar** p)
   else if (element == "nbdone")    parser = new attrParser();
   else if (element == "condition") parser = new attrParser();
   else if (element == "outputPort") parser = new outputParser();
+  else if (element == "loopOutputPort")
+  {
+    loopPortParser* sparser = new loopPortParser();
+    _loopSamples.push_back(sparser);
+    parser = sparser;
+  }
   else
     { 
       _what = "expected name, state or inputPort, got <" + element + ">";
@@ -362,10 +372,118 @@ void nodeParser::onEnd   (const XML_Char* name)
         }
       mySwitch->edGetConditionPort()->edInit(condition);
     }
+  else if (nodeType == "forEachLoop")
+  {
+    ForEachLoop* feNode = dynamic_cast<ForEachLoop*>(node);
+    if(!feNode)
+    {
+      _what = "node is not a ForEachLoop: " + _mapAttrib["name"];
+      _state = XMLFATALERROR;
+      stopParse(_what);
+    }
+    else
+    {
+      std::vector<unsigned int> passedIds;
+      std::vector<SequenceAny *> passedOutputs;
+      std::vector<std::string> nameOfOutputs;
+      bool firstPort = true;
+      std::list<loopPortParser*>::const_iterator itPort;
+      for(itPort=_loopSamples.begin(); itPort!=_loopSamples.end(); itPort++)
+      {
+        const std::string& portName =(*itPort)->getPortName();
+        nameOfOutputs.push_back(portName);
+        const YACS::ENGINE::TypeCode* tc = feNode->getOutputPortType(portName);
+        if(!tc)
+        {
+          _what = "Impossible to find the type of the port " + portName;
+          _state = XMLFATALERROR;
+          stopParse(_what);
+          return;
+        }
+        unsigned int nbSamples = (*itPort)->getNbSamples();
+        SequenceAny* seqValues = SequenceAny::New(tc, nbSamples);
+        passedOutputs.push_back(seqValues);
+        for(unsigned int i = 0; i < nbSamples; i++)
+        {
+          unsigned int sampleId = (*itPort)->getSampleId(i);
+          const std::string& sampleData = (*itPort)->getSampleData(i);
+          Any* value = xmlToAny(sampleData, tc);
+          if(firstPort)
+          {
+            passedIds.push_back(sampleId);
+            seqValues->setEltAtRank(i, value);
+          }
+          else
+          {
+            unsigned int pos = 0;
+            while(pos < passedIds.size() && sampleId != passedIds[pos])
+              pos++;
+            if(pos < passedIds.size())
+              seqValues->setEltAtRank(pos, value);
+            else
+            {
+              _what = "Inconsistent sample id in foreach node " + _mapAttrib["name"];
+              _state = XMLFATALERROR;
+              stopParse(_what);
+              itPort=_loopSamples.end();
+              return;
+            }
+          }
+        }
+        firstPort = false;
+      }
+      feNode->assignPassedResults(passedIds, passedOutputs, nameOfOutputs);
+    }
+  }
 
   stateParser::onEnd(name);
 }
 
+Any* nodeParser::xmlToAny(const std::string& data, const YACS::ENGINE::TypeCode* tc)const
+{
+  xmlDocPtr doc;
+  xmlNodePtr cur;
+  //YACS::ENGINE::Any *ob=YACS::ENGINE::AtomAny::New(0);
+  YACS::ENGINE::Any *ob=NULL;
+  {
+    doc = xmlParseMemory(data.c_str(), data.length());
+    if (doc == NULL )
+      {
+        stringstream msg;
+        msg << "Problem in conversion: XML Document not parsed successfully ";
+        msg << " (" << __FILE__ << ":" << __LINE__ << ")";
+        throw ConversionException(msg.str());
+      }
+    cur = xmlDocGetRootElement(doc);
+    if (cur == NULL)
+      {
+        xmlFreeDoc(doc);
+        stringstream msg;
+        msg << "Problem in conversion: empty XML Document";
+        msg << " (" << __FILE__ << ":" << __LINE__ << ")";
+        throw ConversionException(msg.str());
+      }
+    while (cur != NULL)
+      {
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"value")))
+          {
+            ob=convertXmlNeutral(tc,doc,cur);
+            break;
+          }
+        cur = cur->next;
+      }
+    xmlFreeDoc(doc);
+    if(ob==NULL)
+      {
+        stringstream msg;
+        msg << "Problem in conversion: incorrect XML value";
+        msg << " (" << __FILE__ << ":" << __LINE__ << ")";
+        throw ConversionException(msg.str());
+      }
+  }
+  return ob;
+}
+
 // ----------------------------------------------------------------------------
 
 void attrParser::init(const xmlChar** p, xmlParserBase* father)
@@ -470,11 +588,13 @@ void portParser::onEnd   (const XML_Char* name)
       what += " in node " + nodeName + " of type " + nodeType;
       throw Exception(what);
     }
-  else if (nodeType == "foreachLoop")
+  else if (nodeType == "forEachLoop")
     {
-      string what="no way to set a port value on port " +  _mapAttrib["name"];
-      what += " in node " + nodeName + " of type " + nodeType;
-      throw Exception(what);
+      ForEachLoop* eNode = dynamic_cast<ForEachLoop*>(node);
+      YASSERT(eNode);
+      InputPort *port = eNode->getInputPort(_mapAttrib["name"]);
+      if(_data != "")
+        port->edInit("XML",_data.c_str());
     }
   else 
     {
@@ -660,7 +780,130 @@ void simpleTypeParser::charData(std::string data)
   _data = _data + data;
 }
 
+// ----------------------------------------------------------------------------
+
+void loopPortParser::init(const xmlChar** p, xmlParserBase* father)
+{
+  DEBTRACE("loopPortParser::init()");
+  //_state = XMLINPORT;
+  _father = father;
+  _stackState.push(_state);
+  _ids.clear();
+  _sampleData.clear();
+  if (p) getAttributes(p);
+}
+
+void loopPortParser::onStart(const XML_Char* elem, const xmlChar** p)
+{
+  DEBTRACE("loopPortParser::onStart" << elem);
+  string element(elem);
+  stateParser *parser = 0;
+  if (element == "name")      parser = new attrParser();
+  else if (element == "sample") parser = new sampleParser(this);
+  else
+    { 
+      _what = "expected name or sample, got <" + element + ">";
+      _state = XMLFATALERROR;
+      stopParse(_what);
+    }
+  if (parser)
+    {
+      _stackParser.push(parser);
+      XML_SetUserData(_xmlParser, parser);
+      parser->init(p, this);
+    }
+}
+
+void loopPortParser::onEnd(const XML_Char* name)
+{
+  stateParser::onEnd(name);
+}
+
+void loopPortParser::charData(std::string data)
+{
+}
+
+void loopPortParser::addSample(int index, const std::string data)
+{
+  _ids.push_back(index);
+  _sampleData.push_back(data);
+}
+
+unsigned int loopPortParser::getNbSamples()const
+{
+  return _ids.size();
+}
+
+unsigned int loopPortParser::getSampleId(unsigned int i)const
+{
+  return _ids[i];
+}
+
+const std::string& loopPortParser::getSampleData(unsigned int i)const
+{
+  return _sampleData[i];
+}
+
+const std::string& loopPortParser::getPortName()const
+{
+  return _mapAttrib.at("name");
+}
+
+// ----------------------------------------------------------------------------
+
+sampleParser::sampleParser(loopPortParser* father)
+: stateParser(),
+  _sampleFather(father)
+{
+}
+
+void sampleParser::init(const xmlChar** p, xmlParserBase* father)
+{
+  DEBTRACE("sampleParser::init()");
+  //_state = XMLINPORT;
+  _father = father;
+  _stackState.push(_state);
+  if (p) getAttributes(p);
+}
+
+void sampleParser::onStart(const XML_Char* elem, const xmlChar** p)
+{
+  DEBTRACE("sampleParser::onStart" << elem);
+  string element(elem);
+  stateParser *parser = 0;
+  if (element == "index")      parser = new attrParser();
+  else if (element == "value") parser = new valueParser();
+  else
+    { 
+      _what = "expected index or value, got <" + element + ">";
+      _state = XMLFATALERROR;
+      stopParse(_what);
+    }
+  if (parser)
+    {
+      _stackParser.push(parser);
+      XML_SetUserData(_xmlParser, parser);
+      parser->init(p, this);
+    }
+}
 
+void sampleParser::onEnd(const XML_Char* name)
+{
+  if (_mapAttrib.find("index") == _mapAttrib.end())
+    {
+      _what = "no attribute index in sample ";
+      _state = XMLFATALERROR;
+      stopParse(_what);
+    }
+  int index =  atoi(_mapAttrib["index"].c_str());
+  _sampleFather->addSample(index, _data);
+  stateParser::onEnd(name);
+}
+
+void sampleParser::charData(std::string data)
+{
+  _data = _data + data;
+}
 
 // ----------------------------------------------------------------------------
 
index 3935d569ee57d9504a8e3157f2de9ed5e20ebb7e..1e74f2889002f855fc5dd9462366f95288c32daa 100644 (file)
 
 #include "YACSloaderExport.hxx"
 #include "xmlParserBase.hxx"
+#include "InputPort.hxx"
 
 #include "define.hxx"
 #include "Exception.hxx"
+#include <vector>
+#include <list>
 
 namespace YACS
 {
@@ -32,6 +35,9 @@ namespace YACS
   {
     class Proc;
     class Runtime;
+    class SequenceAny;
+    class Any;
+    class TypeCode;
 
     //! Load state from a file into a Proc
     /*!
@@ -96,6 +102,7 @@ namespace YACS
       static std::map<std::string, YACS::StatesForNode> _nodeStates;
     };
 
+#ifndef SWIG
     class YACSLOADER_EXPORT graphParser: public stateParser
     {
     public:
@@ -105,14 +112,18 @@ namespace YACS
     };
 
 
+    class loopPortParser;
     class YACSLOADER_EXPORT nodeParser: public stateParser
     {
     public:
       virtual void init(const xmlChar** p, xmlParserBase* father=0);
       virtual void onStart (const XML_Char* elem, const xmlChar** p);
       virtual void onEnd   (const XML_Char* name);
+      Any* xmlToAny(const std::string& data, const TypeCode* tc)const;
       std::string _nodeName;
       std::string _nodeState;
+    private:
+      std::list<loopPortParser*> _loopSamples;
     };
 
     class YACSLOADER_EXPORT attrParser: public stateParser
@@ -172,6 +183,37 @@ namespace YACS
       virtual void charData(std::string data);
     };
 
+    class YACSLOADER_EXPORT loopPortParser: public stateParser
+    {
+    public:
+      virtual void init(const xmlChar** p, xmlParserBase* father=0);
+      virtual void onStart (const XML_Char* elem, const xmlChar** p);
+      virtual void onEnd   (const XML_Char* name);
+      virtual void charData(std::string data);
+      void addSample(int index, const std::string data);
+      unsigned int getNbSamples()const;
+      unsigned int getSampleId(unsigned int i)const;
+      const std::string& getSampleData(unsigned int i)const;
+      const std::string& getPortName()const;
+    private:
+      std::vector<unsigned int> _ids;
+      std::vector<std::string> _sampleData;
+    };
+
+    class YACSLOADER_EXPORT sampleParser: public stateParser
+    {
+    public:
+      sampleParser(loopPortParser* father);
+      virtual void init(const xmlChar** p, xmlParserBase* father=0);
+      virtual void onStart (const XML_Char* elem, const xmlChar** p);
+      virtual void onEnd   (const XML_Char* name);
+      virtual void charData(std::string data);
+    //protected:
+    //  Any* xmlToAny()throw(ConversionException);
+    private:
+      loopPortParser* _sampleFather;
+    };
+#endif
   }
 }
 #endif
index 2a898e860d152367b62d799f86f4d3f37e163e2f..a26298375d163a22c8f8bbff4740039a76b4f146 100644 (file)
@@ -24,7 +24,7 @@
 #include "Exception.hxx"
 #include "Executor.hxx"
 #include "parsers.hxx"
-#include "VisitorSaveState.hxx"
+#include "VisitorSalomeSaveState.hxx"
 #include "VisitorSaveSalomeSchema.hxx"
 #include "LoadState.hxx"
 #include "Dispatcher.hxx"
@@ -272,7 +272,7 @@ void Handler(int theSigId)
       bool isFinalDump = (strlen(myArgs.finalDump) != 0);
       if (isFinalDump)
         {
-          YACS::ENGINE::VisitorSaveState vst(p);
+          YACS::ENGINE::VisitorSalomeSaveState vst(p);
           vst.openFileDump(myArgs.finalDump);
           p->accept(&vst);
           vst.closeFileDump();
@@ -308,7 +308,7 @@ void * dumpState(void *arg)
 #endif
     string cmd = "touch " + st->lockFile;
     system(cmd.c_str());
-    YACS::ENGINE::VisitorSaveState vst(p);
+    YACS::ENGINE::VisitorSalomeSaveState vst(p);
     vst.openFileDump(st->dumpFile);
     p->accept(&vst);
     vst.closeFileDump();
@@ -600,7 +600,7 @@ int main (int argc, char* argv[])
       bool isFinalDump = (strlen(myArgs.finalDump) != 0);
       if (isFinalDump)
         {
-          YACS::ENGINE::VisitorSaveState vst(p);
+          YACS::ENGINE::VisitorSalomeSaveState vst(p);
           vst.openFileDump(myArgs.finalDump);
           p->accept(&vst);
           vst.closeFileDump();
index 7caa12bb3351ada3664c90f34578254e1aa298b7..75c6f05ff304eab36ae503bf2d36ecfed18231b2 100755 (executable)
@@ -1516,7 +1516,7 @@ o2=2*i1
     myRun.start()
     import time
     time.sleep(5)
-    p.saveState(xmlStateFileName)
+    SALOMERuntime.schemaSaveState(p, ex, xmlStateFileName)
     a,b,c=n1.getPassedResults(ex)
     myRun.join()
     t0=datetime.now()-startt
@@ -1547,6 +1547,39 @@ o2=5*i1
     pass
   pass
 
+  def test22(self):
+    """Restart from a saved state in a foreach loop without using assignPassedResults.
+       This test uses the files test21.xml and saveState21.xml produced by test21.
+    """
+    fname="test21.xml"
+    xmlStateFileName="saveState21.xml"
+
+    ex=pilot.ExecutorSwig()
+    l=loader.YACSLoader()
+    q=l.load(fname)
+    q.getChildByName("n0").setScript("o0=[ 3*elt for elt in range(6) ]")
+    q.getChildByName("n1").getChildByName("n10").setScript("""
+import time
+time.sleep(0.1)
+print "execution n10:", i1
+o2=5*i1
+""")
+    q.getChildByName("n2").setScript("""
+print "execution n2:", i3
+o4=i3
+""")
+    loader.loadState(q, xmlStateFileName)
+    q.resetState(1)
+    q.exUpdateState()
+    #
+    ex.RunW(q,0,False)
+    #
+    self.assertEqual(q.getChildByName("n1").getState(),pilot.DONE)
+    self.assertEqual(q.getState(),pilot.DONE)
+    self.assertEqual(q.getChildByName("n2").getOutputPort("o4").getPyObj(),[0L,2L,10L,15L,20L,25L])
+    pass
+  pass
+
 if __name__ == '__main__':
   import os,sys
   U = os.getenv('USER')