Salome HOME
Work in progress save and load state.
[modules/yacs.git] / src / engine / ForEachLoop.hxx
index 13f52f2bd7c86d7cf398fac746a6406bafaaf586..875b900fa8a2e2a59818f749f5e820da65eab98b 100644 (file)
@@ -1,11 +1,30 @@
+// Copyright (C) 2006-2015  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
 #ifndef __FOREACHLOOP_HXX__
 #define __FOREACHLOOP_HXX__
 
+#include "YACSlibEngineExport.hxx"
 #include "ElementaryNode.hxx"
 #include "DynParaLoop.hxx"
 #include "OutputPort.hxx"
 #include "InputPort.hxx"
-#include "TypeCode.hxx"
 #include "AnyInputPort.hxx"
 
 namespace YACS
@@ -15,6 +34,8 @@ namespace YACS
     class ForEachLoop;
     class SplitterNode;
     class AnySplitOutputPort;
+    class TypeCode;
+    class TypeCodeSeq;
 
     class InterceptorInputPort : public AnyInputPort
     {
@@ -51,7 +72,7 @@ namespace YACS
       OutputPort *clone(Node *newHelder) const;
     };
 
-    class SeqAnyInputPort : public AnyInputPort
+    class YACSLIBENGINE_EXPORT SeqAnyInputPort : public AnyInputPort
     {
       friend class ForEachLoop;
       friend class SplitterNode;
@@ -102,7 +123,34 @@ namespace YACS
       static const char NAME[];
     };
 
-    class ForEachLoop : public DynParaLoop
+    class YACSLIBENGINE_EXPORT ForEachLoopPassedData
+    {
+    public:
+      ForEachLoopPassedData(const std::vector<unsigned int>& passedIds, const std::vector<SequenceAny *>& passedOutputs, const std::vector<std::string>& nameOfOutputs);
+      ForEachLoopPassedData(const ForEachLoopPassedData& copy);
+      ~ForEachLoopPassedData();
+      void init();
+      void checkCompatibilyWithNb(int nbOfElts) const;
+      void checkLevel2(const std::vector<AnyInputPort *>& ports) const;
+      int getNumberOfEltsAlreadyDone() const { return (int)_passedIds.size(); }
+      int toAbsId(int localId) const;
+      int toAbsIdNot(int localId) const;
+      int getNumberOfElementsToDo() const;
+      void assignAlreadyDone(const std::vector<SequenceAny *>& execVals) const;
+      const std::vector<unsigned int>& getIds()const {return _passedIds;}
+      const std::vector<SequenceAny *>& getOutputs()const {return _passedOutputs;}
+      const std::vector<std::string>& getOutputNames()const {return _nameOfOutputs;}
+      //const std::vector<bool>& getFlags()const {return _flagsIds;}
+    private:
+      std::vector<unsigned int> _passedIds;
+      std::vector<SequenceAny *> _passedOutputs;
+      std::vector<std::string> _nameOfOutputs;
+      mutable std::vector<bool> _flagsIds;
+    };
+
+    class Executor;
+
+    class YACSLIBENGINE_EXPORT ForEachLoop : public DynParaLoop
     {
       friend class SplitterNode;
       friend class FakeNodeForForEachLoop;
@@ -112,6 +160,7 @@ namespace YACS
     protected:
       static const int NOT_RUNNING_BRANCH_ID;
     protected:
+      int _currentIndex;
       SplitterNode _splitterNode;
       FakeNodeForForEachLoop *_nodeForSpecialCases;
       std::vector<AnySplitOutputPort *> _outGoingPorts;//! ports linked to node outside the current scope
@@ -120,21 +169,23 @@ namespace YACS
       unsigned _execCurrentId;
       std::vector<SequenceAny *> _execVals;
       std::vector< std::vector<AnyInputPort *> > _execOutGoingPorts;
+      ForEachLoopPassedData *_passedData;
     public:
       ForEachLoop(const std::string& name, TypeCode *typeOfDataSplitted);
       ForEachLoop(const ForEachLoop& other, ComposedNode *father, bool editionOnly);
       ~ForEachLoop();
       void init(bool start=true);
       void exUpdateState();
+      void exUpdateProgress();
       void getReadyTasks(std::vector<Task *>& tasks);
       int getNumberOfInputPorts() const;
       //
-      void checkConsistency(ComposedNode *pointOfView) const throw(Exception);
       void checkNoCyclePassingThrough(Node *node) throw(Exception);
       void selectRunnableTasks(std::vector<Task *>& tasks);
       //
       unsigned getExecCurrentId() const { return _execCurrentId; } // for update progress bar on GUI part
       std::list<InputPort *> getSetOfInputPort() const;
+      std::list<InputPort *> getLocalInputPorts() const;
       InputPort *edGetSeqOfSamplesPort() { return &_splitterNode._dataPortToDispatch; }
       InputPort *getInputPort(const std::string& name) const throw(Exception);
       OutPort *getOutPort(const std::string& name) const throw(Exception);
@@ -142,15 +193,31 @@ namespace YACS
       Node *getChildByShortName(const std::string& name) const throw(Exception);
       std::list<OutputPort *> getLocalOutputPorts() const;
       void accept(Visitor *visitor);
-      void writeDot(std::ostream &os);
+      void writeDot(std::ostream &os) const;
+      virtual std::string typeName() {return "YACS__ENGINE__ForEachLoop";}
+      virtual void resetState(int level);
+      std::string getProgress() const;
+      std::list<ProgressWeight> getProgressWeight() const;
+      int getCurrentIndex() const { return _currentIndex; }
+      int getNbOfElementsToBeProcessed() const;
+#ifndef SWIG
+      ForEachLoopPassedData* getProcessedData()const;
+      void setProcessedData(ForEachLoopPassedData* processedData);
+      std::vector<unsigned int> getPassedResults(Executor *execut, std::vector<SequenceAny *>& outputs, std::vector<std::string>& nameOfOutputs) const;
+      void assignPassedResults(const std::vector<unsigned int>& passedIds, const std::vector<SequenceAny *>& passedOutputs, const std::vector<std::string>& nameOfOutputs);
+#endif
     protected:
       Node *simpleClone(ComposedNode *father, bool editionOnly=true) const;
-      void checkLinkPossibility(OutPort *start, const std::set<ComposedNode *>& pointsOfViewStart,
-                                InPort *end, const std::set<ComposedNode *>& pointsOfViewEnd) throw(Exception);
+      void checkLinkPossibility(OutPort *start, const std::list<ComposedNode *>& pointsOfViewStart,
+                                InPort *end, const std::list<ComposedNode *>& pointsOfViewEnd) throw(Exception);
       YACS::Event updateStateOnFinishedEventFrom(Node *node);
-      void buildDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::set<ComposedNode *>& pointsOfView);
-      void getDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::set<ComposedNode *>& pointsOfView) throw(Exception);
-      void releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::set<ComposedNode *>& pointsOfView) throw(Exception);
+      YACS::Event updateStateForInitNodeOnFinishedEventFrom(Node *node, unsigned int id);
+      YACS::Event updateStateForWorkNodeOnFinishedEventFrom(Node *node, unsigned int id, bool isNormalFinish);
+      YACS::Event updateStateForFinalizeNodeOnFinishedEventFrom(Node *node, unsigned int id);
+      YACS::Event updateStateOnFailedEventFrom(Node *node);
+      void buildDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView);
+      void getDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView) throw(Exception);
+      void releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView) throw(Exception);
     protected:
       void cleanDynGraph();
       void pushAllSequenceValues();
@@ -158,6 +225,11 @@ namespace YACS
       void prepareSequenceValues(int sizeOfSamples);
       OutPort *getDynOutPortByAbsName(int branchNb, const std::string& name);
       void storeOutValsInSeqForOutOfScopeUse(int rank, int branchNb);
+    private:
+      int getFinishedId();
+    public:
+      static void InterceptorizeNameOfPort(std::string& portName);
+      static const char INTERCEPTOR_STR[];
     };
   }
 }