Salome HOME
Issue EDF13268 - link from list[pyobj] inside ForEachLoop to list[pyobj] outside...
[modules/yacs.git] / src / engine / ForEachLoop.hxx
1 // Copyright (C) 2006-2016  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #ifndef __FOREACHLOOP_HXX__
21 #define __FOREACHLOOP_HXX__
22
23 #include "YACSlibEngineExport.hxx"
24 #include "ElementaryNode.hxx"
25 #include "DynParaLoop.hxx"
26 #include "OutputPort.hxx"
27 #include "InputPort.hxx"
28 #include "AnyInputPort.hxx"
29
30 namespace YACS
31 {
32   namespace ENGINE
33   {
34     class ForEachLoop;
35     class SplitterNode;
36     class AnySplitOutputPort;
37     class TypeCode;
38     class TypeCodeSeq;
39
40     class InterceptorInputPort : public AnyInputPort
41     {
42       friend class ForEachLoop;
43       friend class SplitterNode;
44     private:
45       AnySplitOutputPort *_repr;
46     private:
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);
52     };
53
54     class AnySplitOutputPort : public OutputPort
55     {
56       friend class ForEachLoop;
57       friend class SplitterNode;
58     private:
59       OutPort *_repr;
60       InterceptorInputPort *_intercptr;
61       mutable unsigned int _cnt;
62     private:
63       bool decrRef();
64       void incrRef() const;
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;
73     };
74
75     class YACSLIBENGINE_EXPORT SeqAnyInputPort : public AnyInputPort
76     {
77       friend class ForEachLoop;
78       friend class SplitterNode;
79     public:
80       unsigned getNumberOfElements() const;
81       virtual std::string dump();
82     private:
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;
87     };
88
89     class SplitterNode : public ElementaryNode
90     {
91       friend class ForEachLoop;
92     private:
93       static const char NAME_OF_SEQUENCE_INPUT[];
94     private:
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;
100       void execute();
101       void init(bool start=true);
102       void putSplittedValueOnRankTo(int rankInSeq, int branch, bool first);
103     private:
104       SeqAnyInputPort _dataPortToDispatch;
105     };
106
107     class FakeNodeForForEachLoop : public ElementaryNode
108     {
109       friend class ForEachLoop;
110     private:
111       ForEachLoop *_loop;
112       bool _normalFinish;
113     private:
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();
119       void execute();
120       void aborted();
121       void finished();
122     private:
123       static const char NAME[];
124     };
125
126     class YACSLIBENGINE_EXPORT ForEachLoopPassedData
127     {
128     public:
129       ForEachLoopPassedData(const std::vector<unsigned int>& passedIds, const std::vector<SequenceAny *>& passedOutputs, const std::vector<std::string>& nameOfOutputs);
130       ~ForEachLoopPassedData();
131       void init();
132       void checkCompatibilyWithNb(int nbOfElts) const;
133       void checkLevel2(const std::vector<AnyInputPort *>& ports) const;
134       int getNumberOfEltsAlreadyDone() const { return (int)_passedIds.size(); }
135       int toAbsId(int localId) const;
136       int toAbsIdNot(int localId) const;
137       int getNumberOfElementsToDo() const;
138       void assignAlreadyDone(const std::vector<SequenceAny *>& execVals) const;
139     private:
140       std::vector<unsigned int> _passedIds;
141       std::vector<SequenceAny *> _passedOutputs;
142       std::vector<std::string> _nameOfOutputs;
143       mutable std::vector<bool> _flagsIds;
144     };
145
146     class Executor;
147
148     class YACSLIBENGINE_EXPORT ForEachLoop : public DynParaLoop
149     {
150       friend class SplitterNode;
151       friend class FakeNodeForForEachLoop;
152
153     public:
154       static const char NAME_OF_SPLITTERNODE[];
155     protected:
156       static const int NOT_RUNNING_BRANCH_ID;
157     protected:
158       int _currentIndex;
159       SplitterNode _splitterNode;
160       FakeNodeForForEachLoop *_nodeForSpecialCases;
161       std::vector<AnySplitOutputPort *> _outGoingPorts;//! ports linked to node outside the current scope
162       std::vector<InterceptorInputPort *> _intecptrsForOutGoingPorts;//!ports created for TypeCodes correctness
163       //part of attributes defining graph dynamically built on control notification
164       unsigned _execCurrentId;
165       std::vector<SequenceAny *> _execVals;
166       std::vector< std::vector<AnyInputPort *> > _execOutGoingPorts;
167       ForEachLoopPassedData *_passedData;
168     public:
169       ForEachLoop(const std::string& name, TypeCode *typeOfDataSplitted);
170       ForEachLoop(const ForEachLoop& other, ComposedNode *father, bool editionOnly);
171       ~ForEachLoop();
172       void init(bool start=true);
173       void exUpdateState();
174       void exUpdateProgress();
175       void getReadyTasks(std::vector<Task *>& tasks);
176       int getNumberOfInputPorts() const;
177       //
178       void checkNoCyclePassingThrough(Node *node) throw(Exception);
179       void selectRunnableTasks(std::vector<Task *>& tasks);
180       //
181       unsigned getExecCurrentId() const { return _execCurrentId; } // for update progress bar on GUI part
182       std::list<InputPort *> getSetOfInputPort() const;
183       std::list<InputPort *> getLocalInputPorts() const;
184       InputPort *edGetSeqOfSamplesPort() { return &_splitterNode._dataPortToDispatch; }
185       InputPort *getInputPort(const std::string& name) const throw(Exception);
186       OutPort *getOutPort(const std::string& name) const throw(Exception);
187       OutputPort *getOutputPort(const std::string& name) const throw(Exception);
188       Node *getChildByShortName(const std::string& name) const throw(Exception);
189       std::list<OutputPort *> getLocalOutputPorts() const;
190       void accept(Visitor *visitor);
191       void writeDot(std::ostream &os) const;
192       virtual std::string typeName() {return "YACS__ENGINE__ForEachLoop";}
193       virtual void resetState(int level);
194       std::string getProgress() const;
195       std::list<ProgressWeight> getProgressWeight() const;
196       int getCurrentIndex() const { return _currentIndex; }
197       int getNbOfElementsToBeProcessed() const;
198       static int getFEDeltaBetween(OutPort *start, InPort *end);
199 #ifndef SWIG
200       std::vector<unsigned int> getPassedResults(Executor *execut, std::vector<SequenceAny *>& outputs, std::vector<std::string>& nameOfOutputs) const;
201       void assignPassedResults(const std::vector<unsigned int>& passedIds, const std::vector<SequenceAny *>& passedOutputs, const std::vector<std::string>& nameOfOutputs);
202 #endif
203     protected:
204       Node *simpleClone(ComposedNode *father, bool editionOnly=true) const;
205       void checkLinkPossibility(OutPort *start, const std::list<ComposedNode *>& pointsOfViewStart,
206                                 InPort *end, const std::list<ComposedNode *>& pointsOfViewEnd) throw(Exception);
207       YACS::Event updateStateOnFinishedEventFrom(Node *node);
208       YACS::Event updateStateForInitNodeOnFinishedEventFrom(Node *node, unsigned int id);
209       YACS::Event updateStateForWorkNodeOnFinishedEventFrom(Node *node, unsigned int id, bool isNormalFinish);
210       YACS::Event updateStateForFinalizeNodeOnFinishedEventFrom(Node *node, unsigned int id);
211       YACS::Event updateStateOnFailedEventFrom(Node *node, const Executor *execInst);
212       void buildDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView);
213       void getDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView) throw(Exception);
214       void releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView) throw(Exception);
215     protected:
216       void cleanDynGraph();
217       void pushAllSequenceValues();
218       void createOutputOutOfScopeInterceptors(int branchNb);
219       void prepareSequenceValues(int sizeOfSamples);
220       OutPort *getDynOutPortByAbsName(int branchNb, const std::string& name);
221       void storeOutValsInSeqForOutOfScopeUse(int rank, int branchNb);
222     private:
223       int getFinishedId();
224     public:
225       static void InterceptorizeNameOfPort(std::string& portName);
226       static const char INTERCEPTOR_STR[];
227     };
228   }
229
230
231 #endif