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