1 // Copyright (C) 2006-2016 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #ifndef __FOREACHLOOP_HXX__
21 #define __FOREACHLOOP_HXX__
23 #include "YACSlibEngineExport.hxx"
24 #include "ElementaryNode.hxx"
25 #include "DynParaLoop.hxx"
26 #include "OutputPort.hxx"
27 #include "InputPort.hxx"
28 #include "AnyInputPort.hxx"
36 class AnySplitOutputPort;
40 class InterceptorInputPort : public AnyInputPort
42 friend class ForEachLoop;
43 friend class SplitterNode;
45 AnySplitOutputPort *_repr;
47 InterceptorInputPort(const std::string& name, Node *node, TypeCode* type);
48 InterceptorInputPort(const InterceptorInputPort& other, Node *newHelder);
49 void getAllRepresentants(std::set<InPort *>& repr) const;
50 InputPort *clone(Node *newHelder) const;
51 void setRepr(AnySplitOutputPort *repr);
54 class AnySplitOutputPort : public OutputPort
56 friend class ForEachLoop;
57 friend class SplitterNode;
60 InterceptorInputPort *_intercptr;
61 mutable unsigned int _cnt;
65 AnySplitOutputPort(const std::string& name, Node *node, TypeCode *type);
66 AnySplitOutputPort(const AnySplitOutputPort& other, Node *newHelder);
67 bool addInPort(InPort *inPort) throw(Exception);
68 void getAllRepresented(std::set<OutPort *>& represented) const;
69 int removeInPort(InPort *inPort, bool forward) throw(Exception);
70 void addRepr(OutPort *repr, InterceptorInputPort *intercptr);
71 OutPort *getRepr() const { return _repr; }
72 OutputPort *clone(Node *newHelder) const;
75 class YACSLIBENGINE_EXPORT SeqAnyInputPort : public AnyInputPort
77 friend class ForEachLoop;
78 friend class SplitterNode;
80 unsigned getNumberOfElements() const;
81 virtual std::string dump();
83 SeqAnyInputPort(const std::string& name, Node *node, TypeCodeSeq* type);
84 SeqAnyInputPort(const SeqAnyInputPort& other, Node *newHelder);
85 InputPort *clone(Node *newHelder) const;
86 Any *getValueAtRank(int i) const;
89 class SplitterNode : public ElementaryNode
91 friend class ForEachLoop;
93 static const char NAME_OF_SEQUENCE_INPUT[];
95 SplitterNode(const std::string& name, TypeCode *typeOfData, ForEachLoop *father);
96 SplitterNode(const SplitterNode& other, ForEachLoop *father);
97 InputPort *getInputPort(const std::string& name) const throw(Exception);
98 Node *simpleClone(ComposedNode *father, bool editionOnly) const;
99 unsigned getNumberOfElements() const;
101 void init(bool start=true);
102 void putSplittedValueOnRankTo(int rankInSeq, int branch, bool first);
104 SeqAnyInputPort _dataPortToDispatch;
107 class FakeNodeForForEachLoop : public ElementaryNode
109 friend class ForEachLoop;
114 FakeNodeForForEachLoop(ForEachLoop *loop, bool normalFinish);
115 FakeNodeForForEachLoop(const FakeNodeForForEachLoop& other);
116 Node *simpleClone(ComposedNode *father, bool editionOnly) const;
117 void exForwardFailed();
118 void exForwardFinished();
123 static const char NAME[];
126 class YACSLIBENGINE_EXPORT ForEachLoopPassedData
129 ForEachLoopPassedData(const std::vector<unsigned int>& passedIds, const std::vector<SequenceAny *>& passedOutputs, const std::vector<std::string>& nameOfOutputs);
130 ForEachLoopPassedData(const ForEachLoopPassedData& copy);
131 ~ForEachLoopPassedData();
133 void checkCompatibilyWithNb(int nbOfElts) const;
134 void checkLevel2(const std::vector<AnyInputPort *>& ports) const;
135 int getNumberOfEltsAlreadyDone() const { return (int)_passedIds.size(); }
136 int toAbsId(int localId) const;
137 int toAbsIdNot(int localId) const;
138 int getNumberOfElementsToDo() const;
139 void assignAlreadyDone(const std::vector<SequenceAny *>& execVals) const;
140 const std::vector<unsigned int>& getIds()const {return _passedIds;}
141 const std::vector<SequenceAny *>& getOutputs()const {return _passedOutputs;}
142 const std::vector<std::string>& getOutputNames()const {return _nameOfOutputs;}
143 //const std::vector<bool>& getFlags()const {return _flagsIds;}
145 std::vector<unsigned int> _passedIds;
146 std::vector<SequenceAny *> _passedOutputs;
147 std::vector<std::string> _nameOfOutputs;
148 mutable std::vector<bool> _flagsIds;
153 class YACSLIBENGINE_EXPORT ForEachLoop : public DynParaLoop
155 friend class SplitterNode;
156 friend class FakeNodeForForEachLoop;
159 static const char NAME_OF_SPLITTERNODE[];
161 static const int NOT_RUNNING_BRANCH_ID;
164 SplitterNode _splitterNode;
165 FakeNodeForForEachLoop *_nodeForSpecialCases;
166 std::vector<AnySplitOutputPort *> _outGoingPorts;//! ports linked to node outside the current scope
167 std::vector<InterceptorInputPort *> _intecptrsForOutGoingPorts;//!ports created for TypeCodes correctness
168 //part of attributes defining graph dynamically built on control notification
169 unsigned _execCurrentId;
170 std::vector<SequenceAny *> _execVals;
171 std::vector< std::vector<AnyInputPort *> > _execOutGoingPorts;
172 ForEachLoopPassedData *_passedData;
174 ForEachLoop(const std::string& name, TypeCode *typeOfDataSplitted);
175 ForEachLoop(const ForEachLoop& other, ComposedNode *father, bool editionOnly);
177 void init(bool start=true);
178 void exUpdateState();
179 void exUpdateProgress();
180 void getReadyTasks(std::vector<Task *>& tasks);
181 int getNumberOfInputPorts() const;
183 void checkNoCyclePassingThrough(Node *node) throw(Exception);
184 void selectRunnableTasks(std::vector<Task *>& tasks);
186 unsigned getExecCurrentId() const { return _execCurrentId; } // for update progress bar on GUI part
187 std::list<InputPort *> getSetOfInputPort() const;
188 std::list<InputPort *> getLocalInputPorts() const;
189 InputPort *edGetSeqOfSamplesPort() { return &_splitterNode._dataPortToDispatch; }
190 InputPort *getInputPort(const std::string& name) const throw(Exception);
191 OutPort *getOutPort(const std::string& name) const throw(Exception);
192 OutputPort *getOutputPort(const std::string& name) const throw(Exception);
193 Node *getChildByShortName(const std::string& name) const throw(Exception);
194 std::list<OutputPort *> getLocalOutputPorts() const;
195 void accept(Visitor *visitor);
196 void writeDot(std::ostream &os) const;
197 virtual std::string typeName() {return "YACS__ENGINE__ForEachLoop";}
198 virtual void resetState(int level);
199 std::string getProgress() const;
200 std::list<ProgressWeight> getProgressWeight() const;
201 int getCurrentIndex() const { return _currentIndex; }
202 int getNbOfElementsToBeProcessed() const;
203 static int getFEDeltaBetween(OutPort *start, InPort *end);
205 ForEachLoopPassedData* getProcessedData()const;
206 void setProcessedData(ForEachLoopPassedData* processedData);
207 std::vector<unsigned int> getPassedResults(Executor *execut, std::vector<SequenceAny *>& outputs, std::vector<std::string>& nameOfOutputs) const;
208 void assignPassedResults(const std::vector<unsigned int>& passedIds, const std::vector<SequenceAny *>& passedOutputs, const std::vector<std::string>& nameOfOutputs);
210 const TypeCode* getOutputPortType(const std::string& portName)const;
212 Node *simpleClone(ComposedNode *father, bool editionOnly=true) const;
213 void checkLinkPossibility(OutPort *start, const std::list<ComposedNode *>& pointsOfViewStart,
214 InPort *end, const std::list<ComposedNode *>& pointsOfViewEnd) throw(Exception);
215 YACS::Event updateStateOnFinishedEventFrom(Node *node);
216 YACS::Event updateStateForInitNodeOnFinishedEventFrom(Node *node, unsigned int id);
217 YACS::Event updateStateForWorkNodeOnFinishedEventFrom(Node *node, unsigned int id, bool isNormalFinish);
218 YACS::Event updateStateForFinalizeNodeOnFinishedEventFrom(Node *node, unsigned int id);
219 YACS::Event updateStateOnFailedEventFrom(Node *node, const Executor *execInst);
220 void buildDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView);
221 void getDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView) throw(Exception);
222 void releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView) throw(Exception);
224 void cleanDynGraph();
225 void pushAllSequenceValues();
226 void createOutputOutOfScopeInterceptors(int branchNb);
227 void prepareSequenceValues(int sizeOfSamples);
228 OutPort *getDynOutPortByAbsName(int branchNb, const std::string& name);
229 void storeOutValsInSeqForOutOfScopeUse(int rank, int branchNb);
233 static void InterceptorizeNameOfPort(std::string& portName);
234 static const char INTERCEPTOR_STR[];