Salome HOME
Implementation of keep going mode of executor for ForEachLoops.
[modules/yacs.git] / src / engine / ForEachLoop.hxx
1 // Copyright (C) 2006-2015  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 Executor;
127
128     class YACSLIBENGINE_EXPORT ForEachLoop : public DynParaLoop
129     {
130       friend class SplitterNode;
131       friend class FakeNodeForForEachLoop;
132
133     public:
134       static const char NAME_OF_SPLITTERNODE[];
135     protected:
136       static const int NOT_RUNNING_BRANCH_ID;
137     protected:
138       int _currentIndex;
139       SplitterNode _splitterNode;
140       FakeNodeForForEachLoop *_nodeForSpecialCases;
141       std::vector<AnySplitOutputPort *> _outGoingPorts;//! ports linked to node outside the current scope
142       std::vector<InterceptorInputPort *> _intecptrsForOutGoingPorts;//!ports created for TypeCodes correctness
143       //part of attributes defining graph dynamically built on control notification
144       unsigned _execCurrentId;
145       std::vector<SequenceAny *> _execVals;
146       std::vector< std::vector<AnyInputPort *> > _execOutGoingPorts;
147     public:
148       ForEachLoop(const std::string& name, TypeCode *typeOfDataSplitted);
149       ForEachLoop(const ForEachLoop& other, ComposedNode *father, bool editionOnly);
150       ~ForEachLoop();
151       void init(bool start=true);
152       void exUpdateState();
153       void exUpdateProgress();
154       void getReadyTasks(std::vector<Task *>& tasks);
155       int getNumberOfInputPorts() const;
156       //
157       void checkNoCyclePassingThrough(Node *node) throw(Exception);
158       void selectRunnableTasks(std::vector<Task *>& tasks);
159       //
160       unsigned getExecCurrentId() const { return _execCurrentId; } // for update progress bar on GUI part
161       std::list<InputPort *> getSetOfInputPort() const;
162       std::list<InputPort *> getLocalInputPorts() const;
163       InputPort *edGetSeqOfSamplesPort() { return &_splitterNode._dataPortToDispatch; }
164       InputPort *getInputPort(const std::string& name) const throw(Exception);
165       OutPort *getOutPort(const std::string& name) const throw(Exception);
166       OutputPort *getOutputPort(const std::string& name) const throw(Exception);
167       Node *getChildByShortName(const std::string& name) const throw(Exception);
168       std::list<OutputPort *> getLocalOutputPorts() const;
169       void accept(Visitor *visitor);
170       void writeDot(std::ostream &os) const;
171       virtual std::string typeName() {return "YACS__ENGINE__ForEachLoop";}
172       virtual void resetState(int level);
173       std::string getProgress() const;
174 #ifndef SWIG
175       std::vector<unsigned int> getPassedResults(Executor *execut, std::vector<SequenceAny *>& outputs, std::vector<std::string>& nameOfOutputs) const;
176 #endif
177     protected:
178       Node *simpleClone(ComposedNode *father, bool editionOnly=true) const;
179       void checkLinkPossibility(OutPort *start, const std::list<ComposedNode *>& pointsOfViewStart,
180                                 InPort *end, const std::list<ComposedNode *>& pointsOfViewEnd) throw(Exception);
181       YACS::Event updateStateOnFinishedEventFrom(Node *node);
182       YACS::Event updateStateForInitNodeOnFinishedEventFrom(Node *node, unsigned int id);
183       YACS::Event updateStateForWorkNodeOnFinishedEventFrom(Node *node, unsigned int id, bool isNormalFinish);
184       YACS::Event updateStateForFinalizeNodeOnFinishedEventFrom(Node *node, unsigned int id);
185       YACS::Event updateStateOnFailedEventFrom(Node *node, const Executor *execInst);
186       void buildDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView);
187       void getDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView) throw(Exception);
188       void releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView) throw(Exception);
189     protected:
190       void cleanDynGraph();
191       void pushAllSequenceValues();
192       void createOutputOutOfScopeInterceptors(int branchNb);
193       void prepareSequenceValues(int sizeOfSamples);
194       OutPort *getDynOutPortByAbsName(int branchNb, const std::string& name);
195       void storeOutValsInSeqForOutOfScopeUse(int rank, int branchNb);
196     };
197   }
198
199
200 #endif