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