Salome HOME
copy tag mergefrom_BR_V0_1_CC_Salome_04oct07
[modules/yacs.git] / src / engine / ElementaryNode.cxx
1 #include "ElementaryNode.hxx"
2 #include "Runtime.hxx"
3 #include "InputPort.hxx"
4 #include "OutputPort.hxx"
5 #include "ComposedNode.hxx"
6 #include "InputDataStreamPort.hxx"
7 #include "OutputDataStreamPort.hxx"
8 #include "Visitor.hxx"
9 #include <iostream>
10
11 using namespace YACS::ENGINE;
12 using namespace std;
13
14 ElementaryNode::ElementaryNode(const std::string& name):Node(name)
15 {
16 }
17
18 ElementaryNode::ElementaryNode(const ElementaryNode& other, ComposedNode *father):Node(other,father)
19 {
20   for(list<InputPort *>::const_iterator iter1=other._setOfInputPort.begin();iter1!=other._setOfInputPort.end();iter1++)
21     _setOfInputPort.push_back((InputPort *)(*iter1)->clone(this));
22   for(list<OutputPort *>::const_iterator iter2=other._setOfOutputPort.begin();iter2!=other._setOfOutputPort.end();iter2++)
23     _setOfOutputPort.push_back((OutputPort *)(*iter2)->clone(this));
24   for(list<InputDataStreamPort *>::const_iterator iter3=other._setOfInputDataStreamPort.begin();iter3!=other._setOfInputDataStreamPort.end();iter3++)
25     _setOfInputDataStreamPort.push_back((InputDataStreamPort *)(*iter3)->clone(this));
26   for(list<OutputDataStreamPort *>::const_iterator iter4=other._setOfOutputDataStreamPort.begin();iter4!=other._setOfOutputDataStreamPort.end();iter4++)
27     _setOfOutputDataStreamPort.push_back((OutputDataStreamPort *)(*iter4)->clone(this));
28 }
29
30 void ElementaryNode::performDuplicationOfPlacement(const Node& other)
31 {
32 }
33
34 ElementaryNode::~ElementaryNode()
35 {
36   for(list<InputPort *>::iterator iter1=_setOfInputPort.begin();iter1!=_setOfInputPort.end();iter1++)
37     delete *iter1;
38   for(list<OutputPort *>::iterator iter2=_setOfOutputPort.begin();iter2!=_setOfOutputPort.end();iter2++)
39     delete *iter2;
40   for(list<InputDataStreamPort *>::iterator iter3=_setOfInputDataStreamPort.begin();iter3!=_setOfInputDataStreamPort.end();iter3++)
41     delete *iter3;
42   for(list<OutputDataStreamPort *>::iterator iter4=_setOfOutputDataStreamPort.begin();iter4!=_setOfOutputDataStreamPort.end();iter4++)
43     delete *iter4;
44 }
45
46 void ElementaryNode::init(bool start)
47 {
48   for(list<OutputPort *>::iterator iter=_setOfOutputPort.begin();iter!=_setOfOutputPort.end();iter++)
49     (*iter)->exInit();
50   for(list<InputPort *>::iterator iter2=_setOfInputPort.begin();iter2!=_setOfInputPort.end();iter2++)
51     (*iter2)->exInit(start);
52   _inGate.exReset();
53   if(_state == YACS::DISABLED)
54     {
55       exDisabledState(); // to refresh propagation of DISABLED state
56       return;
57     }
58   if(start) //complete initialization
59     setState(YACS::INITED);
60   else //partial initialization (inside a loop)
61     _state=YACS::LOADED;
62 }
63
64 bool ElementaryNode::isDeployable() const
65 {
66   return false;
67 }
68
69 ComponentInstance *ElementaryNode::getComponent()
70 {
71   return 0;
72 }
73
74 YACS::StatesForNode ElementaryNode::getState() const
75 {
76   return Node::getState();
77 }
78
79 void ElementaryNode::exUpdateState()
80 {
81   if(_state==YACS::DISABLED)return;
82   if(_inGate.exIsReady())
83     if(areAllInputPortsValid())
84       if(_state == YACS::INITED)
85         setState(YACS::TOLOAD);
86       else
87         setState(YACS::TOACTIVATE);
88     else
89       {
90         string what("ElementaryNode::exUpdateState : Invalid graph given : Node with name \"");
91         what+=_name; what+="\" ready to run whereas some inputports are not set correctly\nCheck coherence DF/CF";
92         setState(YACS::INTERNALERR);
93         throw Exception(what);
94       }
95 }
96
97 int ElementaryNode::getNumberOfInputPorts() const
98 {
99   return _setOfInputPort.size();
100 }
101
102 int ElementaryNode::getNumberOfOutputPorts() const
103 {
104   return _setOfOutputPort.size();
105 }
106
107 InputPort *ElementaryNode::getInputPort(const std::string& name) const throw(Exception)
108 {
109   return getPort<InputPort>(name,_setOfInputPort);
110 }
111
112 OutputPort *ElementaryNode::getOutputPort(const std::string& name) const throw(Exception)
113 {
114   return getPort<OutputPort>(name,_setOfOutputPort);
115 }
116
117 std::set<OutPort *> ElementaryNode::getAllOutPortsLeavingCurrentScope() const
118 {
119   set<OutPort *> ret;
120   list<OutPort *> temp=getSetOfOutPort();
121   for(list<OutPort *>::iterator iter2=temp.begin();iter2!=temp.end();iter2++)
122     {
123       set<InPort *> temp2=(*iter2)->edSetInPort();
124       if(temp2.size()!=0)
125         ret.insert(*iter2);
126     }
127   return ret;
128 }
129
130 std::set<InPort *> ElementaryNode::getAllInPortsComingFromOutsideOfCurrentScope() const
131 {
132   set<InPort *> ret;
133   list<InPort *> temp=getSetOfInPort();
134   for(list<InPort *>::iterator iter2=temp.begin();iter2!=temp.end();iter2++)
135     {
136       set<OutPort *> temp2=(*iter2)->edSetOutPort();
137       if(temp2.size()!=0)
138         ret.insert(*iter2);
139     }
140   return ret;
141 }
142
143 InputDataStreamPort *ElementaryNode::getInputDataStreamPort(const std::string& name) const throw(Exception)
144 {
145   return getPort<InputDataStreamPort>(name,_setOfInputDataStreamPort);
146 }
147
148 OutputDataStreamPort *ElementaryNode::getOutputDataStreamPort(const std::string& name) const throw(Exception)
149 {
150   return getPort<OutputDataStreamPort>(name,_setOfOutputDataStreamPort);
151 }
152
153 void ElementaryNode::edDisconnectAllLinksWithMe()
154 {
155   //CF
156   Node::edDisconnectAllLinksWithMe();
157   //Leaving part
158   // - DF
159   for(list<InputPort *>::iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
160     (*iter)->edRemoveAllLinksLinkedWithMe();
161   // - DS
162   for(list<InputDataStreamPort *>::iterator iter2=_setOfInputDataStreamPort.begin();iter2!=_setOfInputDataStreamPort.end();iter2++)
163     (*iter2)->edRemoveAllLinksLinkedWithMe();
164   //Arriving part
165   // - DF
166   for(list<OutputPort *>::iterator iter=_setOfOutputPort.begin();iter!=_setOfOutputPort.end();iter++)
167     (*iter)->edRemoveAllLinksLinkedWithMe();
168   // - DS
169   for(list<OutputDataStreamPort *>::iterator iter2=_setOfOutputDataStreamPort.begin();iter2!=_setOfOutputDataStreamPort.end();iter2++)
170     (*iter2)->edRemoveAllLinksLinkedWithMe();
171 }
172
173 /**
174  * checks if all input ports contains a valid data. Used at execution to change the state of the node
175  * for activation.
176  */
177
178 bool ElementaryNode::areAllInputPortsValid() const
179 {
180   bool ret=true;
181   for(list<InputPort *>::const_iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
182     {
183       ret=!(*iter)->isEmpty();
184       if (!ret) break;
185     }
186   return ret;
187 }
188
189 /**
190  * add this node task to a given set of ready tasks, if this task is ready to activate
191  */
192
193 void ElementaryNode::getReadyTasks(std::vector<Task *>& tasks)
194 {
195   if(_state==YACS::TOACTIVATE or _state==YACS::TOLOAD)
196     tasks.push_back(this);
197 }
198
199 /**
200  * remove port from node at edition. Ports are typed.
201  */
202
203 void ElementaryNode::edRemovePort(Port *port) throw(Exception)
204 {
205   if(port->getNode()!=this)
206     throw Exception("ElementaryNode::edRemovePort : Port is not held by this");
207   string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance();
208   if(typeOfPortInstance==InputPort::NAME)
209     edRemovePortTypedFromSet<InputPort>(dynamic_cast<InputPort *>(port),_setOfInputPort);
210   else if(typeOfPortInstance==OutputPort::NAME)
211     edRemovePortTypedFromSet<OutputPort>(dynamic_cast<OutputPort *>(port),_setOfOutputPort);
212   else if(typeOfPortInstance==InputDataStreamPort::NAME)
213     edRemovePortTypedFromSet<InputDataStreamPort>(dynamic_cast<InputDataStreamPort *>(port),_setOfInputDataStreamPort);
214   else if(typeOfPortInstance==OutputDataStreamPort::NAME)
215     edRemovePortTypedFromSet<OutputDataStreamPort>(dynamic_cast<OutputDataStreamPort *>(port),_setOfOutputDataStreamPort);
216   else
217     throw Exception("ElementaryNode::edRemovePort : unknown port type");
218   delete port;
219 }
220
221 /**
222  * @return a set with only this node. (Same method in composed nodes)
223  */
224
225 set<ElementaryNode *> ElementaryNode::getRecursiveConstituents() const
226 {
227   set<ElementaryNode *> ret;
228   ret.insert((ElementaryNode *)this);
229   return ret;
230 }
231
232 Node *ElementaryNode::getChildByName(const std::string& name) const throw(Exception)
233 {
234   string what("ElementaryNode does not agregate any nodes particullary node with name "); what+=name;
235   throw Exception(what);
236 }
237
238 void ElementaryNode::checkBasicConsistency() const throw(Exception)
239 {
240   list<InputPort *>::const_iterator iter;
241   for(iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
242     (*iter)->checkBasicConsistency();  
243 }
244
245 ComposedNode *ElementaryNode::getDynClonerIfExists(const ComposedNode *levelToStop) const
246 {
247   for(ComposedNode *iter=_father;iter!=levelToStop && iter!=0; iter=iter->_father)
248     if(!iter->isPlacementPredictableB4Run())
249       return iter;
250   return 0;
251 }
252
253 /**
254  * the input port is also published recursively in ancestors because it may be visible from everywhere.
255  * WARNING: CHECK CASE OF BLOC: ONLY INPUT PORTS NOT INTERNALLY CONNECTED MUST BE VISIBLE.
256  */
257
258 InputPort *ElementaryNode::edAddInputPort(const std::string& inputPortName, TypeCode* type) throw(Exception)
259 {
260   InputPort *ret = 0;
261   if (edCheckAddPort<InputPort, TypeCode*>(inputPortName,_setOfInputPort,type))
262     {
263       ret = getRuntime()->createInputPort(inputPortName, _implementation, this, type);
264       _setOfInputPort.push_back(ret);
265       ComposedNode *iter=_father;
266       while(iter)
267         iter=iter->_father;
268     }
269   return ret;
270 }
271
272 /**
273  * TO SOLVE : The output port is not published in father. Father must create an output port.
274  * for now, publication is done the same way as input ports
275  */ 
276
277 OutputPort *ElementaryNode::edAddOutputPort(const std::string& outputPortName, TypeCode* type) throw(Exception)
278 {
279   OutputPort *ret =0;
280   if (edCheckAddPort<OutputPort, TypeCode*>(outputPortName,_setOfOutputPort,type))
281     {
282       ret = getRuntime()->createOutputPort(outputPortName, _implementation, this, type);
283       _setOfOutputPort.push_back(ret);
284       ComposedNode *iter=_father;
285       while(iter)
286         iter=iter->_father;
287     }
288   return ret;
289 }
290
291 InputDataStreamPort *ElementaryNode::edAddInputDataStreamPort(const std::string& inputPortDSName, TypeCode* type) throw(Exception)
292 {
293   InputDataStreamPort *ret = 0;
294   if (edCheckAddPort<InputDataStreamPort, TypeCode*>(inputPortDSName,_setOfInputDataStreamPort,type))
295     {
296       ret = getRuntime()->createInputDataStreamPort(inputPortDSName, this, type);
297       _setOfInputDataStreamPort.push_back(ret);
298     }
299   return ret;
300 }
301
302 OutputDataStreamPort *ElementaryNode::edAddOutputDataStreamPort(const std::string& outputPortDSName, TypeCode* type) throw(Exception)
303 {
304   OutputDataStreamPort *ret = 0;
305   if (edCheckAddPort<OutputDataStreamPort, TypeCode*>(outputPortDSName,_setOfOutputDataStreamPort,type))
306     {
307       ret = getRuntime()->createOutputDataStreamPort(outputPortDSName, this, type);
308       _setOfOutputDataStreamPort.push_back(ret);
309     }
310   return ret;
311 }
312
313 /**
314  * get the input port name used by the current node (see composed nodes)
315  */
316
317 string ElementaryNode::getInPortName(const InPort * inPort) const throw (Exception)
318 {
319   Node *node = inPort->getNode();
320   if ( node != this ) 
321     {
322       string what("InputPort "); what += inPort->getName(); what += " does not belong to node "; what += node->getName();
323       throw Exception(what);
324     }
325   return inPort->getName();
326 }
327
328 string ElementaryNode::getOutPortName(const OutPort *outPort) const throw (Exception)
329 {
330   Node *node = outPort->getNode();
331   if ( node != this ) 
332     {
333       string what("OutputPort "); what += outPort->getName(); what += " does not belong to node "; what += node->getName();
334       throw Exception(what);
335     }
336   return outPort->getName();
337 }
338
339 void ElementaryNode::begin()
340 {
341   setState(ACTIVATED);
342 }
343
344 bool ElementaryNode::isReady()
345 {
346   return _state==TOACTIVATE;
347 }
348
349 void ElementaryNode::finished()
350 {
351   setState(DONE);
352 }
353 void ElementaryNode::aborted()
354 {
355   setState(ERROR);
356 }
357
358 //! Notify this node that it is loaded
359 /*!
360  * When an elementary node has been loaded it goes to TOACTIVATE state
361  * It is then ready to be executed
362  *
363  */
364 void ElementaryNode::loaded()
365 {
366   setState(TOACTIVATE);
367 }
368
369 void ElementaryNode::accept(Visitor *visitor)
370 {
371   visitor->visitElementaryNode(this);
372 }