Salome HOME
First implementation of evalyfx.
authorAnthony Geay <anthony.geay@edf.fr>
Tue, 21 Apr 2015 16:43:15 +0000 (18:43 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Wed, 10 Jun 2015 08:28:52 +0000 (10:28 +0200)
37 files changed:
src/CMakeLists.txt
src/engine/Bloc.cxx
src/engine/Bloc.hxx
src/engine/DynParaLoop.cxx
src/engine/DynParaLoop.hxx
src/engine/ElementaryNode.hxx
src/engine/InlineNode.cxx
src/engine/InlineNode.hxx
src/engine/Loop.cxx
src/engine/Loop.hxx
src/engine/Node.hxx
src/engine/Proc.cxx
src/engine/Proc.hxx
src/engine/Switch.cxx
src/engine/Switch.hxx
src/engine/VisitorSaveSchema.cxx
src/evalyfx/CMakeLists.txt [new file with mode: 0644]
src/evalyfx/YACSEvalAutoPtr.hxx [new file with mode: 0644]
src/evalyfx/YACSEvalPort.cxx [new file with mode: 0644]
src/evalyfx/YACSEvalPort.hxx [new file with mode: 0644]
src/evalyfx/YACSEvalResource.cxx [new file with mode: 0644]
src/evalyfx/YACSEvalResource.hxx [new file with mode: 0644]
src/evalyfx/YACSEvalSeqAny.cxx [new file with mode: 0644]
src/evalyfx/YACSEvalSeqAny.hxx [new file with mode: 0644]
src/evalyfx/YACSEvalSession.cxx [new file with mode: 0644]
src/evalyfx/YACSEvalSession.hxx [new file with mode: 0644]
src/evalyfx/YACSEvalYFX.cxx [new file with mode: 0644]
src/evalyfx/YACSEvalYFX.hxx [new file with mode: 0644]
src/evalyfx/YACSEvalYFXExport.hxx [new file with mode: 0644]
src/evalyfx/YACSEvalYFXPattern.cxx [new file with mode: 0644]
src/evalyfx/YACSEvalYFXPattern.hxx [new file with mode: 0644]
src/evalyfx_swig/CMakeLists.txt [new file with mode: 0644]
src/evalyfx_swig/evalyfx.i [new file with mode: 0644]
src/evalyfx_swig/test.py [new file with mode: 0644]
src/evalyfx_swig/test0.xml [new file with mode: 0644]
src/evalyfx_swig/testEvalYFX.py [new file with mode: 0644]
src/runtime/CORBAPorts.hxx

index 621a019ce94bd0ff545516e03285ed0d485f6fa0..ce9cc73c5912ba19f3f1b2d5e1d7fd608041daf4 100755 (executable)
@@ -29,36 +29,26 @@ SET(SUBDIRS_COMMON
 # KERNEL
 ##
 IF(SALOME_YACS_USE_KERNEL)
-  SET(SUBDIRS_KERNEL
-    runtime yacsloader
-    )
-ENDIF()
+  SET(SUBDIRS_KERNEL runtime yacsloader evalyfx)
+ENDIF(SALOME_YACS_USE_KERNEL)
 
 ##
 # SWIG wrapping
 ##
 IF(SALOME_YACS_USE_SWIG)
-  SET(SUBDIRS_SWIG
-    engine_swig
-  )
+  SET(SUBDIRS_SWIG engine_swig)
   IF(SALOME_YACS_USE_KERNEL)
-    LIST(APPEND SUBDIRS_SWIG
-      runtime_swig yacsloader_swig
-    )
-  ENDIF()
-ENDIF()
+    LIST(APPEND SUBDIRS_SWIG runtime_swig yacsloader_swig evalyfx_swig)
+  ENDIF(SALOME_YACS_USE_KERNEL)
+ENDIF(SALOME_YACS_USE_SWIG)
 
 ##
 # GUI
 ##
 IF(SALOME_BUILD_GUI)
-  SET(SUBDIRS_GUI
-    pyqt hmi salomewrap genericgui salomegui
-    )
+  SET(SUBDIRS_GUI pyqt hmi salomewrap genericgui salomegui)
   IF(SALOME_YACS_USE_SWIG)
-    LIST(APPEND SUBDIRS_GUI
-      salomegui_swig
-      )
+    LIST(APPEND SUBDIRS_GUI salomegui_swig)
   ENDIF()
 ENDIF()
 
index efe4dba100aeb60e6d2b51603fd20f75536e6647..d4822f5b5494c05a023a091406727dc72b00a016 100644 (file)
@@ -27,6 +27,7 @@
 #include "Visitor.hxx"
 
 #include <iostream>
+#include <numeric>
 
 //#define _DEVDEBUG_
 #include "YacsTrace.hxx"
@@ -393,6 +394,45 @@ void Bloc::accept(Visitor* visitor)
   visitor->visitBloc(this);
 }
 
+/*!
+ * Returns the max level of parallelism is this. The max of parallelism is equal to the sum of the max parallelism level
+ * for all concurrent branches in \a this.
+ */
+int Bloc::getMaxLevelOfParallelism() const
+{
+  std::set<Node *> s(_setOfNode.begin(),_setOfNode.end());
+  for(std::set<Node *>::const_iterator it=s.begin();it!=s.end();it++)
+    (*it)->_colour=White;
+  std::vector<int> levs;
+  while(!s.empty())
+    {
+      Node *seed(*(s.begin()));
+      int myCurLev(0);
+      while(seed)
+        {
+          s.erase(seed);
+          std::set<InGate *> ingates(seed->getOutGate()->edSetInGate());
+          int myCurLev2(1);
+          for(std::set<InGate *>::const_iterator it=ingates.begin();it!=ingates.end();it++)
+            {
+              Node *curNode((*it)->getNode());
+              curNode->_colour=Grey;
+              myCurLev2=std::max(curNode->getMaxLevelOfParallelism(),myCurLev2);
+            }
+          myCurLev=std::max(myCurLev,myCurLev2);
+          seed=0;
+          for(std::set<Node *>::const_iterator it=s.begin();it!=s.end();it++)
+            if((*it)->_colour==Grey)
+              {
+                seed=*it;
+                break;
+              }
+        }
+      levs.push_back(myCurLev);
+    }
+  return std::accumulate(levs.begin(),levs.end(),0);
+}
+
 /*!
  * Updates mutable structures _fwLinks and _bwLinks with the result of computation (CPU consuming method).
  * _fwLinks is a map with a Node* as key and a set<Node*> as value. The set gives
index 43d118b2cd260945f9c3ce798577853599cc986b..0bd35120d27a6d7bf648a66e6675705d0d623e97 100644 (file)
@@ -58,7 +58,8 @@ namespace YACS
       void findAllPathsStartingFrom(Node *start, std::list< std::vector<Node *> >& vec, std::map<Node *, std::set<Node *> >& accelStr) const;
       template<bool direction>
       void findAllNodesStartingFrom(Node *start, std::set<Node *>& result, std::map<Node *, std::set<Node *> >& accelStr, LinkInfo& info) const;
-      virtual std::string typeName() {return "YACS__ENGINE__Bloc";}
+      virtual std::string typeName() { return "YACS__ENGINE__Bloc"; }
+      int getMaxLevelOfParallelism() const;
     protected:
       bool areAllSubNodesFinished() const;
       bool areAllSubNodesDone() const;
index 0564dabd0fdd3048a03458a0e80169287949be22..ac42a27d29439888960546c2b6d96fe8ebdf59c7 100644 (file)
@@ -805,6 +805,11 @@ Node * DynParaLoop::getFinalizeNode()
   return _finalizeNode;
 }
 
+int DynParaLoop::getMaxLevelOfParallelism() const
+{
+  return _nbOfBranches.getIntValue();
+}
+
 void DynParaLoop::shutdown(int level)
 {
   if(level==0)return;
index 3a29a872d0ef9a3f140d054c92212383adb112f7..14db8b2f9d763646bed2164656a89fce144447ac 100644 (file)
@@ -104,6 +104,7 @@ namespace YACS
       Node * getInitNode();
       Node * getExecNode();
       Node * getFinalizeNode();
+      int getMaxLevelOfParallelism() const;
     protected:
       void buildDelegateOf(InPort * & port, OutPort *initialStart, const std::list<ComposedNode *>& pointsOfView);
       void buildDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView);
index db82867dd1f77e12ad6711455c7fcf87f821549b..843de41e12e8140931381c11ebe46ccb15dc8c77 100644 (file)
@@ -105,6 +105,8 @@ namespace YACS
       virtual void edUpdateState();
       virtual void ensureLoading();
 
+      int getMaxLevelOfParallelism() const { return 1; }
+
       //run part
       void begin();
       bool isReady();
index ac0c0c38feba722e5bb7405f0b29cfd8193a8569..2d229864585e742d323f25a65da7fcf3e99f08c1 100644 (file)
@@ -28,6 +28,9 @@
 using namespace YACS::ENGINE;
 using namespace std;
 
+const char InlineNode::LOCAL_STR[]="local";
+
+const char InlineNode::REMOTE_STR[]="remote";
 
 InlineNode::~InlineNode()
 {
@@ -82,7 +85,7 @@ void InlineFuncNode::checkBasicConsistency() const throw(YACS::Exception)
 void InlineNode::setExecutionMode(const std::string& mode)
 {
   if(mode == _mode)return;
-  if(mode == "local"||mode == "remote")
+  if(mode == LOCAL_STR || mode == REMOTE_STR)
     {
       _mode=mode;
       modified();
@@ -130,7 +133,7 @@ void InlineNode::performShallowDuplicationOfPlacement(const Node& other)
 
 bool InlineNode::isDeployable() const
 {
-  if(_mode=="remote")
+  if(_mode==REMOTE_STR)
     return true;
   else
     return false;
index 891acb0657873bc92091a857630252014a07e9ea..f6582d599ceec6767be73c6cc946aadd071e3f7d 100644 (file)
@@ -45,7 +45,7 @@ namespace YACS
     protected:
       InlineNode(const InlineNode& other, ComposedNode *father)
         :ElementaryNode(other,father),_script(other._script),_mode(other._mode),_container(0) { }
-      InlineNode(const std::string& name):ElementaryNode(name),_mode("local"),_container(0) { }
+      InlineNode(const std::string& name):ElementaryNode(name),_mode(LOCAL_STR),_container(0) { }
     public:
       virtual void setScript(const std::string& script);
       virtual std::string getScript(){return _script;}
@@ -67,6 +67,9 @@ namespace YACS
       void performDuplicationOfPlacement(const Node& other);
       void performShallowDuplicationOfPlacement(const Node& other);
       bool isDeployable() const;
+    public:
+      static const char LOCAL_STR[];
+      static const char REMOTE_STR[];
     protected:
       std::string _script;
       std::string _mode;
index ccf1375df46f6f5215df1ca3ecce5181d267a66b..8ce0063e627a2762f2b17a7f6a86db4735fca5c5 100644 (file)
@@ -412,6 +412,13 @@ int Loop::getNumberOfInputPorts() const
   return StaticDefinedComposedNode::getNumberOfInputPorts()+1;
 }
 
+int Loop::getMaxLevelOfParallelism() const
+{
+  if(!_node)
+    return 0;
+  return _node->getMaxLevelOfParallelism();
+}
+
 Node *Loop::getChildByShortName(const std::string& name) const throw(YACS::Exception)
 {
   if (_node)
index 8917570f41d1ab111c537a9a6169657fa7c64d31..e1e86f61bd88e78dbbcc21cc58eb0b9b4a08c1ab 100644 (file)
@@ -172,6 +172,7 @@ namespace YACS
       std::list<Node *> edGetDirectDescendants() const;
       std::list<InputPort *> getSetOfInputPort() const;
       int getNumberOfInputPorts() const;
+      int getMaxLevelOfParallelism() const;
       Node *getChildByShortName(const std::string& name) const throw(Exception);
       static TypeCode* MappingDF2DS(TypeCode* type) throw(Exception);
       static TypeCode* MappingDS2DF(TypeCode* type) throw(Exception);
index 98b8dfaa34dd6f8b598b7cdb3a4c13ca0279704c..c724fb605226b88b0a7d0867646fa87afd587600 100644 (file)
@@ -164,6 +164,7 @@ namespace YACS
       virtual Proc *getProc();
       virtual const Proc *getProc() const;
       virtual void accept(Visitor *visitor) = 0;
+      virtual int getMaxLevelOfParallelism() const = 0;
       std::string getQualifiedName() const;
       int getNumId();
       virtual void sendEvent(const std::string& event);
index 3cc7eb291f19bb9d734d643bf483faffb277fca8..5f83fe162dc967e630e282360b65bc76ef8bdfff 100644 (file)
@@ -75,10 +75,7 @@ Proc::~Proc()
   for(pt=typeMap.begin();pt!=typeMap.end();pt++)
     ((*pt).second)->decrRef();
 
-  //get rid of containers in container map
-  std::map<std::string, Container*>::const_iterator it;
-  for(it=containerMap.begin();it!=containerMap.end();it++)
-    ((*it).second)->decrRef();
+  removeContainers();
 
   //get rid of loggers in logger map
   std::map<std::string, Logger*>::const_iterator lt;
@@ -463,6 +460,15 @@ void Proc::saveState(const std::string& xmlStateFile)
   vst.closeFileDump();
 }
 
+void Proc::removeContainers()
+{
+  //get rid of containers in container map
+  std::map<std::string, Container*>::const_iterator it;
+  for(it=containerMap.begin();it!=containerMap.end();it++)
+    ((*it).second)->decrRef();
+  containerMap.clear();
+}
+
 //! Create a new Container and store it in containerMap
 /*!
  * \param name: the container name and key in containerMap
@@ -580,3 +586,47 @@ const Proc * Proc::getProc() const
 {
   return this;
 }
+
+/*!
+ * This method is useful if this has been modified recursively and an update is needed between all the
+ * containers and components refered by children and little children and maps.
+ */
+void Proc::updateContainersAndComponents()
+{
+  std::map<std::string, Container*> myContainerMap;
+  std::map<std::string, ComponentInstance*> myComponentInstanceMap;
+  DeploymentTree treeToDup(getDeploymentTree());
+  vector<Container *> conts(treeToDup.getAllContainers());
+  for(vector<Container *>::const_iterator iterCt=conts.begin();iterCt!=conts.end();iterCt++)
+    {
+      Container *tmp(*iterCt);
+      if(tmp)
+        {
+          if(myContainerMap.find(tmp->getName())!=myContainerMap.end())
+            {
+              std::ostringstream oss; oss << "Proc::updateContainersAndComponents : more than one container instance with name \"" << tmp->getName() << "\" !";
+              throw YACS::Exception(oss.str());
+            }
+          myContainerMap[tmp->getName()]=tmp;
+          tmp->incrRef();
+        }
+      vector<ComponentInstance *> comps=treeToDup.getComponentsLinkedToContainer(*iterCt);
+      for(vector<ComponentInstance *>::iterator iterCp=comps.begin();iterCp!=comps.end();iterCp++)
+        {
+          ComponentInstance *tmp2(*iterCp);
+          if(tmp2)
+            {
+              if(myComponentInstanceMap.find(tmp2->getCompoName())!=myComponentInstanceMap.end())
+                {
+                  std::ostringstream oss; oss << "Proc::updateContainersAndComponents : more than one component instance with name \"" << tmp2->getCompoName() << "\" !";
+                  throw YACS::Exception(oss.str());
+                }
+            }
+          myComponentInstanceMap[tmp2->getCompoName()]=tmp2;
+          tmp2->incrRef();
+        }
+    }
+  removeContainers();
+  containerMap=myContainerMap;
+  componentInstanceMap=myComponentInstanceMap;
+}
index 5f84545d41afac40cab8e00c839159d60cae8dac..e4b8329a3a7ce7f525e9340e621ca1df7b13ff23 100644 (file)
@@ -63,6 +63,7 @@ namespace YACS
       virtual void accept(Visitor *visitor);
       virtual Proc *getProc();
       virtual const Proc *getProc() const;
+      virtual void updateContainersAndComponents();
 
       YACS::StatesForNode getNodeState(int numId);
       std::string getNodeProgress(int numId);
@@ -97,6 +98,8 @@ namespace YACS
       virtual void modified();
       virtual void saveSchema(const std::string& xmlSchemaFile);
       virtual void saveState(const std::string& xmlStateFile);
+    protected:
+      void removeContainers();
     protected:
       bool _edition;
       int _compoinstctr;
index 2c6fb63442f86ba696ae6adeee5156476d1d7ff8..f06d6d86b02a18677bcbbbc0c1cdb5dbf5790cc9 100644 (file)
@@ -400,6 +400,14 @@ int Switch::getNumberOfInputPorts() const
   return StaticDefinedComposedNode::getNumberOfInputPorts()+1;
 }
 
+int Switch::getMaxLevelOfParallelism() const
+{
+  int ret(0);
+  for(std::map< int , Node * >::const_iterator it=_mapOfNode.begin();it!=_mapOfNode.end();it++)
+    ret=std::max(ret,((*it).second)->getMaxLevelOfParallelism());
+  return ret;
+}
+
 void Switch::edRemoveChild(Node *node) throw(YACS::Exception)
 {
   map< int , Node * >::iterator iter=_mapOfNode.begin();
index f8a7dc3a6434dc982f54400454a80c0797673d5f..4d6670d131dba2134f34380df6b9e83e4545796a 100644 (file)
@@ -115,6 +115,7 @@ namespace YACS
       InputPort *edGetConditionPort() { return &_condition; }
       void writeDot(std::ostream &os) const;
       int getNumberOfInputPorts() const;
+      int getMaxLevelOfParallelism() const;
       void edRemoveChild(Node *node) throw(Exception);
       std::list<InputPort *> getSetOfInputPort() const;
       std::list<InputPort *> getLocalInputPorts() const;
index eed7e1b21df03a6cfd7ff3c30eec0fc42254d2d9..6563c0ed9c5a0ad6dad734f4264547a5bbe24066 100644 (file)
@@ -222,7 +222,7 @@ void VisitorSaveSchema::visitInlineNode(InlineNode *node)
   DEBTRACE("START visitInlineNode " << _root->getChildName(node));
   beginCase(node);
   int depth = depthNode(node);
-  if(node->getExecutionMode()=="local")
+  if(node->getExecutionMode()==InlineNode::LOCAL_STR)
     _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
   else
     _out << indent(depth) << "<remote name=\"" << node->getName() << "\"";
@@ -245,7 +245,7 @@ void VisitorSaveSchema::visitInlineNode(InlineNode *node)
   writeOutputPorts(node);
   writeOutputDataStreamPorts(node);
 
-  if(node->getExecutionMode()=="local")
+  if(node->getExecutionMode()==InlineNode::LOCAL_STR)
     _out << indent(depth) << "</inline>" << endl;
   else
     _out << indent(depth) << "</remote>" << endl;
@@ -259,7 +259,7 @@ void VisitorSaveSchema::visitInlineFuncNode(InlineFuncNode *node)
   DEBTRACE("START visitInlineFuncNode " << _root->getChildName(node));
   beginCase(node);
   int depth = depthNode(node);
-  if(node->getExecutionMode()=="local")
+  if(node->getExecutionMode()==InlineNode::LOCAL_STR)
     _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
   else
     _out << indent(depth) << "<remote name=\"" << node->getName() << "\"";
@@ -284,7 +284,7 @@ void VisitorSaveSchema::visitInlineFuncNode(InlineFuncNode *node)
   writeOutputPorts(node);
   writeOutputDataStreamPorts(node);
 
-  if(node->getExecutionMode()=="local")
+  if(node->getExecutionMode()==InlineNode::LOCAL_STR)
     _out << indent(depth) << "</inline>" << endl;
   else
     _out << indent(depth) << "</remote>" << endl;
diff --git a/src/evalyfx/CMakeLists.txt b/src/evalyfx/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8779522
--- /dev/null
@@ -0,0 +1,86 @@
+# Copyright (C) 2012-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
+#
+
+IF(SALOME_YACS_USE_KERNEL)
+  INCLUDE_DIRECTORIES(${KERNEL_INCLUDE_DIRS})
+  ADD_DEFINITIONS(${KERNEL_DEFINITIONS})
+  SET(SALOME_LIBS 
+    ${KERNEL_SalomeLifeCycleCORBA}
+    ${KERNEL_SalomeIDLKernel}
+    ${KERNEL_SalomeNS}
+    ${KERNEL_SalomeContainer}
+    ${KERNEL_SALOMEBasics}
+    ${KERNEL_SalomeResourcesManager}
+    ${KERNEL_OpUtil}
+    ${KERNEL_SALOMELocalTrace}
+    ${KERNEL_Registry}
+    ${KERNEL_SalomeNotification}
+    ${KERNEL_ResourcesManager}
+    ${KERNEL_SalomeHDFPersist}
+    ${KERNEL_SalomeGenericObj}
+    )
+ENDIF(SALOME_YACS_USE_KERNEL)
+
+# additional include directories
+INCLUDE_DIRECTORIES(
+  ${OMNIORB_INCLUDE_DIR}
+  ${PYTHON_INCLUDE_DIR}
+  ${PROJECT_SOURCE_DIR}/src/bases
+  ${PROJECT_SOURCE_DIR}/src/engine
+  ${PROJECT_SOURCE_DIR}/src/runtime
+  ${PROJECT_SOURCE_DIR}/src/yacsloader
+  )
+
+ADD_DEFINITIONS(
+  ${PYTHON_DEFINITIONS}
+  ${OMNIORB_DEFINITIONS}
+  )
+
+SET(YACSevalYFX_LIBRARIES
+  YACSloader
+  YACSRuntimeSALOME
+  ${SALOME_LIBS}
+  ${OMNIORB_LIBRARIES}
+  ${PYTHON_LIBRARIES}
+  ${LIBXML2_LIBRARIES}
+  )
+
+# no more than 4 files should be installed
+SET(YACSEvalYFX_HEADERS
+  YACSEvalYFXExport.hxx
+  YACSEvalYFX.hxx
+  YACSEvalPort.hxx
+  YACSEvalSeqAny.hxx
+  YACSEvalResource.hxx
+  YACSEvalSession.hxx
+  )
+
+SET(YACSevalYFX_SOURCES
+  YACSEvalYFX.cxx
+  YACSEvalYFXPattern.cxx
+  YACSEvalPort.cxx
+  YACSEvalSeqAny.cxx
+  YACSEvalResource.cxx
+  YACSEvalSession.cxx
+  )
+
+ADD_LIBRARY(YACSevalYFX ${YACSevalYFX_SOURCES})
+TARGET_LINK_LIBRARIES(YACSevalYFX ${YACSevalYFX_LIBRARIES})
+INSTALL(TARGETS YACSevalYFX EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS})
+INSTALL(FILES ${YACSEvalYFX_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS})
diff --git a/src/evalyfx/YACSEvalAutoPtr.hxx b/src/evalyfx/YACSEvalAutoPtr.hxx
new file mode 100644 (file)
index 0000000..4efdecb
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright (C) 2012-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
+// 
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef __YACSEVALYFXAUTOPTR_HXX__
+#define __YACSEVALYFXAUTOPTR_HXX__
+
+namespace YACS
+{
+  template<class T>
+  class AutoPtr
+  {
+  public:
+    AutoPtr(T *ptr=0):_ptr(ptr) {  }
+    ~AutoPtr() { destroyPtr(); }
+    AutoPtr &operator=(T *ptr) { if(_ptr!=ptr) { destroyPtr(); _ptr=ptr; } return *this; }
+    T *operator->() { return _ptr ; }
+    const T *operator->() const { return _ptr; }
+    T& operator*() { return *_ptr; }
+    const T& operator*() const { return *_ptr; }
+    operator T *() { return _ptr; }
+    operator const T *() const { return _ptr; }
+  private:
+    void destroyPtr() { delete [] _ptr; }
+  private:
+    T *_ptr;
+  };
+
+  template<class T>
+  class AutoCppPtr
+  {
+  public:
+    AutoCppPtr(T *ptr=0):_ptr(ptr) {  }
+    ~AutoCppPtr() { destroyPtr(); }
+    AutoCppPtr &operator=(T *ptr) { if(_ptr!=ptr) { destroyPtr(); _ptr=ptr; } return *this; }
+    T *operator->() { return _ptr ; }
+    const T *operator->() const { return _ptr; }
+    T& operator*() { return *_ptr; }
+    const T& operator*() const { return *_ptr; }
+    operator T *() { return _ptr; }
+    operator const T *() const { return _ptr; }
+    T *dettach() { T *ret(_ptr); _ptr=0; return ret; }
+  private:
+    void destroyPtr() { delete _ptr; }
+  private:
+    T *_ptr;
+  };
+
+  template<class T>
+  class AutoCPtr
+  {
+  public:
+    AutoCPtr(T *ptr=0):_ptr(ptr) {  }
+    ~AutoCPtr() { destroyPtr(); }
+    AutoCPtr &operator=(T *ptr) { if(_ptr!=ptr) { destroyPtr(); _ptr=ptr; } return *this; }
+    T *operator->() { return _ptr ; }
+    const T *operator->() const { return _ptr; }
+    T& operator*() { return *_ptr; }
+    const T& operator*() const { return *_ptr; }
+    operator T *() { return _ptr; }
+    operator const T *() const { return _ptr; }
+  private:
+    void destroyPtr() { free(_ptr); }
+  private:
+    T *_ptr;
+  };
+}
+
+#endif
diff --git a/src/evalyfx/YACSEvalPort.cxx b/src/evalyfx/YACSEvalPort.cxx
new file mode 100644 (file)
index 0000000..61a06fb
--- /dev/null
@@ -0,0 +1,311 @@
+// Copyright (C) 2012-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
+// 
+// Author : Anthony Geay (EDF R&D)
+
+#include "YACSEvalPort.hxx"
+#include "YACSEvalSeqAny.hxx"
+#include "OutputPort.hxx"
+#include "InputPort.hxx"
+#include "TypeCode.hxx"
+
+#include "CORBAPorts.hxx"
+#include "PythonPorts.hxx"
+#include "AnyInputPort.hxx"
+
+#include <limits>
+#include <sstream>
+#include <typeinfo>
+
+const char YACSEvalAnyDouble::TYPE_REPR[]="double";
+
+const char YACSEvalAnyInt::TYPE_REPR[]="int";
+
+int YACSEvalAnyDouble::toInt() const
+{
+  throw YACS::Exception("YACSEvalAnyDouble::toInt : invalid type requested !");
+}
+
+double YACSEvalAnyDouble::toDouble() const
+{
+  return _v;
+}
+
+YACSEvalAnyDouble *YACSEvalAnyDouble::deepCpy() const
+{
+  return new YACSEvalAnyDouble(*this);
+}
+
+int YACSEvalAnyInt::toInt() const
+{
+  return _v;
+}
+
+double YACSEvalAnyInt::toDouble() const
+{
+  throw YACS::Exception("YACSEvalAnyInt::toDouble : invalid type requested !");
+}
+
+YACSEvalAnyInt *YACSEvalAnyInt::deepCpy() const
+{
+  return new YACSEvalAnyInt(*this);
+}
+
+std::string YACSEvalPort::GetTypeOfData(const YACS::ENGINE::DataPort *port)
+{
+  YACS::ENGINE::TypeCode *tc(port->edGetType());
+  if(!tc)
+    throw YACS::Exception("YACSEvalPort::GetTypeOfData : null type code !");
+  if(tc->kind()==YACS::ENGINE::Double)
+    return std::string(YACSEvalAnyDouble::TYPE_REPR);
+  if(tc->kind()==YACS::ENGINE::Int)
+    return std::string(YACSEvalAnyInt::TYPE_REPR);
+  throw YACS::Exception("YACSEvalPort::GetTypeOfData : Unrecognized type of data ! Must be int or double for the moment !");
+}
+
+YACSEvalInputPort::YACSEvalInputPort(YACS::ENGINE::InputPort *ptr):_ptr(ptr),_isLocked(false),_mySeq(0)
+{
+  GetTypeOfData(_ptr);
+}
+
+std::string YACSEvalInputPort::getName() const
+{
+  return _ptr->getName();
+}
+
+std::string YACSEvalInputPort::getTypeOfData() const
+{
+  return GetTypeOfData(_ptr);
+}
+
+bool YACSEvalInputPort::isOKForLock() const
+{
+  if(_isLocked)
+    return true;
+  return hasDefaultValueDefined();
+}
+
+bool YACSEvalInputPort::hasDefaultValueDefined() const
+{
+  return _ptr->edIsManuallyInitialized();
+}
+
+/*!
+ * The caller has the ownership of the returned instance.
+ */
+YACSEvalAny *YACSEvalInputPort::getDefaultValueDefined() const
+{
+  if(!hasDefaultValueDefined())
+    throw YACS::Exception("YACSEvalInputPort::getDefaultValueDefined : no default value defined !");
+  _ptr->exRestoreInit();
+  YACS::ENGINE::InputPyPort *i0(dynamic_cast<YACS::ENGINE::InputPyPort *>(_ptr));
+  if(i0)
+    {
+      PyObject *data(i0->getPyObj());
+      if(!data)
+        throw YACS::Exception("YACSEvalInputPort::getDefaultValueDefined : internal error !");
+      if(PyFloat_Check(data))
+        return new YACSEvalAnyDouble(PyFloat_AsDouble(data));
+      if(PyInt_Check(data))
+        return new YACSEvalAnyInt((int)PyInt_AsLong(data));
+      throw YACS::Exception("YACSEvalInputPort::getDefaultValueDefined : unmanaged types different from int and double for py !");
+    }
+  YACS::ENGINE::AnyInputPort *i1(dynamic_cast<YACS::ENGINE::AnyInputPort *>(_ptr));
+  if(i1)
+    {
+      YACS::ENGINE::Any *data(i1->getValue());
+      return convertFromInternalAnyToExternal(data);
+    }
+  YACS::ENGINE::InputCorbaPort *i2(dynamic_cast<YACS::ENGINE::InputCorbaPort *>(_ptr));
+  if(i2)
+    {
+      CORBA::Any *data(i2->getAny());
+      if(!data)
+        throw YACS::Exception("YACSEvalInputPort::getDefaultValueDefined : internal error # 3 !");
+      std::string td(getTypeOfData());
+      if(td==YACSEvalAnyDouble::TYPE_REPR)
+        {
+          CORBA::Double v;
+          if((*data)>>=v)
+            return new YACSEvalAnyDouble(v);
+          else
+            throw YACS::Exception("YACSEvalInputPort::getDefaultValueDefined : internal error # 31 !");
+        }
+      if(td==YACSEvalAnyInt::TYPE_REPR)
+        {
+          CORBA::Long v;
+          if((*data)>>=v)
+            return new YACSEvalAnyInt(v);
+          else
+            throw YACS::Exception("YACSEvalInputPort::getDefaultValueDefined : internal error # 32 !");
+        }
+    }
+  std::ostringstream oss;
+  oss << "YACSEvalInputPort::getDefaultValueDefined : Please contact anthony.geay@edf.fr with -> \"" << typeid(*_ptr).name() << "\" !";
+  throw YACS::Exception(oss.str());
+}
+
+/*!
+ * This method does not steal the ownership of \a parameter (a deep copy is performed).
+ */
+void YACSEvalInputPort::setDefaultValue(const YACSEvalAny *parameter)
+{
+  checkForNonConstMethod();
+  if(parameter)
+    {
+      if(parameter->getTypeOfData()!=getTypeOfData())
+        {
+          std::ostringstream oss; oss << "YACSEvalInputPort::setParameter : Type of data mismatch ! Expecting \"" << getTypeOfData() << "\" having \"" <<  parameter->getTypeOfData() << "\" !";
+          throw YACS::Exception(oss.str());
+        }
+    }
+  //
+  YACS::ENGINE::InputPyPort *i0(dynamic_cast<YACS::ENGINE::InputPyPort *>(_ptr));
+  YACS::ENGINE::AnyInputPort *i1(dynamic_cast<YACS::ENGINE::AnyInputPort *>(_ptr));
+  YACS::ENGINE::InputCorbaPort *i2(dynamic_cast<YACS::ENGINE::InputCorbaPort *>(_ptr));
+  if(parameter)
+    {
+      const YACSEvalAnyDouble *par0(dynamic_cast<const YACSEvalAnyDouble *>(parameter));
+      const YACSEvalAnyInt *par1(dynamic_cast<const YACSEvalAnyInt *>(parameter));
+      if(i0)
+        {
+          if(par0)
+            {
+              PyObject *obj(PyFloat_FromDouble(par0->toDouble()));
+              i0->put(obj);
+              Py_XDECREF(obj);
+            }
+          else if(par1)
+            {
+              PyObject *obj(PyInt_FromLong(par1->toInt()));
+              i0->put(obj);
+              Py_XDECREF(obj);
+            }
+          else
+            throw YACS::Exception("YACSEvalInputPort::setDefaultValueDefined : unmanaged types different from int and double for py !");
+        }
+      else if(i1)
+        {
+          if(par0)
+            {
+              YACS::ENGINE::AtomAny *v(YACS::ENGINE::AtomAny::New(par0->toDouble()));
+              i1->put(v);
+              v->decrRef();
+            }
+          else if(par1)
+            {
+              YACS::ENGINE::AtomAny *v(YACS::ENGINE::AtomAny::New(par1->toInt()));
+              i1->put(v);
+              v->decrRef();
+            }
+          else
+            throw YACS::Exception("YACSEvalInputPort::setDefaultValueDefined : unmanaged types different from int and double for yacsport !");
+        }
+      else if(i2)
+        {
+          CORBA::Any v;
+          if(par0)
+            v<<=par0->toDouble();
+          else if(par1)
+            v<<=par1->toInt();
+          else
+            throw YACS::Exception("YACSEvalInputPort::setDefaultValueDefined : unmanaged types different from int and double for corbaport !");
+          i2->put(&v);
+        }
+      else
+        {
+          std::ostringstream oss;
+          oss << "YACSEvalInputPort::getDefaultValueDefined : Please contact anthony.geay@edf.fr with -> \"" << typeid(*_ptr).name() << "\" !";
+          throw YACS::Exception(oss.str());
+        }
+      _ptr->exSaveInit();
+    }
+  else
+    _ptr->edRemoveManInit();
+}
+
+void YACSEvalInputPort::setSequenceOfValuesToEval(const YACSEvalSeqAny *vals)
+{
+  checkForNonConstMethod();
+  if(!vals)
+    throw YACS::Exception("YACSEvalInputPort::setSequenceOfValuesToEval : input is NULL !");
+  if(vals==_mySeq)
+    return ;
+  if(_mySeq)
+    delete _mySeq;
+  _mySeq=vals->copy();
+}
+
+bool YACSEvalInputPort::hasSequenceOfValuesToEval(std::size_t& sz) const
+{
+  sz=std::numeric_limits<std::size_t>::max();
+  bool ret(_mySeq!=0);
+  if(ret)
+    sz=_mySeq->size();
+  return ret;
+}
+
+void YACSEvalInputPort::initializeUndergroundWithSeq(YACS::ENGINE::InputPyPort *p) const
+{
+  if(!p)
+    throw YACS::Exception("YACSEvalInputPort::initializeUndergroundWithSeq : p is null !");
+  if(!_mySeq)
+    throw YACS::Exception("YACSEvalInputPort::initializeUndergroundWithSeq : this is not set as a sequence !");
+  _mySeq->initialize(p);
+}
+
+YACSEvalInputPort::~YACSEvalInputPort()
+{
+  delete _mySeq;
+}
+
+YACSEvalAny *YACSEvalInputPort::convertFromInternalAnyToExternal(YACS::ENGINE::Any *data) const
+{
+  if(!data)
+    throw YACS::Exception("YACSEvalInputPort::convertFromInternalAnyToExternal : internal error # 2 !");
+  YACS::ENGINE::AtomAny *data2(dynamic_cast<YACS::ENGINE::AtomAny *>(data));
+  if(!data2)
+    throw YACS::Exception("YACSEvalInputPort::convertFromInternalAnyToExternal : internal error # 21 !");
+  std::string td(getTypeOfData());
+  if(td==YACSEvalAnyDouble::TYPE_REPR)
+    return new YACSEvalAnyDouble(data2->getDoubleValue());
+  if(td==YACSEvalAnyInt::TYPE_REPR)
+    return new YACSEvalAnyInt(data2->getIntValue());
+  throw YACS::Exception("YACSEvalInputPort::convertFromInternalAnyToExternal : unmanaged types different from int and double for any !");
+}
+
+void YACSEvalInputPort::checkForNonConstMethod() const
+{
+  if(_isLocked)
+    throw YACS::Exception("YACSEvalInputPort::checkForNonConstMethod : trying to modify a locked input ! To release it call unlockAll on YACSEvalYFX instance owning this !");
+}
+
+YACSEvalOutputPort::YACSEvalOutputPort(YACS::ENGINE::OutputPort *ptr):_ptr(ptr)
+{
+  GetTypeOfData(_ptr);
+}
+
+std::string YACSEvalOutputPort::getName() const
+{
+  return _ptr->getName();
+}
+
+std::string YACSEvalOutputPort::getTypeOfData() const
+{
+  return GetTypeOfData(_ptr);
+}
diff --git a/src/evalyfx/YACSEvalPort.hxx b/src/evalyfx/YACSEvalPort.hxx
new file mode 100644 (file)
index 0000000..3044dca
--- /dev/null
@@ -0,0 +1,133 @@
+// Copyright (C) 2012-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
+// 
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef __YACSEVALPORT_HXX__
+#define __YACSEVALPORT_HXX__
+
+#include "YACSEvalYFXExport.hxx"
+
+#include <string>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Any;
+    class DataPort;
+    class InputPort;
+    class OutputPort;
+    class InputPyPort;
+  }
+}
+
+class YACSEvalSeqAny;
+
+class YACSEvalAny
+{
+public:
+  YACSEVALYFX_EXPORT virtual ~YACSEvalAny() { }
+  YACSEVALYFX_EXPORT virtual std::string getTypeOfData() const = 0;
+  YACSEVALYFX_EXPORT virtual int toInt() const = 0;
+  YACSEVALYFX_EXPORT virtual double toDouble() const = 0;
+  YACSEVALYFX_EXPORT virtual YACSEvalAny *deepCpy() const = 0;
+};
+
+class YACSEvalAnyDouble : public YACSEvalAny
+{
+public:
+  YACSEVALYFX_EXPORT YACSEvalAnyDouble(double val):_v(val) { }
+  YACSEVALYFX_EXPORT std::string getTypeOfData() const { return std::string(TYPE_REPR); }
+  YACSEVALYFX_EXPORT int toInt() const;
+  YACSEVALYFX_EXPORT double toDouble() const;
+  YACSEVALYFX_EXPORT YACSEvalAnyDouble *deepCpy() const;
+  YACSEVALYFX_EXPORT ~YACSEvalAnyDouble() { }
+private:
+  double _v;
+public:
+  static const char TYPE_REPR[];
+};
+
+class YACSEvalAnyInt : public YACSEvalAny
+{
+public:
+  YACSEVALYFX_EXPORT YACSEvalAnyInt(int val):_v(val) { }
+  YACSEVALYFX_EXPORT std::string getTypeOfData() const { return std::string(TYPE_REPR); }
+  YACSEVALYFX_EXPORT int toInt() const;
+  YACSEVALYFX_EXPORT double toDouble() const;
+  YACSEVALYFX_EXPORT YACSEvalAnyInt *deepCpy() const;
+  YACSEVALYFX_EXPORT ~YACSEvalAnyInt() { }
+private:
+  int _v;
+public:
+  static const char TYPE_REPR[];
+};
+
+class YACSEvalPort
+{
+public:
+  YACSEVALYFX_EXPORT virtual std::string getTypeOfData() const = 0;
+  YACSEVALYFX_EXPORT virtual ~YACSEvalPort() { }
+protected:
+  YACSEVALYFX_EXPORT static std::string GetTypeOfData(const YACS::ENGINE::DataPort *port);
+};
+
+class YACSEvalInputPort : public YACSEvalPort
+{
+public:
+  YACSEVALYFX_EXPORT YACSEvalInputPort(YACS::ENGINE::InputPort *ptr);
+  YACSEVALYFX_EXPORT std::string getName() const;
+  YACSEVALYFX_EXPORT std::string getTypeOfData() const;
+  YACSEVALYFX_EXPORT bool isOKForLock() const;
+  //
+  YACSEVALYFX_EXPORT bool hasDefaultValueDefined() const;
+  YACSEVALYFX_EXPORT YACSEvalAny *getDefaultValueDefined() const;
+  YACSEVALYFX_EXPORT void setDefaultValue(const YACSEvalAny *parameter);
+  YACSEVALYFX_EXPORT void setSequenceOfValuesToEval(const YACSEvalSeqAny* vals);
+  YACSEVALYFX_EXPORT bool hasSequenceOfValuesToEval(std::size_t& sz) const;
+  //
+  YACSEVALYFX_EXPORT YACS::ENGINE::InputPort *getUndergroundPtr() const { return _ptr; }
+  YACSEVALYFX_EXPORT void initializeUndergroundWithSeq(YACS::ENGINE::InputPyPort *p) const;
+  //
+  YACSEVALYFX_EXPORT virtual ~YACSEvalInputPort();
+  void lock() const { _isLocked=true; }
+  void unlock() const { _isLocked=false; }
+private:
+  YACSEvalAny *convertFromInternalAnyToExternal(YACS::ENGINE::Any *data) const;
+  void checkForNonConstMethod() const;
+private:
+  YACS::ENGINE::InputPort * _ptr;
+  YACSEvalSeqAny *_mySeq;
+  mutable bool _isLocked;
+};
+
+class YACSEvalOutputPort : public YACSEvalPort
+{
+public:
+  YACSEVALYFX_EXPORT YACSEvalOutputPort(YACS::ENGINE::OutputPort *ptr);
+  YACSEVALYFX_EXPORT std::string getName() const;
+  YACSEVALYFX_EXPORT std::string getTypeOfData() const;
+  //
+  YACSEVALYFX_EXPORT YACS::ENGINE::OutputPort *getUndergroundPtr() const { return _ptr; }
+  //
+private:
+  YACS::ENGINE::OutputPort * _ptr;
+};
+
+#endif
diff --git a/src/evalyfx/YACSEvalResource.cxx b/src/evalyfx/YACSEvalResource.cxx
new file mode 100644 (file)
index 0000000..aa9df20
--- /dev/null
@@ -0,0 +1,623 @@
+// Copyright (C) 2012-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
+// 
+// Author : Anthony Geay (EDF R&D)
+
+#include "YACSEvalResource.hxx"
+
+#include "DeploymentTree.hxx"
+#include "Container.hxx"
+#include "Exception.hxx"
+
+#include "SalomeContainer.hxx"
+#include "SalomeHPContainer.hxx"
+#include "ComponentInstance.hxx"
+
+#include "ResourcesManager.hxx"
+
+#include <set>
+#include <queue>
+#include <sstream>
+#include <iterator>
+#include <algorithm>
+
+const char YACSEvalVirtualYACSContainer::CONTAINER_NAME_KEY[]="container_name";
+
+const char YACSEvalVirtualYACSContainer::CPU_CLOCK_KEY[]="cpu_clock";
+
+const char YACSEvalVirtualYACSContainer::HOSTNAME_KEY[]="hostname";
+
+const char YACSEvalVirtualYACSContainer::MEM_KEY[]="mem_mb";
+
+const char YACSEvalVirtualYACSContainer::NB_NODE_KEY[]="nb_node";
+
+const char YACSEvalVirtualYACSContainer::NB_PROC_PER_NODE_KEY[]="nb_proc_per_node";
+
+const char YACSEvalVirtualYACSContainer::NB_RESOURCE_PROCS_KEY[]="nb_resource_procs";
+
+const char YACSEvalVirtualYACSContainer::POLICY_KEY[]="policy";
+
+const char YACSEvalVirtualYACSContainer::OS_KEY[]="OS";
+
+/*!
+ * This class is here only to avoid "friend class YACSEvalListOfResources".
+ */
+class YACSEvalResourceEff : public YACSEvalResource
+{
+public:
+  YACSEvalResourceEff(YACSEvalListOfResources *gf, const std::vector< YACS::ENGINE::Container * >& conts);
+};
+
+YACSEvalResourceEff::YACSEvalResourceEff(YACSEvalListOfResources *gf, const std::vector< YACS::ENGINE::Container * >& conts):YACSEvalResource(gf,conts)
+{
+}
+
+void YACSEvalNonConstLocker::checkNonLocked() const
+{
+  if(_isLocked)
+    throw YACS::Exception("YACSEvalNonConstLocker::checkNonLocked : this is locked and trying to invoke non-const method !");
+}
+
+YACSEvalVirtualYACSContainer::YACSEvalVirtualYACSContainer():_gf(0),_cont(0)
+{
+}
+
+void YACSEvalVirtualYACSContainer::set(YACSEvalResource *gf, YACS::ENGINE::Container *cont)
+{
+  checkNonLocked();
+  _gf=gf;
+  if(_cont==cont)
+    return ;
+  if(_cont)
+    _cont->decrRef();
+  _cont=cont;
+  _propertyMap=listOfPropertiesInYACSContainer();
+}
+
+YACSEvalVirtualYACSContainer::YACSEvalVirtualYACSContainer(YACSEvalResource *gf, YACS::ENGINE::Container *cont):_gf(gf),_cont(cont)
+{
+  if(_cont)
+    _cont->incrRef();
+  _propertyMap=listOfPropertiesInYACSContainer();
+}
+
+YACSEvalVirtualYACSContainer::~YACSEvalVirtualYACSContainer()
+{
+  if(_cont)
+    _cont->decrRef();
+}
+
+/*!
+ * \param [in,out] entry - Resource type instance to be updated with \a this.
+ */
+void YACSEvalVirtualYACSContainer::aggregate(ParserResourcesType& entry) const
+{
+  if(entry.HostName.empty())
+    entry.HostName=getHostName();
+  entry.DataForSort._memInMB=std::max(entry.DataForSort._memInMB,getMem());
+  entry.DataForSort._nbOfProcPerNode=std::max(entry.DataForSort._nbOfProcPerNode,getNbProcPerNode());
+  entry.DataForSort._nbOfNodes=std::max(entry.DataForSort._nbOfNodes,getNbNodes());
+  entry.DataForSort._CPUFreqMHz=std::max(entry.DataForSort._CPUFreqMHz,getCPUFreq());
+  std::vector<YACS::ENGINE::ComponentInstance *> comps(_gf->getGodFather()->getDeploymentTree()->getComponentsLinkedToContainer(_cont));
+  std::set<std::string> compNames;
+  for(std::vector<YACS::ENGINE::ComponentInstance *>::const_iterator it=comps.begin();it!=comps.end();it++)
+    {
+      YACS::ENGINE::ComponentInstance *elt(*it);
+      if(elt)
+        compNames.insert(elt->getCompoName());
+    }
+  compNames.insert(entry.ComponentsList.begin(),entry.ComponentsList.end());
+  compNames.erase(std::string());
+  std::vector<std::string> compNames2(compNames.begin(),compNames.end());
+  entry.ComponentsList=compNames2;
+}
+
+std::string YACSEvalVirtualYACSContainer::findDefault(bool isInteractive) const
+{
+  std::vector<std::string> possibleHosts(_gf->getAllFittingMachines());
+  for(std::vector<std::string>::const_iterator it=possibleHosts.begin();it!=possibleHosts.end();it++)
+    {
+      if(_gf->getGodFather()->hasRightInteractiveStatus(*it,isInteractive))
+        return *it;
+    }
+  throw YACS::Exception("YACSEvalVirtualYACSContainer::findDefault : impossible to find a right machine with requested interactive status !");
+}
+
+void YACSEvalVirtualYACSContainer::setWantedMachine(const std::string& machine)
+{
+  checkNonLocked();
+  std::vector<std::string> possibleHosts(_gf->getAllFittingMachines());
+  if(std::find(possibleHosts.begin(),possibleHosts.end(),machine)==possibleHosts.end())
+    throw YACS::Exception("YACSEvalVirtualYACSContainer::setWantedMachine : the specified machine is not in the list of available !");
+  std::string oldMachine(getChosenMachine());
+  setMachineNoCheck(machine);
+  try
+  {
+      _gf->notifyWantedMachine(this,oldMachine,machine);
+  }
+  catch(YACS::Exception& e)
+  {
+      setMachineNoCheck(oldMachine);
+      throw e;
+  }
+}
+
+std::vector<std::string> YACSEvalVirtualYACSContainer::listOfPropertyKeys() const
+{
+  std::set<std::string> s;
+  std::map<std::string,std::string>::const_iterator it;
+  for(it=_overloadedPropertyMap.begin();it!=_overloadedPropertyMap.end();it++)
+    s.insert((*it).first);
+  for(it=_propertyMap.begin();it!=_propertyMap.end();it++)
+    s.insert((*it).first);
+  std::vector<std::string> ret(s.begin(),s.end());
+  return ret;
+}
+
+std::string YACSEvalVirtualYACSContainer::getValueOfKey(const char *key) const
+{
+  std::map<std::string,std::string>::const_iterator it;
+  it=_overloadedPropertyMap.find(key);
+  if(it!=_overloadedPropertyMap.end())
+    return (*it).second;
+  it=_propertyMap.find(key);
+  if(it!=_propertyMap.end())
+    return (*it).second;
+  return std::string();
+}
+
+void YACSEvalVirtualYACSContainer::setProperty(const std::string& key, const std::string &value)
+{
+  checkNonLocked();
+  _overloadedPropertyMap[key]=value;
+}
+
+void YACSEvalVirtualYACSContainer::apply()
+{
+  YACS::ENGINE::SalomeContainer *cont0(dynamic_cast<YACS::ENGINE::SalomeContainer *>(_cont));
+  YACS::ENGINE::SalomeHPContainer *cont1(dynamic_cast<YACS::ENGINE::SalomeHPContainer *>(_cont));
+  if(cont0)
+    {
+      cont0->setProperty(HOSTNAME_KEY,getValueOfKey(HOSTNAME_KEY));
+      return ;
+    }
+  else if(cont1)
+    {
+      cont1->setProperty(HOSTNAME_KEY,getValueOfKey(HOSTNAME_KEY));
+      return ;
+    }
+  else
+    throw YACS::Exception("YACSEvalVirtualYACSContainer::apply : unrecognized container !");
+}
+
+unsigned int YACSEvalVirtualYACSContainer::getValueOfKeyUInt(const char *key) const
+{
+  std::string v(getValueOfKey(key));
+  unsigned int ret(0);
+  if(v.empty())
+    return ret;
+  std::istringstream iss(v);
+  iss >> ret;
+  return ret;
+}
+
+std::map<std::string,std::string> YACSEvalVirtualYACSContainer::listOfPropertiesInYACSContainer() const
+{
+  YACS::ENGINE::SalomeContainer *cont0(dynamic_cast<YACS::ENGINE::SalomeContainer *>(_cont));
+  YACS::ENGINE::SalomeHPContainer *cont1(dynamic_cast<YACS::ENGINE::SalomeHPContainer *>(_cont));
+  std::map<std::string,std::string> props;
+  if(cont0)
+    props=cont0->getProperties();
+  else if(cont1)
+    props=cont1->getProperties();
+  return props;
+}
+
+YACSEvalResource::~YACSEvalResource()
+{
+}
+
+std::vector<std::string> YACSEvalResource::getAllChosenMachines() const
+{
+  std::set<std::string> s;
+  for(std::vector< YACSEvalVirtualYACSContainer >::const_iterator it=_containers.begin();it!=_containers.end();it++)
+    s.insert((*it).getChosenMachine());
+  std::vector<std::string> ret(s.begin(),s.end());
+  return ret;
+}
+
+std::vector<std::string> YACSEvalResource::getAllFittingMachines() const
+{
+  ParserResourcesType ref;
+  aggregate(ref);
+  return _gf->getFittingResources(&ref);
+}
+
+void YACSEvalResource::setWantedMachine(const std::string& machine)
+{
+  checkNonLocked();
+  std::vector<std::string> possibleHosts(getAllFittingMachines());
+  if(std::find(possibleHosts.begin(),possibleHosts.end(),machine)==possibleHosts.end())
+    throw YACS::Exception("YACSEvalResource::setWantedMachine : the specified machine is not in the list of available !");
+  for(std::vector< YACSEvalVirtualYACSContainer >::iterator it=_containers.begin();it!=_containers.end();it++)
+    (*it).setMachineNoCheck(machine);
+}
+
+YACSEvalVirtualYACSContainer *YACSEvalResource::at(std::size_t i) const
+{
+  if(i>=_containers.size())
+    throw YACS::Exception("YACSEvalResource::at : invalid input ! must be < size !");
+  return const_cast<YACSEvalVirtualYACSContainer *>(&_containers[i]);
+}
+
+void YACSEvalResource::apply()
+{
+  for(std::vector< YACSEvalVirtualYACSContainer >::iterator it=_containers.begin();it!=_containers.end();it++)
+    (*it).apply();
+}
+
+void YACSEvalResource::fitWithCurrentCatalogAbs()
+{
+  std::vector<std::string> ress(getAllFittingMachines());
+  if(ress.empty())
+    throw YACS::Exception("YACSEvalResource::fitWithCurrentCatalogAbs : no suitable host in your catalog of resource !");
+  setMachineNoCheck(ress.front());
+}
+
+void YACSEvalResource::aggregate(ParserResourcesType& entry) const
+{
+  for(std::vector< YACSEvalVirtualYACSContainer >::const_iterator it=_containers.begin();it!=_containers.end();it++)
+    (*it).aggregate(entry);
+}
+
+void YACSEvalResource::notifyWantedMachine(YACSEvalVirtualYACSContainer *sender, const std::string& oldMachine, const std::string& newMachine)
+{
+  _gf->notifyWantedMachine(sender,oldMachine,newMachine);
+}
+
+void YACSEvalResource::setMachineNoCheck(const std::string& machine)
+{
+  for(std::vector< YACSEvalVirtualYACSContainer >::iterator it=_containers.begin();it!=_containers.end();it++)
+    (*it).setMachineNoCheck(machine);
+}
+
+YACSEvalResource::YACSEvalResource(YACSEvalListOfResources *gf, const std::vector< YACS::ENGINE::Container * >& conts):_gf(gf)
+{
+  std::size_t sz(conts.size());
+  _containers.resize(sz);
+  for(std::size_t i=0;i<sz;i++)
+    _containers[i].set(this,conts[i]);
+}
+
+YACSEvalListOfResources::YACSEvalListOfResources(int maxLevOfPara, ResourcesManager_cpp *rm, const YACS::ENGINE::DeploymentTree& dt):_maxLevOfPara(maxLevOfPara),_rm(rm),_dt(new YACS::ENGINE::DeploymentTree(dt))
+{
+  std::vector<YACS::ENGINE::Container *> conts(_dt->getAllContainers());
+  std::map<std::string, std::vector<YACS::ENGINE::Container *> > listOfHosts;
+  for(std::vector<YACS::ENGINE::Container *>::const_iterator it=conts.begin();it!=conts.end();it++)
+    {
+      std::vector<YACS::ENGINE::ComponentInstance *> cis(dt.getComponentsLinkedToContainer(*it));
+      YACS::ENGINE::SalomeContainer *c1(dynamic_cast<YACS::ENGINE::SalomeContainer *>(*it));
+      YACS::ENGINE::SalomeHPContainer *c2(dynamic_cast<YACS::ENGINE::SalomeHPContainer *>(*it));
+      std::string zeHost;
+      if(c1)
+        zeHost=c1->getProperty(YACSEvalVirtualYACSContainer::HOSTNAME_KEY);
+      if(c2)
+        zeHost=c2->getProperty(YACSEvalVirtualYACSContainer::HOSTNAME_KEY);
+      listOfHosts[zeHost].push_back(*it);
+    }
+  for(std::map<std::string, std::vector<YACS::ENGINE::Container *> >::const_iterator it=listOfHosts.begin();it!=listOfHosts.end();it++)
+    _resources.push_back(new YACSEvalResourceEff(this,(*it).second));
+  fitWithCurrentCatalog();
+}
+
+std::vector<std::string> YACSEvalListOfResources::getAllChosenMachines() const
+{
+  std::set<std::string> s;
+  for(std::vector<YACSEvalResource *>::const_iterator it=_resources.begin();it!=_resources.end();it++)
+    {
+      std::vector<std::string> tmp((*it)->getAllChosenMachines());
+      s.insert(tmp.begin(),tmp.end());
+    }
+  std::vector<std::string> ret(s.begin(),s.end());
+  return ret;
+}
+
+std::vector<std::string> YACSEvalListOfResources::getAllFittingMachines() const
+{
+  ParserResourcesType ref;
+  for(std::vector<YACSEvalResource *>::const_iterator it=_resources.begin();it!=_resources.end();it++)
+    (*it)->aggregate(ref);
+  return getFittingResources(&ref);
+}
+
+void YACSEvalListOfResources::setWantedMachine(const std::string& machine)
+{
+  checkNonLocked();
+  std::vector<std::string> possibleHosts(getAllFittingMachines());
+  if(std::find(possibleHosts.begin(),possibleHosts.end(),machine)==possibleHosts.end())
+    throw YACS::Exception("YACSEvalResource::setWantedMachine : the specified machine is not in the list of available !");
+  for(std::vector<YACSEvalResource *>::iterator it=_resources.begin();it!=_resources.end();it++)
+    (*it)->setMachineNoCheck(machine);
+}
+
+YACSEvalResource *YACSEvalListOfResources::at(std::size_t i) const
+{
+  if(i>=size())
+    throw YACS::Exception("YACSEvalListOfResources::at : invalid id !");
+  return _resources[i];
+}
+
+bool YACSEvalListOfResources::isInteractive() const
+{
+  const MapOfParserResourcesType& zeList(_rm->GetList());
+  std::vector<std::string> allMachines(getAllChosenMachines());
+  if(allMachines.empty())
+    return true;
+  std::size_t ii(0),sz(allMachines.size());
+  std::vector<bool> status(sz);
+  for(std::vector<std::string>::const_iterator it=allMachines.begin();it!=allMachines.end();it++,ii++)
+    {
+      std::map<std::string, ParserResourcesType>::const_iterator it2(zeList.find(*it));
+      if(it2==zeList.end())
+        {
+          std::ostringstream oss; oss << "YACSEvalListOfResources::isInteractive : presence of non existing \"" << *it << "\" !";
+          throw YACS::Exception(oss.str());
+        }
+      const ParserResourcesType& elt((*it2).second);
+      status[ii]=(elt.ClusterInternalProtocol==sh || elt.ClusterInternalProtocol==rsh || elt.ClusterInternalProtocol==ssh);
+    }
+  std::size_t trueRet(std::count(status.begin(),status.end(),true)),falseRet(std::count(status.begin(),status.end(),false));
+  if(trueRet==sz && falseRet==0)
+    return true;
+  else if(trueRet==0 && falseRet==sz)
+    return false;
+  throw YACS::Exception("YACSEvalListOfResources::isInteractive : mix of interactive and non interactive ! internal error !");
+}
+
+unsigned int YACSEvalListOfResources::getNumberOfProcsDeclared() const
+{
+  std::vector<std::string> chosen(getAllChosenMachines());
+  unsigned int ret(0);
+  for(std::vector<std::string>::const_iterator it=chosen.begin();it!=chosen.end();it++)
+    ret+=getNumberOfProcOfResource(*it);
+  return ret;
+}
+
+void YACSEvalListOfResources::apply()
+{
+  for(std::vector<YACSEvalResource *>::iterator it=_resources.begin();it!=_resources.end();it++)
+    (*it)->apply();
+}
+
+YACSEvalListOfResources::~YACSEvalListOfResources()
+{
+  delete _dt;
+  for(std::vector<YACSEvalResource *>::iterator it=_resources.begin();it!=_resources.end();it++)
+    delete *it;
+}
+
+class EffectiveComparator
+{
+public:
+  virtual ~EffectiveComparator() { }
+  virtual EffectiveComparator *copy() const = 0;
+  virtual bool compare(const ResourceDataToSort& elt1, const ResourceDataToSort& elt2) const = 0;
+};
+
+// comparator for a null request in scheme
+class BasicComparator : public EffectiveComparator
+{
+public:
+  EffectiveComparator *copy() const { return new BasicComparator; }
+  bool compare(const ResourceDataToSort& elt1, const ResourceDataToSort& elt2) const;
+};
+
+class MemAwareComparator : public EffectiveComparator
+{
+public:
+  EffectiveComparator *copy() const { return new MemAwareComparator; }
+  bool compare(const ResourceDataToSort& elt1, const ResourceDataToSort& elt2) const;
+};
+
+class CompromiseComparator : public EffectiveComparator
+{
+public:
+  CompromiseComparator(int memMB, int nbProcs):_memMB(memMB),_nbProcs(nbProcs) { }
+  EffectiveComparator *copy() const { return new CompromiseComparator(_memMB,_nbProcs); }
+  bool compare(const ResourceDataToSort& elt1, const ResourceDataToSort& elt2) const;
+private:
+  int _memMB;
+  int _nbProcs;
+};
+
+class CompareRes
+{
+public:
+  CompareRes(const ParserResourcesType *request, const MapOfParserResourcesType& zeCatalog);
+  CompareRes(const CompareRes& other);
+  bool operator()(const std::string& res1, const std::string& res2);
+  ~CompareRes() { delete _comp; }
+private:
+  EffectiveComparator *_comp;
+  const ParserResourcesType *_request;
+  const MapOfParserResourcesType& _zeCatalog;
+};
+
+bool BasicComparator::compare(const ResourceDataToSort& elt1, const ResourceDataToSort& elt2) const
+{
+  int nbOfProcs1(elt1._nbOfNodes*elt1._nbOfProcPerNode),nbOfProcs2(elt2._nbOfNodes*elt2._nbOfProcPerNode);
+  return nbOfProcs1<nbOfProcs2;
+}
+
+bool MemAwareComparator::compare(const ResourceDataToSort& elt1, const ResourceDataToSort& elt2) const
+{
+  return elt1._memInMB<elt2._memInMB;
+}
+
+bool CompromiseComparator::compare(const ResourceDataToSort& elt1, const ResourceDataToSort& elt2) const
+{
+  double v1a(elt1._memInMB/_memMB),v1b(elt1._nbOfNodes*elt1._nbOfProcPerNode/_nbProcs);
+  double v2a(elt2._memInMB/_memMB),v2b(elt2._nbOfNodes*elt2._nbOfProcPerNode/_nbProcs);
+  return std::min(v1a,v1b)<std::min(v2a,v2b);
+}
+
+CompareRes::CompareRes(const ParserResourcesType *request, const MapOfParserResourcesType& zeCatalog):_comp(0),_request(request),_zeCatalog(zeCatalog)
+{
+  const ResourceDataToSort& tmp(_request->DataForSort);
+  // all request items are set to default -> Basic comparison on procs
+  if(request->DataForSort._nbOfNodes==1 && request->DataForSort._nbOfProcPerNode==1 && request->DataForSort._memInMB==0)
+    _comp=new BasicComparator;
+  // all items are set to default except memory -> Memory aware only
+  else if(request->DataForSort._memInMB!=0 && request->DataForSort._nbOfNodes==1 && request->DataForSort._nbOfProcPerNode==1)
+    _comp=new MemAwareComparator;
+  // memory and procs are set by the user -> do the best possible.
+  else if(request->DataForSort._memInMB!=0 && ( request->DataForSort._nbOfNodes!=1 || request->DataForSort._nbOfProcPerNode!=1 ) )
+    _comp=new CompromiseComparator(request->DataForSort._memInMB,request->DataForSort._nbOfNodes*request->DataForSort._nbOfProcPerNode);
+  else
+    _comp=new BasicComparator;
+}
+
+CompareRes::CompareRes(const CompareRes& other):_comp(other._comp->copy()),_request(other._request),_zeCatalog(other._zeCatalog)
+{
+}
+
+bool CompareRes::operator()(const std::string& res1, const std::string& res2)
+{
+  std::map<std::string, ParserResourcesType>::const_iterator it1(_zeCatalog.find(res1)),it2(_zeCatalog.find(res2));
+  if(it1==_zeCatalog.end() || it2==_zeCatalog.end())
+    throw YACS::Exception("Internal error during comparison !");
+  const ParserResourcesType& elt1((*it1).second);
+  const ParserResourcesType& elt2((*it2).second);
+  return _comp->compare(elt1.DataForSort,elt2.DataForSort);
+}
+
+/*!
+ * Implements an another alg than those proposed by default in ResourcesManager_cpp in "ResourcesManager.hxx".
+ */
+std::vector<std::string> YACSEvalListOfResources::getFittingResources(ParserResourcesType *request) const
+{
+  int mlop(getMaxLevelOfParallelism());
+  request->DataForSort._memInMB*=mlop;
+  request->DataForSort._nbOfNodes*=mlop;
+  //
+  const MapOfParserResourcesType& zeListInCatalog(_rm->GetList());
+  std::vector<std::string> list0;
+  // first keep those having relevant components
+  const std::vector<std::string>& listExpected(request->ComponentsList);
+  std::set<std::string> listExpected2(listExpected.begin(),listExpected.end());
+  for(std::map<std::string, ParserResourcesType>::const_iterator it=zeListInCatalog.begin();it!=zeListInCatalog.end();it++)
+    {
+      const std::vector<std::string>& compoList((*it).second.ComponentsList);
+      std::set<std::string> s1(compoList.begin(),compoList.end());
+      std::vector<std::string> diff;
+      std::set_difference(listExpected2.begin(),listExpected2.end(),s1.begin(),s1.end(),std::inserter(diff,diff.begin()));
+      if(diff.empty())
+        list0.push_back((*it).first);
+    }
+  // sort list0 regarding request
+  std::sort(list0.begin(),list0.end(),CompareRes(request,zeListInCatalog));
+  // if HostName in request is defined and in list0 put it first.
+  std::string tmp(request->HostName);
+  if(!tmp.empty())
+    {
+      std::vector<std::string>::iterator it1(std::find(list0.begin(),list0.end(),tmp));
+      if(it1!=list0.end())
+        {// HostName in list0 so put it in first place.
+          list0.erase(it1);
+          list0.insert(list0.begin(),tmp);
+        }
+    }
+  return list0;
+}
+
+void YACSEvalListOfResources::notifyWantedMachine(YACSEvalVirtualYACSContainer *sender, const std::string& oldMachine, const std::string& newMachine)
+{
+  const MapOfParserResourcesType& zeList(_rm->GetList());
+  std::map<std::string, ParserResourcesType>::const_iterator itOld(zeList.find(oldMachine)),itNew(zeList.find(newMachine));
+  if(itOld==zeList.end() || itNew==zeList.end())
+    throw YACS::Exception("YACSEvalListOfResources::notifyWantedMachine : internal error !");
+  const ParserResourcesType& oldPRT((*itOld).second);
+  const ParserResourcesType& newPRT((*itNew).second);
+  if(oldPRT.ClusterInternalProtocol==newPRT.ClusterInternalProtocol)
+    return ;
+  // the batch/interactive mode has changed -> try to change for all.
+  std::queue<std::string> sts;
+  try
+  {
+      for(std::vector<YACSEvalResource *>::const_iterator it=_resources.begin();it!=_resources.end();it++)
+        {
+          std::size_t sz((*it)->size());
+          for(std::size_t i=0;i<sz;i++)
+            {
+              YACSEvalVirtualYACSContainer *cont((*it)->at(i));
+              if(cont==sender)
+                continue;
+              sts.push(cont->findDefault(newPRT.ClusterInternalProtocol==sh));
+            }
+        }
+  }
+  catch(YACS::Exception& e)
+  {
+      std::ostringstream oss; oss << "YACSEvalListOfResources::notifyWantedMachine : switching from interactive/batch must be global ! " << e.what();
+      throw YACS::Exception(oss.str());
+  }
+  for(std::vector<YACSEvalResource *>::const_iterator it=_resources.begin();it!=_resources.end();it++)
+    {
+      std::size_t sz((*it)->size());
+      for(std::size_t i=0;i<sz;i++)
+        {
+          YACSEvalVirtualYACSContainer *cont((*it)->at(i));
+          if(cont==sender)
+            continue;
+          cont->setMachineNoCheck(sts.front());
+          sts.pop();
+        }
+    }
+}
+
+bool YACSEvalListOfResources::hasRightInteractiveStatus(const std::string& machineToTest, bool isInteractive) const
+{
+  const MapOfParserResourcesType& zeList(_rm->GetList());
+  std::map<std::string, ParserResourcesType>::const_iterator it(zeList.find(machineToTest));
+  if(it==zeList.end())
+    throw YACS::Exception("YACSEvalListOfResources::hasRightInteractiveStatus : internal error !");
+  const ParserResourcesType& elt((*it).second);
+  bool myStatus(elt.ClusterInternalProtocol==sh);
+  return myStatus==isInteractive;
+}
+
+void YACSEvalListOfResources::fitWithCurrentCatalog()
+{
+  std::vector<std::string> ress(getAllFittingMachines());
+  if(ress.empty())
+    throw YACS::Exception("YACSEvalListOfResources::fitWithCurrentCatalog : no available resource in your catalog !");
+  for(std::vector<YACSEvalResource *>::iterator it=_resources.begin();it!=_resources.end();it++)
+    (*it)->setMachineNoCheck(ress.front());
+}
+
+unsigned int YACSEvalListOfResources::getNumberOfProcOfResource(const std::string& machine) const
+{
+  const MapOfParserResourcesType& zeList(_rm->GetList());
+  std::map<std::string, ParserResourcesType>::const_iterator it(zeList.find(machine));
+  if(it==zeList.end())
+    throw YACS::Exception("YACSEvalListOfResources::getNumberOfProcOfResource : internal error !");
+  const ParserResourcesType& PRT((*it).second);
+  const ResourceDataToSort& RDT(PRT.DataForSort);
+  unsigned int ret(RDT._nbOfNodes*RDT._nbOfProcPerNode);
+  return ret;
+}
diff --git a/src/evalyfx/YACSEvalResource.hxx b/src/evalyfx/YACSEvalResource.hxx
new file mode 100644 (file)
index 0000000..344d764
--- /dev/null
@@ -0,0 +1,157 @@
+// Copyright (C) 2012-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
+// 
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef __YACSEVALRESOURCE_HXX__
+#define __YACSEVALRESOURCE_HXX__
+
+#include "YACSEvalYFXExport.hxx"
+
+#include <map>
+#include <string>
+#include <vector>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Container;
+    class DeploymentTree;
+  }
+}
+
+class YACSEvalNonConstLocker
+{
+public:
+  YACSEVALYFX_EXPORT YACSEvalNonConstLocker():_isLocked(false) { }
+  YACSEVALYFX_EXPORT YACSEvalNonConstLocker(const YACSEvalNonConstLocker& other):_isLocked(false) { }
+  YACSEVALYFX_EXPORT void lock() { _isLocked=true; }
+  YACSEVALYFX_EXPORT bool isLocked() const { return _isLocked; }
+  YACSEVALYFX_EXPORT void checkNonLocked() const;
+private:
+  bool _isLocked;
+};
+
+class ParserResourcesType;
+class YACSEvalResource;
+
+class YACSEvalVirtualYACSContainer : public YACSEvalNonConstLocker
+{
+public:
+  YACSEvalVirtualYACSContainer(YACSEvalResource *gf, YACS::ENGINE::Container *cont);
+  YACSEVALYFX_EXPORT ~YACSEvalVirtualYACSContainer();
+  YACSEVALYFX_EXPORT std::string getChosenMachine() const { return _chosenHost; }
+  YACSEVALYFX_EXPORT void setWantedMachine(const std::string& machine);
+  YACSEVALYFX_EXPORT std::vector<std::string> listOfPropertyKeys() const;
+  YACSEVALYFX_EXPORT std::string getValueOfKey(const char *key) const;
+  YACSEVALYFX_EXPORT void setProperty(const std::string& key, const std::string &value);
+  YACSEVALYFX_EXPORT void resetOverloadedProps() { checkNonLocked(); _overloadedPropertyMap.clear(); }
+  void apply();
+public:
+  YACSEvalVirtualYACSContainer();
+  void set(YACSEvalResource *gf, YACS::ENGINE::Container *cont);
+  void aggregate(ParserResourcesType& entry) const;
+  void setMachineNoCheck(const std::string& machine) { checkNonLocked(); _chosenHost=machine; }
+  std::string findDefault(bool isInteractive) const;
+private:
+  std::string getHostName() const { return getValueOfKey(HOSTNAME_KEY); }
+  unsigned int getMem() const { return getValueOfKeyUInt(MEM_KEY); }
+  unsigned int getNbNodes() const { return getValueOfKeyUInt(NB_NODE_KEY); }
+  unsigned int getCPUFreq() const { return getValueOfKeyUInt(CPU_CLOCK_KEY); }
+  unsigned int getNbProcPerNode() const { return getValueOfKeyUInt(NB_PROC_PER_NODE_KEY); }
+  unsigned int getValueOfKeyUInt(const char *key) const;
+  std::map<std::string,std::string> listOfPropertiesInYACSContainer() const;
+public:
+  YACSEVALYFX_EXPORT static const char CONTAINER_NAME_KEY[];
+  YACSEVALYFX_EXPORT static const char CPU_CLOCK_KEY[];
+  YACSEVALYFX_EXPORT static const char HOSTNAME_KEY[];
+  YACSEVALYFX_EXPORT static const char MEM_KEY[];
+  YACSEVALYFX_EXPORT static const char NB_NODE_KEY[];
+  YACSEVALYFX_EXPORT static const char NB_PROC_PER_NODE_KEY[];
+  YACSEVALYFX_EXPORT static const char NB_RESOURCE_PROCS_KEY[];
+  YACSEVALYFX_EXPORT static const char POLICY_KEY[];
+  YACSEVALYFX_EXPORT static const char OS_KEY[];
+private:
+  std::string _chosenHost;
+  //! list of properties that overloads.
+  std::map<std::string,std::string> _overloadedPropertyMap;
+  //! property map at the origin.
+  std::map<std::string,std::string> _propertyMap;
+  YACSEvalResource *_gf;
+  YACS::ENGINE::Container *_cont;
+};
+
+class YACSEvalListOfResources;
+
+class YACSEvalResource : public YACSEvalNonConstLocker
+{
+public:
+  YACSEVALYFX_EXPORT virtual ~YACSEvalResource();
+  YACSEVALYFX_EXPORT std::vector<std::string> getAllChosenMachines() const;
+  YACSEVALYFX_EXPORT std::vector<std::string> getAllFittingMachines() const;
+  YACSEVALYFX_EXPORT void setWantedMachine(const std::string& machine);
+  YACSEVALYFX_EXPORT std::size_t size() const { return _containers.size(); }
+  YACSEVALYFX_EXPORT YACSEvalVirtualYACSContainer *at(std::size_t i) const;
+  YACSEVALYFX_EXPORT void apply();
+public:
+  void fitWithCurrentCatalogAbs();
+  void aggregate(ParserResourcesType& entry) const;
+  YACSEvalListOfResources *getGodFather() const { return _gf; }
+  void notifyWantedMachine(YACSEvalVirtualYACSContainer *sender, const std::string& oldMachine, const std::string& newMachine);
+  void setMachineNoCheck(const std::string& machine);
+protected:
+  YACSEvalResource(YACSEvalListOfResources *gf, const std::vector< YACS::ENGINE::Container * >& conts);
+protected:
+  YACSEvalListOfResources *_gf;
+  std::vector< YACSEvalVirtualYACSContainer > _containers;
+};
+
+class ResourcesManager_cpp;
+
+class YACSEvalListOfResources : public YACSEvalNonConstLocker
+{
+public:
+  YACSEvalListOfResources(int maxLevOfPara, ResourcesManager_cpp *rm, const YACS::ENGINE::DeploymentTree& dt);
+  YACSEVALYFX_EXPORT std::vector<std::string> getAllChosenMachines() const;
+  YACSEVALYFX_EXPORT std::vector<std::string> getAllFittingMachines() const;
+  YACSEVALYFX_EXPORT void setWantedMachine(const std::string& machine);
+  YACSEVALYFX_EXPORT std::size_t size() const { return _resources.size(); }
+  YACSEVALYFX_EXPORT YACSEvalResource *at(std::size_t i) const;
+  YACSEVALYFX_EXPORT bool isInteractive() const;
+  YACSEVALYFX_EXPORT unsigned int getNumberOfProcsDeclared() const;
+  void apply();
+  YACSEVALYFX_EXPORT ~YACSEvalListOfResources();
+public:
+  ResourcesManager_cpp *getCatalogEntry() const { return _rm; }
+  YACS::ENGINE::DeploymentTree *getDeploymentTree() const { return _dt; }
+  int getMaxLevelOfParallelism() const { return _maxLevOfPara; }
+  std::vector<std::string> getFittingResources(ParserResourcesType *request) const;
+  void notifyWantedMachine(YACSEvalVirtualYACSContainer *sender, const std::string& oldMachine, const std::string& newMachine);
+  bool hasRightInteractiveStatus(const std::string& machineToTest, bool isInteractive) const;
+private:
+  void fitWithCurrentCatalog();
+  unsigned int getNumberOfProcOfResource(const std::string& machine) const;
+private:
+  ResourcesManager_cpp *_rm;
+  int _maxLevOfPara;
+  std::vector<YACSEvalResource *> _resources;
+  YACS::ENGINE::DeploymentTree *_dt;
+};
+
+#endif
diff --git a/src/evalyfx/YACSEvalSeqAny.cxx b/src/evalyfx/YACSEvalSeqAny.cxx
new file mode 100644 (file)
index 0000000..43f3fad
--- /dev/null
@@ -0,0 +1,135 @@
+// Copyright (C) 2012-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
+// 
+// Author : Anthony Geay (EDF R&D)
+
+#include "YACSEvalSeqAny.hxx"
+#include "YACSEvalPort.hxx"
+#include "Exception.hxx"
+
+#include "PythonPorts.hxx"
+
+YACSEvalSeqAny *YACSEvalSeqAny::BuildEmptyFromType(const std::string& dataType)
+{
+  if(dataType==YACSEvalAnyDouble::TYPE_REPR)
+    return new YACSEvalSeqAnyDouble;
+  else if(dataType==YACSEvalAnyInt::TYPE_REPR)
+    return new YACSEvalSeqAnyInt;
+  else
+    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));
+  _arr=YACSEvalSeqAnyInternal<double>::New(zeArr);
+}
+
+YACSEvalSeqAnyDouble::YACSEvalSeqAnyDouble(const YACSEvalSeqAnyDouble& other):_arr(other._arr)
+{
+  if(_arr)
+    _arr->incrRef();
+}
+
+YACSEvalSeqAnyDouble::YACSEvalSeqAnyDouble():_arr(YACSEvalSeqAnyInternal<double>::New(new std::vector<double>(0)))
+{
+}
+
+std::string YACSEvalSeqAnyDouble::getTypeOfConstitutingElements() const
+{
+  return std::string(YACSEvalAnyDouble::TYPE_REPR);
+}
+
+YACSEvalSeqAnyDouble *YACSEvalSeqAnyDouble::copy() const
+{
+  return new YACSEvalSeqAnyDouble(*this);
+}
+
+void YACSEvalSeqAnyDouble::initialize(YACS::ENGINE::InputPyPort *p) const
+{
+  std::size_t sz(size());
+  PyObject *ob(PyList_New(sz));
+  for(std::size_t i=0;i<sz;i++)
+    {
+      PyList_SetItem(ob,i,PyFloat_FromDouble((*_arr)[i]));
+    }
+  p->put(ob);
+  p->exSaveInit();
+  Py_XDECREF(ob);
+}
+
+std::vector<double> *YACSEvalSeqAnyDouble::getInternal() const
+{
+  if(!_arr)
+    throw YACS::Exception("YACSEvalSeqAnyDouble::getInternal : null internal ref !");
+  return _arr->getInternal();
+}
+
+YACSEvalSeqAnyInt::YACSEvalSeqAnyInt(const std::vector<int>& arr):_arr(0)
+{
+  std::vector<int> *zeArr(new std::vector<int>(arr));
+  _arr=YACSEvalSeqAnyInternal<int>::New(zeArr);
+}
+
+YACSEvalSeqAnyInt::YACSEvalSeqAnyInt(const YACSEvalSeqAnyInt& other):_arr(other._arr)
+{
+  if(_arr)
+    _arr->incrRef();
+}
+
+YACSEvalSeqAnyInt::YACSEvalSeqAnyInt():_arr(YACSEvalSeqAnyInternal<int>::New(new std::vector<int>(0)))
+{
+}
+
+std::string YACSEvalSeqAnyInt::getTypeOfConstitutingElements() const
+{
+  return std::string(YACSEvalAnyInt::TYPE_REPR);
+}
+
+YACSEvalSeqAnyInt *YACSEvalSeqAnyInt::copy() const
+{
+  return new YACSEvalSeqAnyInt(*this);
+}
+
+void YACSEvalSeqAnyInt::initialize(YACS::ENGINE::InputPyPort *p) const
+{
+  std::size_t sz(size());
+  PyObject *ob(PyList_New(sz));
+  for(std::size_t i=0;i<sz;i++)
+    {
+      PyList_SetItem(ob,i,PyInt_FromLong((*_arr)[i]));
+    }
+  p->put(ob);
+  p->exSaveInit();
+  Py_XDECREF(ob);
+}
+
+std::vector<int> *YACSEvalSeqAnyInt::getInternal() const
+{
+  if(!_arr)
+    throw YACS::Exception("YACSEvalSeqAnyInt::getInternal : null internal ref !");
+  return _arr->getInternal();
+}
diff --git a/src/evalyfx/YACSEvalSeqAny.hxx b/src/evalyfx/YACSEvalSeqAny.hxx
new file mode 100644 (file)
index 0000000..d0edbf4
--- /dev/null
@@ -0,0 +1,97 @@
+// Copyright (C) 2012-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
+// 
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef __YACSEVALSEQANY_HXX__
+#define __YACSEVALSEQANY_HXX__
+
+#include "YACSEvalYFXExport.hxx"
+#include "RefCounter.hxx"
+#include "Exception.hxx"
+
+#include <vector>
+#include <string>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class InputPyPort;
+  }
+}
+
+class YACSEvalSeqAny
+{
+public:
+  YACSEVALYFX_EXPORT static YACSEvalSeqAny *BuildEmptyFromType(const std::string& dataType);
+  YACSEVALYFX_EXPORT virtual std::size_t size() const = 0;
+  YACSEVALYFX_EXPORT virtual std::string getTypeOfConstitutingElements() const = 0;
+  YACSEVALYFX_EXPORT virtual YACSEvalSeqAny *copy() const = 0;
+  YACSEVALYFX_EXPORT virtual void initialize(YACS::ENGINE::InputPyPort *p) const = 0;
+  YACSEVALYFX_EXPORT virtual ~YACSEvalSeqAny() { }
+};
+
+template<class T>
+class YACSEvalSeqAnyInternal : public YACS::ENGINE::RefCounter
+{
+public:
+  static YACSEvalSeqAnyInternal<T> *New(std::vector<T> *arr) { return new YACSEvalSeqAnyInternal(arr); }
+  std::size_t size() const;
+  T operator[](const std::size_t i) const { if(_arr) return (*_arr)[i]; else throw YACS::Exception("YACSEvalSeqAnyInternal[] : internal pointer is null !"); }
+  std::vector<T> *getInternal() const { return _arr; }
+private:
+  ~YACSEvalSeqAnyInternal() { delete _arr; }
+  YACSEvalSeqAnyInternal(std::vector<T> *arr):_arr(arr) { }
+private:
+  std::vector<T> *_arr;
+};
+
+class YACSEvalSeqAnyDouble : public YACSEvalSeqAny
+{
+public:
+  YACSEVALYFX_EXPORT std::size_t size() const { return _arr->size(); }
+  YACSEVALYFX_EXPORT ~YACSEvalSeqAnyDouble() { if(_arr) _arr->decrRef(); }
+  YACSEVALYFX_EXPORT YACSEvalSeqAnyDouble(const std::vector<double>& arr);
+  YACSEVALYFX_EXPORT YACSEvalSeqAnyDouble(const YACSEvalSeqAnyDouble& other);
+  YACSEVALYFX_EXPORT YACSEvalSeqAnyDouble();
+  YACSEVALYFX_EXPORT std::string getTypeOfConstitutingElements() const;
+  YACSEVALYFX_EXPORT YACSEvalSeqAnyDouble *copy() const;
+  YACSEVALYFX_EXPORT void initialize(YACS::ENGINE::InputPyPort *p) const;
+  YACSEVALYFX_EXPORT std::vector<double> *getInternal() const;
+private:
+  YACSEvalSeqAnyInternal<double> *_arr;
+};
+
+class YACSEvalSeqAnyInt : public YACSEvalSeqAny
+{
+public:
+  YACSEVALYFX_EXPORT std::size_t size() const { return _arr->size(); }
+  YACSEVALYFX_EXPORT ~YACSEvalSeqAnyInt() { if(_arr) _arr->decrRef(); }
+  YACSEVALYFX_EXPORT YACSEvalSeqAnyInt(const std::vector<int>& arr);
+  YACSEVALYFX_EXPORT YACSEvalSeqAnyInt(const YACSEvalSeqAnyInt& other);
+  YACSEVALYFX_EXPORT YACSEvalSeqAnyInt();
+  YACSEVALYFX_EXPORT std::string getTypeOfConstitutingElements() const;
+  YACSEVALYFX_EXPORT YACSEvalSeqAnyInt *copy() const;
+  YACSEVALYFX_EXPORT void initialize(YACS::ENGINE::InputPyPort *p) const;
+  YACSEVALYFX_EXPORT std::vector<int> *getInternal() const;
+private:
+  YACSEvalSeqAnyInternal<int> *_arr;
+};
+
+#endif
diff --git a/src/evalyfx/YACSEvalSession.cxx b/src/evalyfx/YACSEvalSession.cxx
new file mode 100644 (file)
index 0000000..43b4478
--- /dev/null
@@ -0,0 +1,130 @@
+// Copyright (C) 2012-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
+// 
+// Author : Anthony Geay (EDF R&D)
+
+#include "YACSEvalSession.hxx"
+#include "Exception.hxx"
+
+#include <Python.h>
+
+const char YACSEvalSession::KERNEL_ROOT_DIR[]="KERNEL_ROOT_DIR";
+
+const char YACSEvalSession::CORBA_CONFIG_ENV_VAR_NAME[]="OMNIORB_CONFIG";
+
+YACSEvalSession::YACSEvalSession():_isLaunched(false),_port(-1),_salomeInstanceModule(0),_salomeInstance(0)
+{
+  if(!Py_IsInitialized())
+    Py_Initialize();
+  //
+  _salomeInstanceModule=PyImport_ImportModule(const_cast<char *>("salome_instance"));
+}
+
+YACSEvalSession::~YACSEvalSession()
+{
+  if(isLaunched())
+    {
+      PyObject *terminateSession(PyObject_GetAttrString(_salomeInstance,const_cast<char *>("stop")));//new
+      PyObject *res(PyObject_CallObject(terminateSession,0));
+      Py_XDECREF(res);
+      Py_XDECREF(terminateSession);
+    }
+  Py_XDECREF(_salomeInstance);
+  Py_XDECREF(_salomeInstanceModule);
+}
+
+void YACSEvalSession::launch()
+{
+  if(isLaunched())
+    return ;
+  PyObject *salomeInstance(PyObject_GetAttrString(_salomeInstanceModule,const_cast<char *>("SalomeInstance")));//new
+  PyObject *startMeth(PyObject_GetAttrString(salomeInstance,const_cast<char *>("start")));
+  Py_XDECREF(salomeInstance);
+  PyObject *myArgs(PyTuple_New(0));//new
+  PyObject *myKWArgs(PyDict_New());//new
+  PyDict_SetItemString(myKWArgs,"shutdown_servers",Py_True);//Py_True ref not stolen
+  _salomeInstance=PyObject_Call(startMeth,myArgs,myKWArgs);//new
+  PyObject *getPortMeth(PyObject_GetAttrString(_salomeInstance,const_cast<char *>("get_port")));//new
+  PyObject *portPy(PyObject_CallObject(getPortMeth,0));//new
+  _port=PyInt_AsLong(portPy);
+  Py_XDECREF(portPy);
+  Py_XDECREF(getPortMeth);
+  Py_XDECREF(myKWArgs);
+  Py_XDECREF(myArgs);
+  //
+  PyObject *osPy(PyImport_ImportModule(const_cast<char *>("os")));//new
+  PyObject *environPy(PyObject_GetAttrString(osPy,const_cast<char *>("environ")));//new
+  PyObject *corbaConfigStr(PyString_FromString(const_cast<char *>(CORBA_CONFIG_ENV_VAR_NAME)));//new
+  PyObject *corbaConfigFileNamePy(PyObject_GetItem(environPy,corbaConfigStr));//new
+  _corbaConfigFileName=PyString_AsString(corbaConfigFileNamePy);
+  Py_XDECREF(corbaConfigFileNamePy);
+  Py_XDECREF(corbaConfigStr);
+  Py_XDECREF(environPy);
+  Py_XDECREF(osPy);
+  _isLaunched=true;
+}
+
+void YACSEvalSession::checkLaunched() const
+{
+  if(!isLaunched())
+    throw YACS::Exception("YACSEvalSession::checkLaunched : not launched !");
+}
+
+int YACSEvalSession::getPort() const
+{
+  checkLaunched();
+  return _port;
+}
+
+std::string YACSEvalSession::getCorbaConfigFileName() const
+{
+  checkLaunched();
+  return _corbaConfigFileName;
+}
+
+std::string YACSEvalSession::GetPathToAdd()
+{
+  std::string ret;
+  PyObject *osPy(PyImport_ImportModule(const_cast<char *>("os")));//new
+  PyObject *kernelRootDir(0);// os.environ["KERNEL_ROOT_DIR"]
+  {
+    PyObject *environPy(PyObject_GetAttrString(osPy,const_cast<char *>("environ")));//new
+    PyObject *kernelRootDirStr(PyString_FromString(const_cast<char *>(KERNEL_ROOT_DIR)));//new
+    kernelRootDir=PyObject_GetItem(environPy,kernelRootDirStr);//new
+    Py_XDECREF(kernelRootDirStr);
+    Py_XDECREF(environPy);
+  }
+  {
+    PyObject *pathPy(PyObject_GetAttrString(osPy,const_cast<char *>("path")));//new
+    PyObject *joinPy(PyObject_GetAttrString(pathPy,const_cast<char *>("join")));//new
+    PyObject *myArgs(PyTuple_New(4));
+    Py_XINCREF(kernelRootDir); PyTuple_SetItem(myArgs,0,kernelRootDir);
+    PyTuple_SetItem(myArgs,1,PyString_FromString(const_cast<char *>("bin")));
+    PyTuple_SetItem(myArgs,2,PyString_FromString(const_cast<char *>("salome")));
+    PyTuple_SetItem(myArgs,3,PyString_FromString(const_cast<char *>("appliskel")));
+    PyObject *res(PyObject_CallObject(joinPy,myArgs));
+    ret=PyString_AsString(res);
+    Py_XDECREF(res);
+    Py_XDECREF(myArgs);
+    Py_XDECREF(joinPy);
+    Py_XDECREF(pathPy);
+  }
+  Py_XDECREF(kernelRootDir);
+  Py_XDECREF(osPy);
+  return ret;
+}
diff --git a/src/evalyfx/YACSEvalSession.hxx b/src/evalyfx/YACSEvalSession.hxx
new file mode 100644 (file)
index 0000000..ba62b76
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (C) 2012-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
+// 
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef __YACSEVALSESSION_HXX__
+#define __YACSEVALSESSION_HXX__
+
+#include "YACSEvalYFXExport.hxx"
+
+#include <string>
+
+struct _object;
+typedef _object PyObject;
+
+class YACSEvalSession
+{
+public:
+  YACSEVALYFX_EXPORT YACSEvalSession();
+  YACSEVALYFX_EXPORT ~YACSEvalSession();
+  YACSEVALYFX_EXPORT void launch();
+  YACSEVALYFX_EXPORT bool isLaunched() const { return _isLaunched; }
+  YACSEVALYFX_EXPORT void checkLaunched() const;
+  YACSEVALYFX_EXPORT int getPort() const;
+  YACSEVALYFX_EXPORT std::string getCorbaConfigFileName() const;
+private:
+  static std::string GetPathToAdd();
+public:
+  YACSEVALYFX_EXPORT static const char KERNEL_ROOT_DIR[];
+  YACSEVALYFX_EXPORT static const char CORBA_CONFIG_ENV_VAR_NAME[];
+private:
+  bool _isLaunched;
+  int _port;
+  std::string _corbaConfigFileName;
+  PyObject *_salomeInstanceModule;
+  PyObject *_salomeInstance;
+};
+
+#endif
diff --git a/src/evalyfx/YACSEvalYFX.cxx b/src/evalyfx/YACSEvalYFX.cxx
new file mode 100644 (file)
index 0000000..b3210bd
--- /dev/null
@@ -0,0 +1,180 @@
+// Copyright (C) 2012-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
+// 
+// Author : Anthony Geay (EDF R&D)
+
+#include "YACSEvalYFX.hxx"
+#include "YACSEvalYFXPattern.hxx"
+#include "YACSEvalAutoPtr.hxx"
+#include "YACSEvalResource.hxx"
+#include "YACSEvalSession.hxx"
+#include "YACSEvalPort.hxx"
+#include "RuntimeSALOME.hxx"
+#include "Executor.hxx"
+#include "Proc.hxx"
+#include "Exception.hxx"
+#include "parsers.hxx"
+
+#include <algorithm>
+#include <sstream>
+#include <limits>
+#include <set>
+
+#include <Python.h>
+
+class MyAutoThreadSaver
+{
+public:
+  MyAutoThreadSaver():_save(PyEval_SaveThread()) { }
+  ~MyAutoThreadSaver() { PyEval_RestoreThread(_save); }
+private:
+  PyThreadState *_save;
+};
+
+
+YACSEvalYFX *YACSEvalYFX::BuildFromFile(const std::string& xmlOfScheme)
+{
+  YACS::ENGINE::RuntimeSALOME::setRuntime();
+  YACS::YACSLoader l;
+  YACS::ENGINE::Proc *scheme(l.load(xmlOfScheme.c_str()));
+  return new YACSEvalYFX(scheme,true);
+}
+
+YACSEvalYFX *YACSEvalYFX::BuildFromScheme(YACS::ENGINE::Proc *scheme)
+{
+  return new YACSEvalYFX(scheme,false);
+}
+
+std::list< YACSEvalInputPort * > YACSEvalYFX::getFreeInputPorts() const
+{
+  return _pattern->getFreeInputPorts();
+}
+
+std::list< YACSEvalOutputPort * > YACSEvalYFX::getFreeOutputPorts() const
+{
+  return _pattern->getFreeOutputPorts();
+}
+
+void YACSEvalYFX::lockPortsForEvaluation(const std::list< YACSEvalOutputPort * >& outputsOfInterest)
+{
+  std::size_t sz(checkPortsForEvaluation(outputsOfInterest));
+  _pattern->setOutPortsOfInterestForEvaluation(sz,outputsOfInterest);
+  _pattern->generateGraph();
+}
+
+void YACSEvalYFX::unlockAll()
+{
+  std::list< YACSEvalInputPort * > allInputs(getFreeInputPorts());
+  for(std::list< YACSEvalInputPort * >::const_iterator it=allInputs.begin();it!=allInputs.end();it++)
+    (*it)->unlock();
+  _pattern->resetOutputsOfInterest();
+  _pattern->resetGeneratedGraph();
+}
+
+bool YACSEvalYFX::isLocked() const
+{
+  return _pattern->isLocked();
+}
+
+YACSEvalListOfResources *YACSEvalYFX::giveResources()
+{
+  return _pattern->giveResources();
+}
+
+bool YACSEvalYFX::run(YACSEvalSession *session, int& nbOfBranches)
+{
+  YACSEvalListOfResources *rss(giveResources());
+  if(!rss->isInteractive())
+    throw YACS::Exception("YACSEvalYFX::run : not implemented yet for non interactive !");
+  YACSEvalSession *mySession(session);
+  YACS::AutoCppPtr<YACSEvalSession> loc;
+  if(!session)
+    {
+      throw YACS::Exception("YACSEvalYFX::run : input session in null !");
+      /*loc=new YACSEvalSession;
+      mySession=loc;*/
+    }
+  rss->apply();
+  nbOfBranches=_pattern->assignNbOfBranches();
+  mySession->launch();
+  YACS::ENGINE::Executor exe;
+  //
+  {
+    MyAutoThreadSaver locker;
+    exe.RunW(getUndergroundGeneratedGraph());
+  }
+  return getUndergroundGeneratedGraph()->getState()==YACS::DONE;
+}
+
+std::vector<YACSEvalSeqAny *> YACSEvalYFX::getResults() const
+{
+  return _pattern->getResults();
+}
+
+YACS::ENGINE::Proc *YACSEvalYFX::getUndergroundGeneratedGraph() const
+{
+  return _pattern->getUndergroundGeneratedGraph();
+}
+
+YACSEvalYFX::YACSEvalYFX(YACS::ENGINE::Proc *scheme, bool ownScheme):_pattern(0)
+{
+  _pattern=YACSEvalYFXPattern::FindPatternFrom(scheme,ownScheme);
+}
+
+std::size_t YACSEvalYFX::checkPortsForEvaluation(const std::list< YACSEvalOutputPort * >& outputs) const
+{
+  std::list< YACSEvalInputPort * > allInputs(getFreeInputPorts());
+  std::list< YACSEvalOutputPort * > allOutputs(getFreeOutputPorts());
+  std::size_t sz(std::numeric_limits<std::size_t>::max());
+  for(std::list< YACSEvalInputPort * >::const_iterator it=allInputs.begin();it!=allInputs.end();it++)
+    {
+      std::size_t mySz;
+      if(!(*it)->isOKForLock() && !(*it)->hasSequenceOfValuesToEval(mySz))
+        {
+          std::ostringstream oss; oss << "YACSEvalYFX::checkPortsForEvaluation : input port with name \"" << (*it)->getName() << "\" is not set properly !";
+          throw YACS::Exception(oss.str());
+        }
+      if((*it)->hasSequenceOfValuesToEval(mySz))
+        {
+          if(sz==std::numeric_limits<std::size_t>::max())
+            sz=mySz;
+          else
+            {
+              if(sz!=mySz)
+                {
+                  std::ostringstream oss; oss << "YACSEvalYFX::checkPortsForEvaluation : input port with name \"" << (*it)->getName() << "\" is declared as to be evaluated on array ! But size of array is not the same than the others !";
+                  throw YACS::Exception(oss.str());
+                }
+            }
+        }
+    }
+  for(std::list< YACSEvalOutputPort * >::const_iterator it=outputs.begin();it!=outputs.end();it++)
+    if(std::find(allOutputs.begin(),allOutputs.end(),*it)==allOutputs.end())
+      throw YACS::Exception("YACSEvalYFX::lockPortsForEvaluation : one of output is not part of this !");
+  std::set< YACSEvalOutputPort * > soutputs(outputs.begin(),outputs.end());
+  if(soutputs.size()!=outputs.size())
+    throw YACS::Exception("YACSEvalYFX::lockPortsForEvaluation : each elt in outputs must appear once !");
+  for(std::list< YACSEvalInputPort * >::const_iterator it=allInputs.begin();it!=allInputs.end();it++)
+    (*it)->lock();
+  return sz;
+}
+
+YACSEvalYFX::~YACSEvalYFX()
+{
+  delete _pattern;
+}
diff --git a/src/evalyfx/YACSEvalYFX.hxx b/src/evalyfx/YACSEvalYFX.hxx
new file mode 100644 (file)
index 0000000..f9ccdd5
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright (C) 2012-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
+// 
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef __YACSEVALYFX_HXX__
+#define __YACSEVALYFX_HXX__
+
+#include "YACSEvalYFXExport.hxx"
+
+#include <list>
+#include <string>
+#include <vector>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Proc;
+  }
+}
+
+class YACSEvalSeqAny;
+class YACSEvalSession;
+class YACSEvalYFXPattern;
+class YACSEvalInputPort;
+class YACSEvalOutputPort;
+class YACSEvalListOfResources;
+
+class YACSEvalYFX
+{
+public:
+  YACSEVALYFX_EXPORT static YACSEvalYFX *BuildFromFile(const std::string& xmlOfScheme);
+  YACSEVALYFX_EXPORT static YACSEvalYFX *BuildFromScheme(YACS::ENGINE::Proc *scheme);
+  YACSEVALYFX_EXPORT std::list< YACSEvalInputPort * > getFreeInputPorts() const;
+  YACSEVALYFX_EXPORT std::list< YACSEvalOutputPort * > getFreeOutputPorts() const;
+  YACSEVALYFX_EXPORT void lockPortsForEvaluation(const std::list< YACSEvalOutputPort * >& outputsOfInterest);
+  YACSEVALYFX_EXPORT void unlockAll();
+  YACSEVALYFX_EXPORT bool isLocked() const;
+  YACSEVALYFX_EXPORT YACSEvalListOfResources *giveResources();
+  YACSEVALYFX_EXPORT bool run(YACSEvalSession *session, int& nbOfBranches);
+  YACSEVALYFX_EXPORT std::vector<YACSEvalSeqAny *> getResults() const;
+  //
+  YACSEVALYFX_EXPORT YACS::ENGINE::Proc *getUndergroundGeneratedGraph() const;
+  YACSEVALYFX_EXPORT ~YACSEvalYFX();
+private:
+  YACSEvalYFX(YACS::ENGINE::Proc *scheme, bool ownScheme);
+  std::size_t checkPortsForEvaluation(const std::list< YACSEvalOutputPort * >& outputs) const;
+private:
+  YACSEvalYFXPattern *_pattern;
+};
+
+#endif
diff --git a/src/evalyfx/YACSEvalYFXExport.hxx b/src/evalyfx/YACSEvalYFXExport.hxx
new file mode 100644 (file)
index 0000000..3ef78fd
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright (C) 2012-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
+//
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef __YACSEVALYFXEXPORT_HXX__
+#define __YACSEVALYFXEXPORT_HXX__
+
+#ifdef WIN32
+#  if defined YACSEVALYFX_EXPORTS
+#    define YACSEVALYFX_EXPORT __declspec( dllexport )
+#  else
+#    define YACSEVALYFX_EXPORT __declspec( dllimport )
+#  endif
+#else
+#  define YACSEVALYFX_EXPORT
+#endif
+
+#endif
diff --git a/src/evalyfx/YACSEvalYFXPattern.cxx b/src/evalyfx/YACSEvalYFXPattern.cxx
new file mode 100644 (file)
index 0000000..9ac3852
--- /dev/null
@@ -0,0 +1,491 @@
+// Copyright (C) 2012-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
+// 
+// Author : Anthony Geay (EDF R&D)
+
+#include "YACSEvalYFXPattern.hxx"
+#include "YACSEvalResource.hxx"
+#include "YACSEvalSeqAny.hxx"
+#include "YACSEvalAutoPtr.hxx"
+
+#include "ElementaryNode.hxx"
+#include "RuntimeSALOME.hxx"
+#include "InputPort.hxx"
+#include "LinkInfo.hxx"
+#include "TypeCode.hxx"
+#include "Proc.hxx"
+
+#include "PythonPorts.hxx"
+#include "ForEachLoop.hxx"
+#include "PythonNode.hxx"
+#include "InlineNode.hxx"
+#include "ServiceNode.hxx"
+
+#include "ResourcesManager.hxx"
+
+#include <map>
+#include <numeric>
+#include <sstream>
+
+const char YACSEvalYFXPattern::DFT_PROC_NAME[]="YFX";
+
+const char YACSEvalYFXRunOnlyPattern::GATHER_NODE_NAME[]="__gather__";
+
+std::list< YACSEvalInputPort *> YACSEvalYFXPattern::getFreeInputPorts() const
+{
+  std::size_t sz(_inputs.size());
+  std::list< YACSEvalInputPort *> ret;
+  std::list< YACSEvalInputPort >::const_iterator it(_inputs.begin());
+  for(std::size_t i=0;i<sz;i++,it++)
+    ret.push_back(const_cast<YACSEvalInputPort *>(&(*it)));
+  return ret;
+}
+
+std::list< YACSEvalOutputPort *> YACSEvalYFXPattern::getFreeOutputPorts() const
+{
+  std::size_t sz(_outputs.size());
+  std::list< YACSEvalOutputPort *> ret;
+  std::list< YACSEvalOutputPort >::const_iterator it(_outputs.begin());
+  for(std::size_t i=0;i<sz;i++,it++)
+    ret.push_back(const_cast<YACSEvalOutputPort *>(&(*it)));
+  return ret;
+}
+
+YACSEvalYFXPattern *YACSEvalYFXPattern::FindPatternFrom(YACS::ENGINE::Proc *scheme, bool ownScheme)
+{
+  if(!scheme)
+    throw YACS::Exception("YACSEvalYFXPattern::FindPatternFrom : input scheme must be not null !");
+  {
+      YACS::ENGINE::ComposedNode *zeRunNode(0);
+      bool isMatchingRunOnlyPattern(YACSEvalYFXRunOnlyPattern::IsMatching(scheme,zeRunNode));
+      if(isMatchingRunOnlyPattern)
+        return new YACSEvalYFXRunOnlyPattern(scheme,ownScheme,zeRunNode);
+  }
+  throw YACS::Exception("YACSEvalYFXPattern::FindPatternFrom : no pattern found for the input scheme !");
+}
+
+bool YACSEvalYFXPattern::isAlreadyComputedResources() const
+{
+  return _res!=0;
+}
+
+void YACSEvalYFXPattern::checkNonAlreadyComputedResources() const
+{
+  if(isAlreadyComputedResources())
+    throw YACS::Exception("checkNonAlreadyComputedResources : instance of computed resources already computed !");
+}
+
+void YACSEvalYFXPattern::checkAlreadyComputedResources() const
+{
+  if(!isAlreadyComputedResources())
+    throw YACS::Exception("checkAlreadyComputedResources : instance of computed resources not already computed !");
+}
+
+void YACSEvalYFXPattern::checkLocked() const
+{
+  if(!isLocked())
+    throw YACS::Exception("YACSEvalYFXPattern::checkLocked : Pattern is not locked !");
+}
+
+void YACSEvalYFXPattern::checkNonLocked() const
+{
+  if(isLocked())
+    throw YACS::Exception("YACSEvalYFXPattern::checkNonLocked : Pattern is locked !");
+}
+
+void YACSEvalYFXPattern::CheckNodeIsOK(YACS::ENGINE::ComposedNode *node)
+{
+  /*YACS::ENGINE::LinkInfo info(YACS::ENGINE::LinkInfo::WARN_ONLY_DONT_STOP);
+  try
+  {
+      node->checkConsistency(info);
+  }
+  catch(YACS::Exception& e)
+  {
+  }
+  if(info.getNumberOfErrLinks(YACS::ENGINE::E_ALL)!=0)
+    throw YACS::Exception("YACSEvalYFXPattern::CheckNodeIsOK : found node is not OK !");
+  std::list<YACS::ENGINE::ElementaryNode *> allNodes(node->getRecursiveConstituents());
+  for(std::list<YACS::ENGINE::ElementaryNode *>::const_iterator it=allNodes.begin();it!=allNodes.end();it++)
+    {
+      YACS::ENGINE::ServiceNode *node0(dynamic_cast<YACS::ENGINE::ServiceNode *>(*it));
+      YACS::ENGINE::InlineNode *node1(dynamic_cast<YACS::ENGINE::InlineNode *>(*it));
+      if(node0)
+        {
+          YACS::ENGINE::Container *cont(node0->getContainer());
+          YACS::ENGINE::ComponentInstance *comp(node0->getComponent());
+          if(!cont || !comp)
+            {
+              std::ostringstream oss; oss << "YACSEvalYFXPattern::CheckNodeIsOK : ServiceNode called \"" << node0->getName() << "\" is not correctly defined !";
+              throw YACS::Exception(oss.str());
+            }
+        }
+      if(node1)
+        {
+          YACS::ENGINE::Container *cont(node1->getContainer());
+          if(!cont && node1->getExecutionMode()==YACS::ENGINE::InlineNode::REMOTE_STR)
+            {
+              std::ostringstream oss; oss << "YACSEvalYFXPattern::CheckNodeIsOK : InlineNode called \"" << node1->getName() << "\" is not correctly defined !";
+              throw YACS::Exception(oss.str());
+            }
+        }
+    }*/
+}
+
+YACSEvalYFXPattern::YACSEvalYFXPattern(YACS::ENGINE::Proc *scheme, bool ownScheme):_scheme(scheme),_ownScheme(ownScheme),_rm(new ResourcesManager_cpp),_res(0)
+{
+}
+
+YACS::ENGINE::TypeCode *YACSEvalYFXPattern::createSeqTypeCodeFrom(YACS::ENGINE::Proc *scheme, const std::string& zeType)
+{
+  std::ostringstream oss; oss << "list[" << zeType << "]";
+  YACS::ENGINE::TypeCode *tc(scheme->getTypeCode(zeType));
+  return scheme->createSequenceTc(oss.str(),oss.str(),tc);
+}
+
+void YACSEvalYFXPattern::setResources(YACSEvalListOfResources *res)
+{
+  checkNonAlreadyComputedResources();
+  if(res!=_res)
+    delete _res;
+  _res=res;
+}
+
+void YACSEvalYFXPattern::resetResources()
+{
+  delete _res;
+  _res=0;
+}
+
+YACSEvalSeqAny *YACSEvalYFXPattern::BuildValueInPort(YACS::ENGINE::InputPyPort *port)
+{
+  if(!port)
+    throw YACS::Exception("YACSEvalYFXPattern::GetValueInPort : null input port !");
+  PyObject *obj(port->getPyObj());
+  YACS::ENGINE::TypeCode *tc(port->edGetType());
+  YACS::ENGINE::TypeCodeSeq *tcc(dynamic_cast<YACS::ENGINE::TypeCodeSeq *>(tc));
+  if(!tcc)
+    {
+      std::ostringstream oss; oss << "YACSEvalYFXPattern::GetValueInPort : internal error for tc of input \"" << port->getName() << "\"";
+      throw YACS::Exception(oss.str());
+    }
+  const YACS::ENGINE::TypeCode *tcct(tcc->contentType());
+  if(!PyList_Check(obj))
+    throw YACS::Exception("YACSEvalYFXPattern::GetValueInPort : internal error 2 !");
+  std::size_t sz(PyList_Size(obj));
+  if(tcct->kind()==YACS::ENGINE::Double)
+    {
+      std::vector<double> eltCpp(sz);
+      for(std::size_t i=0;i<sz;i++)
+        {
+          PyObject *elt(PyList_GetItem(obj,i));
+          eltCpp[i]=PyFloat_AsDouble(elt);
+        }
+      YACS::AutoCppPtr<YACSEvalSeqAnyDouble> elt(new YACSEvalSeqAnyDouble(eltCpp));
+      return elt.dettach();
+    }
+  else if(tcct->kind()==YACS::ENGINE::Int)
+    {
+      std::vector<int> eltCpp(sz);
+      for(std::size_t i=0;i<sz;i++)
+        {
+          PyObject *elt(PyList_GetItem(obj,i));
+          eltCpp[i]=PyInt_AsLong(elt);
+        }
+      YACS::AutoCppPtr<YACSEvalSeqAnyInt> elt(new YACSEvalSeqAnyInt(eltCpp));
+      return elt.dettach();
+    }
+  else
+    throw YACS::Exception("YACSEvalYFXPattern::GetValueInPort : not implemented yet for other than Double and Int !");
+}
+
+void YACSEvalYFXPattern::cleanScheme()
+{
+  if(_ownScheme)
+    delete _scheme;
+  _scheme=0;
+}
+
+YACSEvalYFXPattern::~YACSEvalYFXPattern()
+{
+  delete _rm;
+  delete _res;
+}
+
+YACSEvalYFXRunOnlyPattern::YACSEvalYFXRunOnlyPattern(YACS::ENGINE::Proc *scheme, bool ownScheme, YACS::ENGINE::ComposedNode *runNode):YACSEvalYFXPattern(scheme,ownScheme),_runNode(runNode),_commonSz(0),_generatedGraph(0)
+{
+  if(!_runNode)
+    throw YACS::Exception("YACSEvalYFXRunOnlyPattern : internal run node must be not null !");
+  buildInputPorts();
+  buildOutputPorts();
+}
+
+void YACSEvalYFXRunOnlyPattern::setOutPortsOfInterestForEvaluation(std::size_t commonSize, const std::list<YACSEvalOutputPort *>& outputsOfInterest)
+{
+  checkNonLocked();
+  _commonSz=commonSize;
+  _outputsOfInterest=outputsOfInterest;
+}
+
+void YACSEvalYFXRunOnlyPattern::resetOutputsOfInterest()
+{
+  checkLocked();
+  _commonSz=0;
+  _outputsOfInterest.clear();
+}
+
+void YACSEvalYFXRunOnlyPattern::generateGraph()
+{
+  static const char LISTPYOBJ_STR[]="list[pyobj]";
+  if(_commonSz==0 || _outputsOfInterest.empty())
+    return ;
+  YACS::ENGINE::RuntimeSALOME::setRuntime();
+  YACS::ENGINE::RuntimeSALOME *r(YACS::ENGINE::getSALOMERuntime());
+  _generatedGraph=r->createProc(DFT_PROC_NAME);
+  YACS::ENGINE::TypeCode *pyobjTC(_generatedGraph->createInterfaceTc("python:obj:1.0","pyobj",std::list<YACS::ENGINE::TypeCodeObjref *>()));
+  std::ostringstream oss; oss << "Loop_" << _runNode->getName();
+  _generatedGraph->createType(YACSEvalAnyDouble::TYPE_REPR,"double");
+  _generatedGraph->createType(YACSEvalAnyInt::TYPE_REPR,"int");
+  //
+  YACS::ENGINE::InlineNode *n0(r->createScriptNode(YACS::ENGINE::PythonNode::KIND,"__initializer__"));
+  _generatedGraph->edAddChild(n0);
+  YACS::ENGINE::TypeCode *listPyobjTC(_generatedGraph->createSequenceTc(LISTPYOBJ_STR,LISTPYOBJ_STR,pyobjTC));
+  YACS::ENGINE::OutputPort *sender(n0->edAddOutputPort("sender",listPyobjTC));
+  std::ostringstream var0;
+  for(std::list< YACSEvalInputPort >::const_iterator it=_inputs.begin();it!=_inputs.end();it++)
+    {
+      std::size_t dummy;
+      if((*it).hasSequenceOfValuesToEval(dummy))
+        {
+          var0 << (*it).getName() << ",";
+          YACS::ENGINE::TypeCode *tc(createSeqTypeCodeFrom(_generatedGraph,(*it).getTypeOfData()));
+          YACS::ENGINE::InputPort *inp(n0->edAddInputPort((*it).getName(),tc));
+          YACS::ENGINE::InputPyPort *inpc(dynamic_cast<YACS::ENGINE::InputPyPort *>(inp));
+          if(!inpc)
+            throw YACS::Exception("YACSEvalYFXRunOnlyPattern::generateGraph : internal error 1 !");
+          (*it).initializeUndergroundWithSeq(inpc);
+        }
+    }
+  std::ostringstream n0Script; n0Script << "sender=zip(" << var0.str() << ")\n";
+  n0->setScript(n0Script.str());
+  //
+  YACS::ENGINE::ForEachLoop *n1(r->createForEachLoop(oss.str(),pyobjTC));
+  _generatedGraph->edAddChild(n1);
+  _generatedGraph->edAddCFLink(n0,n1);
+  _generatedGraph->edAddDFLink(sender,n1->edGetSeqOfSamplesPort());
+  YACS::ENGINE::InlineNode *n2(r->createScriptNode(YACS::ENGINE::PythonNode::KIND,GATHER_NODE_NAME));
+  _generatedGraph->edAddChild(n2);
+  _generatedGraph->edAddCFLink(n1,n2);
+  //
+  YACS::ENGINE::Bloc *n10(r->createBloc("Bloc"));
+  n1->edAddChild(n10);
+  YACS::ENGINE::InlineNode *n100(r->createScriptNode(YACS::ENGINE::PythonNode::KIND,"__dispatch__"));
+  YACS::ENGINE::Node *n101(_runNode->cloneWithoutCompAndContDeepCpy(0,true));
+  n10->edAddChild(n100);
+  n10->edAddChild(n101);
+  YACS::ENGINE::InputPort *dispatchIn(n100->edAddInputPort("i0",pyobjTC));
+  n10->edAddCFLink(n100,n101);
+  n1->edAddDFLink(n1->edGetSamplePort(),dispatchIn);
+  std::ostringstream var1;
+  for(std::list< YACSEvalInputPort >::const_iterator it=_inputs.begin();it!=_inputs.end();it++)
+    {
+      std::size_t dummy;
+      if((*it).hasSequenceOfValuesToEval(dummy))
+        {
+          var1 << (*it).getName() << ",";
+          YACS::ENGINE::OutputPort *myOut(n100->edAddOutputPort((*it).getName(),_generatedGraph->getTypeCode((*it).getTypeOfData())));
+          std::string tmpPortName(_runNode->getInPortName((*it).getUndergroundPtr()));
+          YACS::ENGINE::InputPort *myIn(n101->getInputPort(tmpPortName));
+          n10->edAddDFLink(myOut,myIn);
+        }
+    }
+  std::ostringstream n100Script;  n100Script << var1.str() << "=i0\n";
+  n100->setScript(n100Script.str());
+  for(std::list< YACSEvalOutputPort * >::const_iterator it=_outputsOfInterest.begin();it!=_outputsOfInterest.end();it++)
+    {
+      YACS::ENGINE::TypeCode *tc(createSeqTypeCodeFrom(_generatedGraph,(*it)->getTypeOfData()));
+      YACS::ENGINE::InputPort *myIn(n2->edAddInputPort((*it)->getName(),tc));
+      std::string tmpPortName(_runNode->getOutPortName((*it)->getUndergroundPtr()));
+      YACS::ENGINE::OutputPort *myOut(n101->getOutputPort(tmpPortName));
+      _generatedGraph->edAddDFLink(myOut,myIn);
+    }
+  _generatedGraph->updateContainersAndComponents();
+}
+
+void YACSEvalYFXRunOnlyPattern::resetGeneratedGraph()
+{
+  delete _generatedGraph;
+  _generatedGraph=0;
+  resetResources();
+}
+
+int YACSEvalYFXRunOnlyPattern::assignNbOfBranches()
+{
+  checkAlreadyComputedResources();
+  if(!_generatedGraph)
+    throw YACS::Exception("YACSEvalYFXRunOnlyPattern::assignNbOfBranches : the generated graph has not been created !");
+  std::list<YACS::ENGINE::Node *> nodes(_generatedGraph->getChildren());
+  YACS::ENGINE::ForEachLoop *zeMainNode(0);
+  for(std::list<YACS::ENGINE::Node *>::const_iterator it=nodes.begin();it!=nodes.end();it++)
+    {
+      YACS::ENGINE::ForEachLoop *isZeMainNode(dynamic_cast<YACS::ENGINE::ForEachLoop *>(*it));
+      if(isZeMainNode)
+        {
+          if(!zeMainNode)
+            zeMainNode=isZeMainNode;
+          else
+            throw YACS::Exception("YACSEvalYFXRunOnlyPattern::assignNbOfBranches : internal error 1 !");
+        }
+    }
+  if(!zeMainNode)
+    throw YACS::Exception("YACSEvalYFXRunOnlyPattern::assignNbOfBranches : internal error 2 !");
+  unsigned int nbProcsDeclared(getResourcesInternal()->getNumberOfProcsDeclared());
+  nbProcsDeclared=std::max(nbProcsDeclared,4u);
+  int nbOfBranch(nbProcsDeclared/getResourcesInternal()->getMaxLevelOfParallelism());
+  nbOfBranch=std::max(nbOfBranch,1);
+  YACS::ENGINE::InputPort *zeInputToSet(zeMainNode->edGetNbOfBranchesPort());
+  YACS::ENGINE::AnyInputPort *zeInputToSetC(dynamic_cast<YACS::ENGINE::AnyInputPort *>(zeInputToSet));
+  if(!zeInputToSetC)
+    throw YACS::Exception("YACSEvalYFXRunOnlyPattern::assignNbOfBranches : internal error 3 !");
+  YACS::ENGINE::Any *a(YACS::ENGINE::AtomAny::New(nbOfBranch));
+  zeInputToSetC->put(a);
+  zeInputToSetC->exSaveInit();
+  a->decrRef();
+  return nbOfBranch;
+}
+
+bool YACSEvalYFXRunOnlyPattern::isLocked() const
+{
+  return _generatedGraph!=0;
+}
+
+YACSEvalListOfResources *YACSEvalYFXRunOnlyPattern::giveResources()
+{
+  checkLocked();
+  if(!isAlreadyComputedResources())
+    {
+      YACS::ENGINE::DeploymentTree dt(_runNode->getDeploymentTree());
+      YACSEvalListOfResources *res(new YACSEvalListOfResources(_runNode->getMaxLevelOfParallelism(),getCatalogInAppli(),dt));
+      setResources(res);
+    }
+  return getResourcesInternal();
+}
+
+YACS::ENGINE::Proc *YACSEvalYFXRunOnlyPattern::getUndergroundGeneratedGraph() const
+{
+  return _generatedGraph;
+}
+
+std::vector<YACSEvalSeqAny *> YACSEvalYFXRunOnlyPattern::getResults() const
+{
+  if(_generatedGraph->getState()!=YACS::DONE)
+    throw YACS::Exception("YACSEvalYFXRunOnlyPattern::getResults : the execution did not finished correctly ! getResults should not be called !");
+  std::vector<YACSEvalSeqAny *> ret(_outputsOfInterest.size());
+  YACS::ENGINE::Node *node(_generatedGraph->getChildByName(GATHER_NODE_NAME));
+  YACS::ENGINE::PythonNode *nodeC(dynamic_cast<YACS::ENGINE::PythonNode *>(node));
+  if(!nodeC)
+    throw YACS::Exception("YACSEvalYFXRunOnlyPattern::getResults : internal error !");
+  std::size_t ii(0);
+  for(std::list< YACSEvalOutputPort * >::const_iterator it=_outputsOfInterest.begin();it!=_outputsOfInterest.end();it++,ii++)
+    {
+      YACS::ENGINE::InPort *input(nodeC->getInPort((*it)->getName()));
+      YACS::ENGINE::InputPyPort *inputC(dynamic_cast<YACS::ENGINE::InputPyPort *>(input));
+      if(!inputC)
+        {
+          std::ostringstream oss; oss << "YACSEvalYFXRunOnlyPattern::getResults : internal error for input \"" << (*it)->getName() << "\"";
+          throw YACS::Exception(oss.str());
+        }
+      ret[ii]=BuildValueInPort(inputC);
+    }
+  return ret;
+}
+
+bool YACSEvalYFXRunOnlyPattern::IsMatching(YACS::ENGINE::Proc *scheme, YACS::ENGINE::ComposedNode *& runNode)
+{
+  std::list<YACS::ENGINE::Node *> nodes(scheme->getChildren());
+  if(nodes.empty())
+    return false;
+  bool areAllElementary(true);
+  for(std::list<YACS::ENGINE::Node *>::const_iterator it=nodes.begin();it!=nodes.end() && areAllElementary;it++)
+    if(!dynamic_cast<YACS::ENGINE::ElementaryNode *>(*it))
+      areAllElementary=false;
+  if(areAllElementary)
+    {
+      if(scheme)
+        CheckNodeIsOK(scheme);
+      runNode=scheme;
+      return true;
+    }
+  if(nodes.size()!=1)
+    return false;
+  YACS::ENGINE::ComposedNode *candidate(dynamic_cast<YACS::ENGINE::ComposedNode *>(nodes.front()));
+  runNode=candidate;
+  if(candidate)
+    CheckNodeIsOK(candidate);
+  return candidate!=0;
+}
+
+void YACSEvalYFXRunOnlyPattern::buildInputPorts()
+{
+  _inputs.clear();
+  std::list< YACS::ENGINE::InputPort *> allInputPorts(_runNode->getSetOfInputPort());
+  std::vector<std::string> allNames;
+  for(std::list< YACS::ENGINE::InputPort *>::const_iterator it=allInputPorts.begin();it!=allInputPorts.end();it++)
+    {
+      YACS::ENGINE::InputPort *elt(*it);
+      if(!elt)
+        throw YACS::Exception("YACSEvalYFXRunOnlyPattern::buildInputPorts : presence of null input !");
+      std::set<YACS::ENGINE::OutPort *> bls(elt->edSetOutPort());
+      if(bls.empty())
+        {
+          std::string inpName(elt->getName());
+          if(inpName.empty())
+            throw YACS::Exception("YACSEvalYFXRunOnlyPattern::buildInputPorts : an input has empty name ! Should not !");
+          _inputs.push_back(YACSEvalInputPort(elt));
+          if(std::find(allNames.begin(),allNames.end(),inpName)!=allNames.end())
+            {
+              std::ostringstream oss; oss << "YACSEvalYFXRunOnlyPattern::buildInputPorts : input name \"" << inpName << "\" appears more than once !";
+              throw YACS::Exception(oss.str());
+            }
+          allNames.push_back(inpName);
+        }
+    }
+}
+
+void YACSEvalYFXRunOnlyPattern::buildOutputPorts()
+{
+  _outputs.clear();
+  std::list< YACS::ENGINE::OutputPort *> allOutputPorts(_runNode->getSetOfOutputPort());
+  std::vector<std::string> allNames;
+  for(std::list< YACS::ENGINE::OutputPort *>::const_iterator it=allOutputPorts.begin();it!=allOutputPorts.end();it++)
+    {
+      YACS::ENGINE::OutputPort *elt(*it);
+      if(!elt)
+        throw YACS::Exception("YACSEvalYFXRunOnlyPattern::buildOutputPorts : presence of null output !");
+      std::string outpName(elt->getName());
+      if(outpName.empty())
+        throw YACS::Exception("YACSEvalYFXRunOnlyPattern::buildOutputPorts : an output has empty name ! Should not !");
+      if(std::find(allNames.begin(),allNames.end(),outpName)!=allNames.end())
+        {
+          std::ostringstream oss; oss << "YACSEvalYFXRunOnlyPattern::buildOutputPorts : output name \"" << outpName << "\" appears more than once !";
+          throw YACS::Exception(oss.str());
+        }
+      _outputs.push_back(YACSEvalOutputPort(*it));
+    }
+}
+
diff --git a/src/evalyfx/YACSEvalYFXPattern.hxx b/src/evalyfx/YACSEvalYFXPattern.hxx
new file mode 100644 (file)
index 0000000..063dae7
--- /dev/null
@@ -0,0 +1,113 @@
+// Copyright (C) 2012-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
+// 
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef __YACSEVALYFXPATTERN_HXX__
+#define __YACSEVALYFXPATTERN_HXX__
+
+#include "YACSEvalPort.hxx"
+
+#include <list>
+#include <vector>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Proc;
+    class TypeCode;
+    class ComposedNode;
+    class InputPyPort;
+  }
+}
+
+class YACSEvalListOfResources;
+class ResourcesManager_cpp;
+
+class YACSEvalYFXPattern
+{
+public:
+  virtual ~YACSEvalYFXPattern();
+  std::list< YACSEvalInputPort *> getFreeInputPorts() const;
+  std::list< YACSEvalOutputPort *> getFreeOutputPorts() const;
+  static YACSEvalYFXPattern *FindPatternFrom(YACS::ENGINE::Proc *scheme, bool ownScheme);
+  bool isAlreadyComputedResources() const;
+  void checkNonAlreadyComputedResources() const;
+  void checkAlreadyComputedResources() const;
+  void checkLocked() const;
+  void checkNonLocked() const;
+  static void CheckNodeIsOK(YACS::ENGINE::ComposedNode *node);
+  virtual void setOutPortsOfInterestForEvaluation(std::size_t commonSize, const std::list<YACSEvalOutputPort *>& outputs) = 0;
+  virtual void resetOutputsOfInterest() = 0;
+  virtual void generateGraph() = 0;
+  virtual void resetGeneratedGraph() = 0;
+  virtual int assignNbOfBranches() = 0;
+  virtual bool isLocked() const = 0;
+  virtual YACSEvalListOfResources *giveResources() = 0;
+  virtual YACS::ENGINE::Proc *getUndergroundGeneratedGraph() const = 0;
+  virtual std::vector<YACSEvalSeqAny *> getResults() const = 0;
+public:
+  static const char DFT_PROC_NAME[];
+protected:
+  YACSEvalYFXPattern(YACS::ENGINE::Proc *scheme, bool ownScheme);
+  YACS::ENGINE::TypeCode *createSeqTypeCodeFrom(YACS::ENGINE::Proc *scheme, const std::string& zeType);
+  void setResources(YACSEvalListOfResources *res);
+  void resetResources();
+  YACSEvalListOfResources *getResourcesInternal() const { return _res; }
+  ResourcesManager_cpp *getCatalogInAppli() const { return _rm; }
+  static YACSEvalSeqAny *BuildValueInPort(YACS::ENGINE::InputPyPort *port);
+private:
+  void cleanScheme();
+private:
+  bool _ownScheme;
+  YACS::ENGINE::Proc *_scheme;
+  ResourcesManager_cpp *_rm;
+  YACSEvalListOfResources *_res;
+protected:
+  std::list< YACSEvalInputPort > _inputs;
+  std::list< YACSEvalOutputPort > _outputs;
+};
+
+class YACSEvalYFXRunOnlyPattern : public YACSEvalYFXPattern
+{
+public:
+  YACSEvalYFXRunOnlyPattern(YACS::ENGINE::Proc *scheme, bool ownScheme, YACS::ENGINE::ComposedNode *runNode);
+  void setOutPortsOfInterestForEvaluation(std::size_t commonSize, const std::list<YACSEvalOutputPort *>& outputsOfInterest);
+  void resetOutputsOfInterest();
+  void generateGraph();
+  void resetGeneratedGraph();
+  int assignNbOfBranches();
+  bool isLocked() const;
+  YACSEvalListOfResources *giveResources();
+  YACS::ENGINE::Proc *getUndergroundGeneratedGraph() const;
+  std::vector<YACSEvalSeqAny *> getResults() const;
+  static bool IsMatching(YACS::ENGINE::Proc *scheme, YACS::ENGINE::ComposedNode *& runNode);
+public:
+  static const char GATHER_NODE_NAME[];
+private:
+  void buildInputPorts();
+  void buildOutputPorts();
+private:
+  YACS::ENGINE::ComposedNode *_runNode;
+  std::size_t _commonSz;
+  std::list<YACSEvalOutputPort *> _outputsOfInterest;
+  YACS::ENGINE::Proc *_generatedGraph;
+};
+
+#endif
diff --git a/src/evalyfx_swig/CMakeLists.txt b/src/evalyfx_swig/CMakeLists.txt
new file mode 100644 (file)
index 0000000..79522c7
--- /dev/null
@@ -0,0 +1,63 @@
+# Copyright (C) 2012-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(${SWIG_USE_FILE})
+
+# additional include directories
+INCLUDE_DIRECTORIES(
+  ${PROJECT_SOURCE_DIR}/src/bases
+  ${PROJECT_SOURCE_DIR}/src/engine
+  ${PROJECT_SOURCE_DIR}/src/engine_swig
+  ${PROJECT_SOURCE_DIR}/src/yacsloader
+  ${PROJECT_SOURCE_DIR}/src/yacsloader_swig
+  ${PROJECT_SOURCE_DIR}/src/evalyfx
+  ${OMNIORB_INCLUDE_DIR}
+  ${PYTHON_INCLUDE_DIRS}
+)
+
+# swig flags
+SET_SOURCE_FILES_PROPERTIES(evalyfx.i PROPERTIES CPLUSPLUS ON SWIG_DEFINITIONS "-shadow")
+
+SET_PROPERTY(SOURCE evalyfx.i PROPERTY SWIG_FLAGS "-noexcept" "-DYACS_PTHREAD")
+
+# additional preprocessor / compiler flags
+ADD_DEFINITIONS(
+  ${PYTHON_DEFINITIONS}
+  ${OMNIORB_DEFINITIONS}
+  )
+
+# libraries to link to
+SET(_link_LIBRARIES
+  YACSevalYFX
+  ${PYTHON_LIBRARIES}
+  ${OMNIORB_LIBRARIES}
+  )
+
+SET(_swig_SCRIPTS ${CMAKE_CURRENT_BINARY_DIR}/evalyfx.py)
+
+SWIG_ADD_MODULE(evalyfx python evalyfx.i)
+
+SWIG_LINK_LIBRARIES(evalyfx ${_link_LIBRARIES})
+IF(WIN32)
+  SET_TARGET_PROPERTIES(_evalyfx PROPERTIES DEBUG_OUTPUT_NAME _evalyfx_d)
+ENDIF(WIN32)
+
+INSTALL(TARGETS ${SWIG_MODULE_evalyfx_REAL_NAME} DESTINATION ${SALOME_INSTALL_PYTHON})
+
+SALOME_INSTALL_SCRIPTS("${_swig_SCRIPTS}"  ${SALOME_INSTALL_PYTHON})
diff --git a/src/evalyfx_swig/evalyfx.i b/src/evalyfx_swig/evalyfx.i
new file mode 100644 (file)
index 0000000..6d9ee76
--- /dev/null
@@ -0,0 +1,431 @@
+// Copyright (C) 2012-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
+//
+// Author : Anthony Geay (EDF R&D)
+
+%define EVALYFXDOCSTRING
+"Module to evaluate Y=f(X) easily."
+%enddef
+
+%module(docstring=EVALYFXDOCSTRING) evalyfx
+
+%feature("autodoc", "1");
+
+%include "engtypemaps.i"
+
+%{
+#include "YACSEvalYFX.hxx"
+#include "YACSEvalPort.hxx"
+#include "YACSEvalSeqAny.hxx"
+#include "YACSEvalResource.hxx"
+#include "YACSEvalSession.hxx"
+
+static void convertPyToIntArr(PyObject *pyLi, std::vector<int>& arr)
+{
+  if(PyList_Check(pyLi))
+    {
+      int size=PyList_Size(pyLi);
+      arr.resize(size);
+      for(int i=0;i<size;i++)
+        {
+          PyObject *o=PyList_GetItem(pyLi,i);
+          if(PyInt_Check(o))
+            {
+              int val=(int)PyInt_AS_LONG(o);
+              arr[i]=val;
+            }
+          else
+            throw YACS::Exception("list must contain integers only");
+        }
+    }
+  else if(PyTuple_Check(pyLi))
+    {
+      int size=PyTuple_Size(pyLi);
+      arr.resize(size);
+      for(int i=0;i<size;i++)
+        {
+          PyObject *o=PyTuple_GetItem(pyLi,i);
+          if(PyInt_Check(o))
+            {
+              int val=(int)PyInt_AS_LONG(o);
+              arr[i]=val;
+            }
+          else
+            throw YACS::Exception("tuple must contain integers only");
+        }
+    }
+  else
+    {
+      throw YACS::Exception("convertPyToIntArr : not a list nor a tuple");
+    }
+}
+
+static void convertPyToDblArr(PyObject *pyLi, std::vector<double>& arr)
+{
+  if(PyList_Check(pyLi))
+    {
+      int size=PyList_Size(pyLi);
+      arr.resize(size);
+      for(int i=0;i<size;i++)
+        {
+          PyObject *o=PyList_GetItem(pyLi,i);
+          if(PyFloat_Check(o))
+            {
+              double val(PyFloat_AS_DOUBLE(o));
+              arr[i]=val;
+            }
+          else
+            throw YACS::Exception("list must contain integers only");
+        }
+    }
+  else if(PyTuple_Check(pyLi))
+    {
+      int size=PyTuple_Size(pyLi);
+      arr.resize(size);
+      for(int i=0;i<size;i++)
+        {
+          PyObject *o=PyTuple_GetItem(pyLi,i);
+          if(PyFloat_Check(o))
+            {
+              double val(PyFloat_AS_DOUBLE(o));
+              arr[i]=val;
+            }
+          else
+            throw YACS::Exception("tuple must contain floats only");
+        }
+    }
+  else
+    {
+      throw YACS::Exception("convertPyToNewIntArr3 : not a list nor a tuple");
+    }
+}
+%}
+
+%types(YACSEvalInputPort,YACSEvalOutputPort);
+/*%types(YACS::ENGINE::Node *,YACS::ENGINE::Proc *);
+%types(YACS::ENGINE::InputPort *,YACS::ENGINE::OutputPort *,YACS::ENGINE::InputDataStreamPort *,YACS::ENGINE::OutputDataStreamPort *);
+%types(YACS::ENGINE::InGate *,YACS::ENGINE::OutGate *,YACS::ENGINE::InPort *,YACS::ENGINE::OutPort *,YACS::ENGINE::Port *);
+%types(YACS::ENGINE::Container *, YACS::ENGINE::HomogeneousPoolContainer *);*/
+
+%import "loader.i"
+
+%newobject YACSEvalYFX::BuildFromFile;
+%newobject YACSEvalYFX::BuildFromScheme;
+
+%typemap(out) std::list<YACSEvalInputPort *>
+{
+  std::list<YACSEvalInputPort *>::const_iterator it;
+  $result = PyList_New($1.size());
+  int i = 0;
+  for (it = $1.begin(); it != $1.end(); ++it, ++i)
+    {
+      PyList_SetItem($result,i,SWIG_NewPointerObj(SWIG_as_voidptr(*it),SWIGTYPE_p_YACSEvalInputPort, 0 | 0 ));
+    }
+}
+
+%typemap(out) std::list<YACSEvalOutputPort *>
+{
+  std::list<YACSEvalOutputPort *>::const_iterator it;
+  $result = PyList_New($1.size());
+  int i = 0;
+  for (it = $1.begin(); it != $1.end(); ++it, ++i)
+    {
+      PyList_SetItem($result,i,SWIG_NewPointerObj(SWIG_as_voidptr(*it),SWIGTYPE_p_YACSEvalOutputPort, 0 | 0 ));
+    }
+}
+
+%typemap(out) YACSEvalAny *
+{
+  $result = 0;
+  YACSEvalAnyDouble *val0(dynamic_cast<YACSEvalAnyDouble *>($1));
+  YACSEvalAnyInt *val1(dynamic_cast<YACSEvalAnyInt *>($1));
+  if(val0)
+    {
+      $result = PyFloat_FromDouble(val0->toDouble());
+      delete $1;
+    }
+  else if(val1)
+    {
+      $result = PyInt_FromLong(val1->toInt());
+      delete $1;
+    }
+  else
+    {
+      delete $1;
+      throw YACS::Exception("PyWrap of YACSEvalInputPort::getDefaultValueDefined : unrecognized type !");
+    }
+}
+
+%typemap(in) const std::list< YACSEvalOutputPort * >& 
+{
+  
+}
+
+class YACSEvalPort
+{
+public:
+  virtual std::string getTypeOfData() const;
+private:
+  YACSEvalPort();
+};
+
+class YACSEvalInputPort : public YACSEvalPort
+{
+public:
+  std::string getName() const;
+  bool hasDefaultValueDefined() const;
+  YACSEvalAny *getDefaultValueDefined() const;
+  %extend
+     {
+       void setDefaultValue(PyObject *parameter)
+       {
+         if(parameter==Py_None)
+           self->setDefaultValue(0);
+         else if(PyFloat_Check(parameter))
+           {
+             YACSEvalAnyDouble tmp(PyFloat_AsDouble(parameter));
+             self->setDefaultValue(&tmp);
+           }
+         else if(PyInt_Check(parameter))
+           {
+             YACSEvalAnyInt tmp((int)PyInt_AsLong(parameter));
+             self->setDefaultValue(&tmp);
+           }
+         else
+           throw YACS::Exception("PyWrap of YACSEvalInputPort::setParameter : unrecognized type !");
+       }
+       
+       void setSequenceOfValuesToEval(PyObject *vals)
+       {
+         if(!PyList_Check(vals))
+           {
+             PyErr_SetString(PyExc_TypeError,"not a list");
+             return ;
+           }
+         int size(PyList_Size(vals));
+         YACSEvalSeqAny *valsCpp(0);
+         if(size>0)
+           {
+             PyObject *elt0(PyList_GetItem(vals,0));
+             if(PyFloat_Check(elt0))
+               {
+                 std::vector<double> zeVals;
+                 convertPyToDblArr(vals,zeVals);
+                 valsCpp=new YACSEvalSeqAnyDouble(zeVals);
+               }
+             else if(PyInt_Check(elt0))
+               {
+                 std::vector<int> zeVals;
+                 convertPyToIntArr(vals,zeVals);
+                 valsCpp=new YACSEvalSeqAnyInt(zeVals);
+               }
+             else
+               throw YACS::Exception("YACSEvalInputPort::setSequenceOfValuesToEval : only list[float] and list[int] actualy supported !");
+           }
+         else
+           valsCpp=YACSEvalSeqAny::BuildEmptyFromType(self->getTypeOfData());
+         self->setSequenceOfValuesToEval(valsCpp);
+         delete valsCpp;
+       }
+
+       PyObject *hasSequenceOfValuesToEval() const
+       {
+         std::size_t ret1;
+         bool ret0(self->hasSequenceOfValuesToEval(ret1));
+         PyObject *ret(PyTuple_New(2));
+         PyObject *ret0Py=ret0?Py_True:Py_False;
+         Py_XINCREF(ret0Py);
+         PyTuple_SetItem(ret,0,ret0Py);
+         PyTuple_SetItem(ret,1,PyInt_FromLong(ret1));
+         return ret;
+       }
+     }
+private:
+  YACSEvalInputPort();
+};
+
+class YACSEvalOutputPort : public YACSEvalPort
+{
+public:
+  std::string getName() const;
+private:
+  YACSEvalOutputPort();
+};
+
+class YACSEvalVirtualYACSContainer
+{
+public:
+  std::string getChosenMachine() const;
+  void setWantedMachine(const std::string& machine);
+  std::vector<std::string> listOfPropertyKeys() const;
+  std::string getValueOfKey(const char *key) const;
+  void setProperty(const std::string& key, const std::string &value);
+private:
+  YACSEvalVirtualYACSContainer();
+};
+
+class YACSEvalResource
+{
+public:
+  std::vector<std::string> getAllChosenMachines() const;
+  std::vector<std::string> getAllFittingMachines() const;
+  void setWantedMachine(const std::string& machine);
+  std::size_t size() const;
+  YACSEvalVirtualYACSContainer *at(std::size_t i) const;
+  %extend
+     {
+       std::size_t __len__() const
+       {
+         return self->size();
+       }
+       YACSEvalVirtualYACSContainer *__getitem__(std::size_t i) const
+       {
+         return self->at(i);
+       }
+     }
+private:
+  YACSEvalResource();
+};
+
+class YACSEvalListOfResources
+{
+public:
+  std::vector<std::string> getAllChosenMachines() const;
+  std::vector<std::string> getAllFittingMachines() const;
+  void setWantedMachine(const std::string& machine);
+  std::size_t size() const;
+  bool isInteractive() const;
+  YACSEvalResource *at(std::size_t i) const;
+  unsigned int getNumberOfProcsDeclared() const;
+  %extend
+     {
+       std::size_t __len__() const
+       {
+         return self->size();
+       }
+       YACSEvalResource *__getitem__(std::size_t i) const
+       {
+         return self->at(i);
+       }
+     }
+private:
+  YACSEvalListOfResources();
+};
+
+class YACSEvalSession
+{
+public:
+  YACSEvalSession();
+  ~YACSEvalSession();
+  void launch();
+  bool isLaunched() const;
+  void checkLaunched() const;
+  int getPort() const;
+  std::string getCorbaConfigFileName() const;
+};
+
+class YACSEvalYFX
+{
+public:
+  static YACSEvalYFX *BuildFromFile(const std::string& xmlOfScheme);
+  static YACSEvalYFX *BuildFromScheme(YACS::ENGINE::Proc *schema);
+  std::list<YACSEvalInputPort *> getFreeInputPorts() const;
+  std::list<YACSEvalOutputPort *> getFreeOutputPorts() const;
+  void unlockAll();
+  bool isLocked() const;
+  YACS::ENGINE::Proc *getUndergroundGeneratedGraph() const;
+  YACSEvalListOfResources *giveResources();
+  %extend
+     {
+       void lockPortsForEvaluation(PyObject *outputsOfInterest)
+       {
+         std::list<YACSEvalOutputPort *> outputsOfInterestCpp;
+         if(PyList_Check(outputsOfInterest))
+           {
+             int size(PyList_Size(outputsOfInterest));
+             for(int i=0;i<size;i++)
+               {
+                 PyObject *obj(PyList_GetItem(outputsOfInterest,i));
+                 void *argp(0);
+                 int status(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_YACSEvalOutputPort,0|0));
+                 if(!SWIG_IsOK(status))
+                   {
+                     std::ostringstream oss; oss << "Input elt #" << i << " in list is not a YACSEvalOutputPort instance !";
+                     throw YACS::Exception(oss.str());
+                   }
+                 outputsOfInterestCpp.push_back(reinterpret_cast<YACSEvalOutputPort *>(argp));
+               }
+           }
+         else
+           {
+             PyErr_SetString(PyExc_TypeError,"not a list");
+             return ;
+           }
+         self->lockPortsForEvaluation(outputsOfInterestCpp);
+       }
+
+       PyObject *getResults() const
+       {
+         std::vector<YACSEvalSeqAny *> retCpp(self->getResults());
+         std::size_t sz(retCpp.size());
+         PyObject *ret(PyList_New(sz));
+         for(std::size_t i=0;i<sz;i++)
+           {
+             YACSEvalSeqAny *elt(retCpp[i]);
+             YACSEvalSeqAnyDouble *elt1(dynamic_cast<YACSEvalSeqAnyDouble *>(elt));
+             YACSEvalSeqAnyInt *elt2(dynamic_cast<YACSEvalSeqAnyInt *>(elt));
+             if(elt1)
+               {
+                 std::vector<double> *zeArr(elt1->getInternal());
+                 std::size_t sz2(zeArr->size());
+                 PyObject *ret2(PyList_New(sz2));
+                 for(std::size_t i2=0;i2<sz2;i2++)
+                   PyList_SetItem(ret2,i2,PyFloat_FromDouble((*zeArr)[i2]));
+                 PyList_SetItem(ret,i,ret2);
+               }
+             else if(elt2)
+               {
+                 std::vector<int> *zeArr(elt2->getInternal());
+                 std::size_t sz2(zeArr->size());
+                 PyObject *ret2(PyList_New(sz2));
+                 for(std::size_t i2=0;i2<sz2;i2++)
+                   PyList_SetItem(ret2,i2,PyInt_FromLong((*zeArr)[i2]));
+                 PyList_SetItem(ret,i,ret2);
+               }
+             else
+               throw YACS::Exception("wrap of YACSEvalYFX.getResults : unrecognized type !");
+             delete elt;
+           }
+         return ret;
+       }
+
+       PyObject *run(YACSEvalSession *session)
+       {
+         int ret1;
+         bool ret0(self->run(session,ret1));
+         PyObject *ret(PyTuple_New(2));
+         PyObject *ret0Py(ret0?Py_True:Py_False);
+         Py_XINCREF(ret0Py);
+         PyTuple_SetItem(ret,0,ret0Py);
+         PyTuple_SetItem(ret,1,PyInt_FromLong(ret1));
+         return ret;
+       }
+     }
+private:
+  YACSEvalYFX();
+};
diff --git a/src/evalyfx_swig/test.py b/src/evalyfx_swig/test.py
new file mode 100644 (file)
index 0000000..fc42faa
--- /dev/null
@@ -0,0 +1,97 @@
+def buildScheme(fname):
+    import SALOMERuntime
+    import loader
+    SALOMERuntime.RuntimeSALOME.setRuntime()
+    r=SALOMERuntime.getSALOMERuntime()
+    p=r.createProc("run")
+    td=p.createType("double","double")
+    #
+    cont=p.createContainer("zeCont","Salome")
+    #
+    n0=r.createFuncNode("Salome","node0")
+    p.edAddChild(n0)
+    n0.setFname("func0")
+    n0.setContainer(cont)
+    n0.setScript("""def func0(a,b):
+  return a*b
+""")
+    n0.setExecutionMode("remote")
+    a=n0.edAddInputPort("a",td)
+    b=n0.edAddInputPort("b",td)  ; b.edInitPy(1.3)
+    c=n0.edAddOutputPort("c",td)
+    #
+    n1=r.createFuncNode("Salome","node1")
+    p.edAddChild(n1)
+    n1.setFname("func1")
+    n1.setContainer(cont)
+    n1.setScript("""def func1(a,b):
+  return a+b,3*(a+b)
+""")
+    n1.setExecutionMode("remote")
+    d=n1.edAddInputPort("d",td)
+    e=n1.edAddInputPort("e",td)  ; e.edInitPy(2.5) # agy : useless but for test
+    f=n1.edAddOutputPort("f",td)
+    g=n1.edAddOutputPort("g",td)
+    #
+    p.edAddCFLink(n0,n1)
+    p.edAddLink(c,d)
+    #
+    p.saveSchema(fname)
+
+fileName="test0.xml"
+import evalyfx
+session=evalyfx.YACSEvalSession()
+session.launch()
+buildScheme(fileName)
+efx=evalyfx.YACSEvalYFX.BuildFromFile(fileName)
+inps=efx.getFreeInputPorts()
+#
+inps[0].setDefaultValue(3.4)
+#
+inps[0].setDefaultValue(None)
+inps[2].setDefaultValue(2.7)
+inps[2].setDefaultValue(None)
+#
+outps=efx.getFreeOutputPorts()
+# prepare for execution
+inps[0].setDefaultValue(1.1)
+inps[1].setSequenceOfValuesToEval([10.1,10.2,10.3])
+a,b=inps[2].hasSequenceOfValuesToEval()
+inps[2].setSequenceOfValuesToEval([20.1,20.2,30.3,40.4])
+a,b=inps[2].hasSequenceOfValuesToEval()
+inps[2].setSequenceOfValuesToEval([20.1,20.2,30.3])
+efx.lockPortsForEvaluation([outps[0],outps[2]])
+#
+g=efx.getUndergroundGeneratedGraph()
+g.saveSchema("toto.xml")
+rss=efx.giveResources()
+rss[0][0].setWantedMachine("localhost")
+a,b=efx.run(session)
+assert(a)
+assert(b==4)
+assert(efx.getResults()==[[11.110000000000001, 11.22, 11.330000000000002], [93.63, 94.26, 124.89000000000001]])
+#import loader
+#import pilot
+#l=loader.YACSLoader()
+#p=l.load("/home/H87074/aaaaaaa.xml")
+#ex=pilot.ExecutorSwig()
+#ex.RunW(efx.getUndergroundGeneratedGraph())
+#
+"""
+import pilot
+import SALOMERuntime
+import loader
+import os,sys
+zePath=os.path.join(os.environ["KERNEL_ROOT_DIR"],"bin","salome","appliskel")
+sys.path.append(zePath)
+import salome_test_session
+port=salome_test_session.startSession(shutdownAtExit=False)
+omniorb_cfg=os.environ["OMNIORB_CONFIG"]
+SALOMERuntime.RuntimeSALOME.setRuntime()
+r=SALOMERuntime.getSALOMERuntime()
+l=loader.YACSLoader()
+p=l.load("/home/H87074/aaaaaaa.xml")
+ex=pilot.ExecutorSwig()
+ex.RunW(p)
+salome_test_session.terminateSession(port)
+"""
diff --git a/src/evalyfx_swig/test0.xml b/src/evalyfx_swig/test0.xml
new file mode 100644 (file)
index 0000000..e23ae1c
--- /dev/null
@@ -0,0 +1,54 @@
+<?xml version='1.0' encoding='iso-8859-1' ?>
+<proc name="run">
+   <type name="bool" kind="bool"/>
+   <type name="double" kind="double"/>
+   <objref name="file" id="file"/>
+   <type name="int" kind="int"/>
+   <type name="string" kind="string"/>
+   <container name="DefaultContainer">
+      <property name="container_kind" value="Salome"/>
+      <property name="attached_on_cloning" value="0"/>
+      <property name="container_name" value="FactoryServer"/>
+      <property name="name" value="localhost"/>
+   </container>
+   <container name="zeCont">
+      <property name="container_kind" value="Salome"/>
+      <property name="attached_on_cloning" value="0"/>
+   </container>
+   <remote name="node0">
+      <function name="func0">
+         <code><![CDATA[def func0(a,b):
+  return a*b
+]]></code>
+      </function>
+      <load container="zeCont"/>
+      <inport name="a" type="double"/>
+      <inport name="b" type="double"/>
+      <outport name="c" type="double"/>
+   </remote>
+   <remote name="node1">
+      <function name="func1">
+         <code><![CDATA[def func1(a,b):
+  return a+b,3*(a+b)
+]]></code>
+      </function>
+      <load container="zeCont"/>
+      <inport name="d" type="double"/>
+      <inport name="e" type="double"/>
+      <outport name="f" type="double"/>
+      <outport name="g" type="double"/>
+   </remote>
+   <control> <fromnode>node0</fromnode> <tonode>node1</tonode> </control>
+   <datalink control="false">
+      <fromnode>node0</fromnode> <fromport>c</fromport>
+      <tonode>node1</tonode> <toport>d</toport>
+   </datalink>
+   <parameter>
+      <tonode>node0</tonode><toport>b</toport>
+      <value><double>1.3</double></value>
+   </parameter>
+   <parameter>
+      <tonode>node1</tonode><toport>e</toport>
+      <value><double>2.5</double></value>
+   </parameter>
+</proc>
diff --git a/src/evalyfx_swig/testEvalYFX.py b/src/evalyfx_swig/testEvalYFX.py
new file mode 100644 (file)
index 0000000..119065f
--- /dev/null
@@ -0,0 +1,94 @@
+import unittest
+
+class TestEvalYFX(unittest.TestCase):
+    def test0(self):
+        fileName="test0.xml"
+        self.__buildScheme(fileName)
+        import evalyfx
+        efx=evalyfx.YACSEvalYFX.BuildFromFile(fileName)
+        inps=efx.getFreeInputPorts()
+        self.assertEqual([elt.getName() for elt in inps],['a','b','e'])
+        self.assertEqual([elt.hasDefaultValueDefined() for elt in inps],[False,True,True])
+        self.assertAlmostEqual(inps[1].getDefaultValueDefined(),1.3,12)
+        self.assertAlmostEqual(inps[2].getDefaultValueDefined(),2.5,12)
+        #
+        inps[0].setDefaultValue(3.4)
+        self.assertEqual([elt.hasDefaultValueDefined() for elt in inps],[True,True,True])
+        self.assertAlmostEqual(inps[0].getDefaultValueDefined(),3.4,12)
+        #
+        inps[0].setDefaultValue(None)
+        self.assertEqual([elt.hasDefaultValueDefined() for elt in inps],[False,True,True])
+        inps[2].setDefaultValue(2.7)
+        self.assertAlmostEqual(inps[2].getDefaultValueDefined(),2.7,12)
+        inps[2].setDefaultValue(None)
+        self.assertEqual([elt.hasDefaultValueDefined() for elt in inps],[False,True,False])
+        self.assertRaises(ValueError,inps[0].getDefaultValueDefined)
+        self.assertAlmostEqual(inps[1].getDefaultValueDefined(),1.3,12)
+        self.assertRaises(ValueError,inps[2].getDefaultValueDefined)
+        #
+        outps=efx.getFreeOutputPorts()
+        self.assertEqual([elt.getName() for elt in outps],['c','f','g'])
+        # prepare for execution
+        inps[0].setDefaultValue(1.1)
+        inps[1].setSequenceOfValuesToEval([10.1,10.2,10.3])
+        self.assertRaises(ValueError,efx.lockPortsForEvaluation,[outps[0],outps[2]]) # because e is not set
+        a,b=inps[2].hasSequenceOfValuesToEval()
+        self.assertTrue(not a)
+        inps[2].setSequenceOfValuesToEval([20.1,20.2,30.3,40.4])
+        a,b=inps[2].hasSequenceOfValuesToEval()
+        self.assertTrue(a)
+        self.assertEqual(b,4)
+        self.assertRaises(ValueError,efx.lockPortsForEvaluation,[outps[0],outps[2]]) # because size of vals of e is not equal to size of vals of a
+        inps[2].setSequenceOfValuesToEval([20.1,20.2,30.3])
+        efx.lockPortsForEvaluation([outps[0],outps[2]])
+        #
+        g=efx.getUndergroundGeneratedGraph()
+        g.saveSchema("toto.xml")
+        #
+        
+        pass
+
+    def __buildScheme(self,fname):
+        import SALOMERuntime
+        import loader
+        SALOMERuntime.RuntimeSALOME.setRuntime()
+        r=SALOMERuntime.getSALOMERuntime()
+        p=r.createProc("run")
+        td=p.createType("double","double")
+        #
+        cont=p.createContainer("zeCont","Salome")
+        #
+        n0=r.createFuncNode("Salome","node0")
+        p.edAddChild(n0)
+        n0.setFname("func0")
+        n0.setContainer(cont)
+        n0.setScript("""def func0(a,b):
+  return a*b
+""")
+        n0.setExecutionMode("remote")
+        a=n0.edAddInputPort("a",td)
+        b=n0.edAddInputPort("b",td)  ; b.edInitPy(1.3)
+        c=n0.edAddOutputPort("c",td)
+        #
+        n1=r.createFuncNode("Salome","node1")
+        p.edAddChild(n1)
+        n1.setFname("func1")
+        n1.setContainer(cont)
+        n1.setScript("""def func1(a,b):
+  return a+b,3*(a+b)
+""")
+        n1.setExecutionMode("remote")
+        d=n1.edAddInputPort("d",td)
+        e=n1.edAddInputPort("e",td)  ; e.edInitPy(2.5) # agy : useless but for test
+        f=n1.edAddOutputPort("f",td)
+        g=n1.edAddOutputPort("g",td)
+        #
+        p.edAddCFLink(n0,n1)
+        p.edAddLink(c,d)
+        #
+        p.saveSchema(fname)
+        pass
+    pass
+
+if __name__ == '__main__':
+    unittest.main()
index de5479026f45146d687623819af61e1f4e6cc1d9..162ec0a0b2db0165098619241e17c78f7bb97f53 100644 (file)
@@ -27,6 +27,8 @@
 #include "OutputPort.hxx"
 #include "Mutex.hxx"
 
+#include <Python.h>
+
 #include <string>
 
 namespace YACS