Salome HOME
94bf78e2082e13fb10588876ffe9fb1124b3ef24
[modules/yacs.git] / src / engine / Loop.cxx
1 #include "Loop.hxx"
2 #include "InputPort.hxx"
3 #include "OutputPort.hxx"
4 #include "InputDataStreamPort.hxx"
5 #include "OutputDataStreamPort.hxx"
6 #include "TypeCheckerDataStream.hxx"
7
8 using namespace YACS::ENGINE;
9
10 DFToDSForLoop::DFToDSForLoop(Loop *loop, const std::string& name, YACS::DynType type):ElementaryNode(""),_nbOfTimeUsed(1)
11 {
12   _name="DF2DS For "; _name+=loop->getName(); _name+=" representing port "; _name+=name;
13   _father=loop;
14   _listOfInputPort.push_back(new InputPort("",this,type));
15   _listOfOutputDataStreamPort.push_back(new OutputDataStreamPort("",this,Loop::MappingDF2DS(type)));
16 }
17
18 DFToDSForLoop::~DFToDSForLoop()
19 {
20 }
21
22 InputPort *DFToDSForLoop::getInputPort(const std::string& name) const throw(Exception)
23 {
24   return (InputPort *) &_listOfInputPort.back();
25 }
26
27 OutputDataStreamPort *DFToDSForLoop::getOutputDataStreamPort(const std::string& name) const throw(Exception)
28 {
29   return (OutputDataStreamPort *) &_listOfOutputDataStreamPort.back();
30 }
31
32 void DFToDSForLoop::execute()
33 {
34   //TO IMPLEMENT
35 }
36
37 DSToDFForLoop::DSToDFForLoop(Loop *loop, const std::string& name, YACS::StreamType type):ElementaryNode(""),_nbOfTimeUsed(1)
38 {
39   _name="DS2DF For "; _name+=loop->getName(); _name+=" representing port "; _name+=name;
40   _father=loop;
41   _listOfOutputPort.push_back(new OutputPort("",this,Loop::MappingDS2DF(type)));
42   _listOfInputDataStreamPort.push_back(new InputDataStreamPort("",this,type));
43 }
44
45 DSToDFForLoop::~DSToDFForLoop()
46 {
47 }
48
49 OutputPort *DSToDFForLoop::getOutputPort(const std::string& name) const throw(Exception)
50 {
51   return (OutputPort *) &_listOfOutputPort.back();
52 }
53
54 InputDataStreamPort *DSToDFForLoop::getInputDataStreamPort(const std::string& name) const throw(Exception)
55 {
56   return (InputDataStreamPort *) &_listOfInputDataStreamPort.back();
57 }
58
59 void DSToDFForLoop::execute()
60 {
61   //TO IMPLEMENT
62 }
63
64 Loop::Loop(const std::string& name):ComposedNode(name),_node(0)
65 {
66 }
67
68 Loop::~Loop()
69 {
70   delete _node;
71 }
72
73 void Loop::edSetNode(Node *node)
74 {
75   delete _node;
76   _node=node;
77 }
78
79 void Loop::edAddExtraInputPort(const std::string& inputPortName, YACS::DynType type) throw(Exception)
80 {
81   edAddPort<InputPort,YACS::DynType>(inputPortName,_listOfExtraInputPort,type);
82 }
83
84 void Loop::edRemoveExtraInputPort(InputPort *inputPort)
85 {
86   edRemovePortTypedFromList<InputPort>(inputPort,_listOfExtraInputPort);
87 }
88
89 YACS::StreamType Loop::MappingDF2DS(YACS::DynType type) throw(Exception)
90 {
91   switch(type)
92     {
93       case Double:
94         return SDouble;
95     }
96   std::string what("Loop::MappingDF2DS : unable to perform DataFlow to DataStream traduction for dataflow type ");
97   what+=Data::edGetTypeInPrintableForm(type);
98   throw Exception(what);
99 }
100
101 YACS::DynType Loop::MappingDS2DF(YACS::StreamType type) throw(Exception)
102 {
103   switch(type)
104     {
105       case SDouble:
106         return Double;
107     }
108   std::string what("Loop::MappingDS2DF : unable to perform DataStream to DataFlow traduction for datastream type ");
109   what+=TypeCheckerDataStream::edGetTypeInPrintableForm(type);
110   throw Exception(what);
111 }
112
113 InPort *Loop::buildDelegateOf(InPort *port, const std::list<ComposedNode *>& pointsOfView)
114 {
115   std::string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance();
116   if(typeOfPortInstance!=InputPort::NAME)
117     return port;
118   else
119     if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView))
120       return port;
121   InputPort *portCasted=(InputPort *)port;
122   std::list<DSToDFForLoop>::iterator iter;
123   //Determinig if a DSToDFForLoop node has already been created for delegation of 'port'
124   for(iter=_inputsTraducer.begin();iter!=_inputsTraducer.end();iter++)
125     if((*iter).getOutputPort("")->isAlreadyInList(portCasted))
126       break;
127   if(iter==_inputsTraducer.end())
128     {//first time that 'port' is delegated on higher level
129       _inputsTraducer.push_back(DSToDFForLoop(this,portCasted->getName(),Loop::MappingDF2DS(portCasted->edGetType())));
130       iter=_inputsTraducer.end(); iter--;
131       (*iter).getOutputPort("")->edAddInputPort(portCasted);
132       //WARNING control flow has to be added
133       (*iter).getOutGate()->edAddInGate(portCasted->getNode()->getInGate());//WARNING HERE MAYBE HAS TO BE IMPROVED - SEPARATE COUNTERS
134     }
135   else
136     (*iter).loopHasOneMoreRef();
137   return (*iter).getInputDataStreamPort("");
138 }
139
140 OutPort *Loop::buildDelegateOf(OutPort *port, const std::list<ComposedNode *>& pointsOfView)
141 {
142   std::string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance();
143   if(typeOfPortInstance!=OutputPort::NAME)
144     return port;
145   else
146     if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView))
147       return port;
148   OutputPort *portCasted=(OutputPort *)port;
149   std::list<DFToDSForLoop>::iterator iter;
150   //Determinig if a DFToDSForLoop node has already been created for delegation of 'port'
151   for(iter=_outputsTraducer.begin();iter!=_outputsTraducer.end();iter++)
152     if(portCasted->isAlreadyInList((*iter).getInputPort("")))
153       break;
154   if(iter==_outputsTraducer.end())
155     {//first time that 'port' is delegated on higher level
156       _outputsTraducer.push_back(DFToDSForLoop(this,portCasted->getName(),portCasted->edGetType()));
157       iter=_outputsTraducer.end(); iter--;
158       portCasted->edAddInputPort((*iter).getInputPort(""));
159       //WARNING control flow has to be added
160       portCasted->getNode()->getOutGate()->edAddInGate((*iter).getInGate());//WARNING HERE MAYBE HAS TO BE IMPROVED - SEPARATE COUNTERS
161     }
162   else
163     (*iter).loopHasOneMoreRef();
164   return (*iter).getOutputDataStreamPort("");
165 }
166
167 InPort *Loop::getDelegateOf(InPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception)
168 {
169   std::string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance();
170   if(typeOfPortInstance!=InputPort::NAME)
171     return port;
172   else
173     if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView))
174       return port;
175   InputPort *portCasted=(InputPort *)port;
176   std::list<DSToDFForLoop>::iterator iter;
177   for(iter=_inputsTraducer.begin();iter!=_inputsTraducer.end();iter++)
178     if((*iter).getOutputPort("")->isAlreadyInList(portCasted))
179       break;
180   if(iter==_inputsTraducer.end())
181     {
182       std::string what("Loop::getDelegateOf Port with name "); what+=portCasted->getName(); what+=" not exported by loop "; what+=_name; 
183       throw Exception(what);
184     }
185   else
186     return (*iter).getInputDataStreamPort("");
187 }
188
189 OutPort *Loop::getDelegateOf(OutPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception)
190 {
191   std::string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance();
192   if(typeOfPortInstance!=OutputPort::NAME)
193     return port;
194   else
195     if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView))
196       return port;
197   OutputPort *portCasted=(OutputPort *)port;
198   std::list<DFToDSForLoop>::iterator iter;
199   for(iter=_outputsTraducer.begin();iter!=_outputsTraducer.end();iter++)
200     if(portCasted->isAlreadyInList((*iter).getInputPort("")))
201       break;
202   if(iter==_outputsTraducer.end())
203     {
204       std::string what("Loop::getDelegateOf Port with name "); what+=portCasted->getName(); what+=" not exported by loop "; what+=_name; 
205       throw Exception(what);
206     }
207   else
208     return (*iter).getOutputDataStreamPort("");
209 }
210
211 InPort *Loop::releaseDelegateOf(InPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception)
212 {
213   std::string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance();
214   if(typeOfPortInstance!=InputPort::NAME)
215     return port;
216   else
217     if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView))
218       return port;
219   InputPort *portCasted=(InputPort *)port;
220   std::list<DSToDFForLoop>::iterator iter;
221   for(iter=_inputsTraducer.begin();iter!=_inputsTraducer.end();iter++)
222     if((*iter).getOutputPort("")->isAlreadyInList(portCasted))
223       break;
224   if(iter==_inputsTraducer.end())
225     {
226       std::string what("Loop::releaseDelegateOf Port with name "); what+=portCasted->getName(); what+=" not exported by loop "; what+=_name; 
227       throw Exception(what);
228     }
229   else
230     {
231       InPort *ret=(*iter).getInputDataStreamPort("");
232       if((*iter).loopHasOneLessRef())
233         _inputsTraducer.erase(iter);
234       return ret;
235     }
236 }
237
238 OutPort *Loop::releaseDelegateOf(OutPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception)
239 {
240     std::string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance();
241   if(typeOfPortInstance!=OutputPort::NAME)
242     return port;
243   else
244     if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView))
245       return port;
246   OutputPort *portCasted=(OutputPort *)port;
247   std::list<DFToDSForLoop>::iterator iter;
248   for(iter=_outputsTraducer.begin();iter!=_outputsTraducer.end();iter++)
249     if(portCasted->isAlreadyInList((*iter).getInputPort("")))
250       break;
251   if(iter==_outputsTraducer.end())
252     {
253       std::string what("Loop::releaseDelegateOf Port with name "); what+=portCasted->getName(); what+=" not exported by loop "; what+=_name; 
254       throw Exception(what);
255     }
256   else
257     {
258       OutPort *ret=(*iter).getOutputDataStreamPort("");
259       if((*iter).loopHasOneLessRef())
260         _outputsTraducer.erase(iter);
261       return ret;
262     }
263 }
264
265 void Loop::checkNoCyclePassingThrough(Node *node) throw(Exception)
266 {
267   throw Exception("Loop::checkNoCyclePassingThrough : Internal error occured");
268 }
269
270 /**
271  * @ note : States if a DF port must be considered on an upper level in hierarchy as a DS port or not from 'pointsOfView' observers.
272  * @ return : 
273  *            - True : a traduction DF->DS has to be done
274  *            - False : no traduction needed
275  */
276 bool Loop::isNecessaryToBuildSpecificDelegateDF2DS(const std::list<ComposedNode *>& pointsOfView)
277 {
278   bool ret=false;
279   for(std::list<ComposedNode *>::const_iterator iter=pointsOfView.begin();iter!=pointsOfView.end() && !ret;iter++)
280     ret=(*iter)->isRepeatedUnpredictablySeveralTimes();
281   return ret;
282 }