1 #include "ElementaryNode.hxx"
3 #include "InputPort.hxx"
4 #include "OutputPort.hxx"
5 #include "ComposedNode.hxx"
6 #include "InputDataStreamPort.hxx"
7 #include "OutputDataStreamPort.hxx"
12 #include "YacsTrace.hxx"
14 using namespace YACS::ENGINE;
17 ElementaryNode::ElementaryNode(const std::string& name):Node(name)
21 ElementaryNode::ElementaryNode(const ElementaryNode& other, ComposedNode *father):Node(other,father)
23 for(list<InputPort *>::const_iterator iter1=other._setOfInputPort.begin();iter1!=other._setOfInputPort.end();iter1++)
24 _setOfInputPort.push_back((InputPort *)(*iter1)->clone(this));
25 for(list<OutputPort *>::const_iterator iter2=other._setOfOutputPort.begin();iter2!=other._setOfOutputPort.end();iter2++)
26 _setOfOutputPort.push_back((OutputPort *)(*iter2)->clone(this));
27 for(list<InputDataStreamPort *>::const_iterator iter3=other._setOfInputDataStreamPort.begin();iter3!=other._setOfInputDataStreamPort.end();iter3++)
28 _setOfInputDataStreamPort.push_back((InputDataStreamPort *)(*iter3)->clone(this));
29 for(list<OutputDataStreamPort *>::const_iterator iter4=other._setOfOutputDataStreamPort.begin();iter4!=other._setOfOutputDataStreamPort.end();iter4++)
30 _setOfOutputDataStreamPort.push_back((OutputDataStreamPort *)(*iter4)->clone(this));
33 void ElementaryNode::performDuplicationOfPlacement(const Node& other)
37 ElementaryNode::~ElementaryNode()
39 for(list<InputPort *>::iterator iter1=_setOfInputPort.begin();iter1!=_setOfInputPort.end();iter1++)
41 for(list<OutputPort *>::iterator iter2=_setOfOutputPort.begin();iter2!=_setOfOutputPort.end();iter2++)
43 for(list<InputDataStreamPort *>::iterator iter3=_setOfInputDataStreamPort.begin();iter3!=_setOfInputDataStreamPort.end();iter3++)
45 for(list<OutputDataStreamPort *>::iterator iter4=_setOfOutputDataStreamPort.begin();iter4!=_setOfOutputDataStreamPort.end();iter4++)
49 void ElementaryNode::init(bool start)
51 for(list<OutputPort *>::iterator iter=_setOfOutputPort.begin();iter!=_setOfOutputPort.end();iter++)
53 for(list<InputPort *>::iterator iter2=_setOfInputPort.begin();iter2!=_setOfInputPort.end();iter2++)
54 (*iter2)->exInit(start);
56 if(_state == YACS::DISABLED)
58 exDisabledState(); // to refresh propagation of DISABLED state
61 if(start) //complete initialization
62 setState(YACS::READY);
63 else //partial initialization (inside a loop)
64 setState(YACS::LOADED);
67 bool ElementaryNode::isDeployable() const
72 ComponentInstance *ElementaryNode::getComponent()
77 YACS::StatesForNode ElementaryNode::getState() const
79 return Node::getState();
82 void ElementaryNode::exUpdateState()
84 DEBTRACE("ElementaryNode::exUpdateState: " << getName() << " " << _state );
85 if(_state==YACS::DISABLED)return;
86 if(_inGate.exIsReady())
87 if(areAllInputPortsValid())
89 if(_state == YACS::READY)
91 else if(_state == YACS::LOADED)
92 setState(YACS::TOACTIVATE);
96 string what("ElementaryNode::exUpdateState : Invalid graph given : Node with name \"");
97 what+=_name; what+="\" ready to run whereas some inputports are not set correctly\nCheck coherence DF/CF";
98 setState(YACS::INTERNALERR);
100 throw Exception(what);
104 int ElementaryNode::getNumberOfInputPorts() const
106 return _setOfInputPort.size();
109 int ElementaryNode::getNumberOfOutputPorts() const
111 return _setOfOutputPort.size();
114 InputPort *ElementaryNode::getInputPort(const std::string& name) const throw(Exception)
116 return getPort<InputPort>(name,_setOfInputPort);
119 OutputPort *ElementaryNode::getOutputPort(const std::string& name) const throw(Exception)
121 return getPort<OutputPort>(name,_setOfOutputPort);
124 std::set<OutPort *> ElementaryNode::getAllOutPortsLeavingCurrentScope() const
127 list<OutPort *> temp=getSetOfOutPort();
128 for(list<OutPort *>::iterator iter2=temp.begin();iter2!=temp.end();iter2++)
130 set<InPort *> temp2=(*iter2)->edSetInPort();
137 std::set<InPort *> ElementaryNode::getAllInPortsComingFromOutsideOfCurrentScope() const
140 list<InPort *> temp=getSetOfInPort();
141 for(list<InPort *>::iterator iter2=temp.begin();iter2!=temp.end();iter2++)
143 set<OutPort *> temp2=(*iter2)->edSetOutPort();
150 std::vector< std::pair<OutPort *, InPort *> > ElementaryNode::getSetOfLinksLeavingCurrentScope() const
152 vector< pair<OutPort *, InPort *> > ret;
153 std::set<OutPort *> ports=getAllOutPortsLeavingCurrentScope();
154 for(set<OutPort *>::iterator iter2=ports.begin();iter2!=ports.end();iter2++)
156 set<InPort *> temp2=(*iter2)->edSetInPort();
157 for(set<InPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
158 ret.push_back(pair<OutPort *, InPort *>(*iter2,*iter3));
163 std::vector< std::pair<InPort *, OutPort *> > ElementaryNode::getSetOfLinksComingInCurrentScope() const
165 vector< pair<InPort *, OutPort *> > ret;
166 set<InPort *> ports=getAllInPortsComingFromOutsideOfCurrentScope();
167 for(set<InPort *>::iterator iter2=ports.begin();iter2!=ports.end();iter2++)
169 set<OutPort *> temp2=(*iter2)->edSetOutPort();
170 for(set<OutPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
171 ret.push_back(pair<InPort *, OutPort *>(*iter2,*iter3));
176 InputDataStreamPort *ElementaryNode::getInputDataStreamPort(const std::string& name) const throw(Exception)
178 return getPort<InputDataStreamPort>(name,_setOfInputDataStreamPort);
181 OutputDataStreamPort *ElementaryNode::getOutputDataStreamPort(const std::string& name) const throw(Exception)
183 return getPort<OutputDataStreamPort>(name,_setOfOutputDataStreamPort);
186 void ElementaryNode::edDisconnectAllLinksWithMe()
189 Node::edDisconnectAllLinksWithMe();
192 for(list<InputPort *>::iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
193 (*iter)->edRemoveAllLinksLinkedWithMe();
195 for(list<InputDataStreamPort *>::iterator iter2=_setOfInputDataStreamPort.begin();iter2!=_setOfInputDataStreamPort.end();iter2++)
196 (*iter2)->edRemoveAllLinksLinkedWithMe();
199 for(list<OutputPort *>::iterator iter=_setOfOutputPort.begin();iter!=_setOfOutputPort.end();iter++)
200 (*iter)->edRemoveAllLinksLinkedWithMe();
202 for(list<OutputDataStreamPort *>::iterator iter2=_setOfOutputDataStreamPort.begin();iter2!=_setOfOutputDataStreamPort.end();iter2++)
203 (*iter2)->edRemoveAllLinksLinkedWithMe();
207 * checks if all input ports contains a valid data. Used at execution to change the state of the node
211 bool ElementaryNode::areAllInputPortsValid() const
214 for(list<InputPort *>::const_iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
216 ret=!(*iter)->isEmpty();
223 * add this node task to a given set of ready tasks, if this task is ready to activate
226 void ElementaryNode::getReadyTasks(std::vector<Task *>& tasks)
228 DEBTRACE("ElementaryNode::getReadyTasks: " << getName() << " " << _state);
229 if(_state==YACS::TOACTIVATE or _state==YACS::TOLOAD)
230 tasks.push_back(this);
234 * remove port from node at edition. Ports are typed.
237 void ElementaryNode::edRemovePort(Port *port) throw(Exception)
239 DEBTRACE("ElementaryNode::edRemovePort ");
240 if(port->getNode()!=this)
241 throw Exception("ElementaryNode::edRemovePort : Port is not held by this");
242 string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance();
243 if(typeOfPortInstance==InputPort::NAME)
244 edRemovePortTypedFromSet<InputPort>(dynamic_cast<InputPort *>(port),_setOfInputPort);
245 else if(typeOfPortInstance==OutputPort::NAME)
246 edRemovePortTypedFromSet<OutputPort>(dynamic_cast<OutputPort *>(port),_setOfOutputPort);
247 else if(typeOfPortInstance==InputDataStreamPort::NAME)
248 edRemovePortTypedFromSet<InputDataStreamPort>(dynamic_cast<InputDataStreamPort *>(port),_setOfInputDataStreamPort);
249 else if(typeOfPortInstance==OutputDataStreamPort::NAME)
250 edRemovePortTypedFromSet<OutputDataStreamPort>(dynamic_cast<OutputDataStreamPort *>(port),_setOfOutputDataStreamPort);
252 throw Exception("ElementaryNode::edRemovePort : unknown port type");
258 * @return a set with only this node. (Same method in composed nodes)
261 list<ElementaryNode *> ElementaryNode::getRecursiveConstituents() const
263 list<ElementaryNode *> ret;
264 ret.push_back((ElementaryNode *)this);
268 Node *ElementaryNode::getChildByName(const std::string& name) const throw(Exception)
270 string what("ElementaryNode does not agregate any nodes particullary node with name "); what+=name;
271 throw Exception(what);
274 void ElementaryNode::checkBasicConsistency() const throw(Exception)
276 DEBTRACE("ElementaryNode::checkBasicConsistency");
277 list<InputPort *>::const_iterator iter;
278 for(iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
279 (*iter)->checkBasicConsistency();
282 ComposedNode *ElementaryNode::getDynClonerIfExists(const ComposedNode *levelToStop) const
284 for(ComposedNode *iter=_father;iter!=levelToStop && iter!=0; iter=iter->_father)
285 if(!iter->isPlacementPredictableB4Run())
290 InputPort *ElementaryNode::createInputPort(const std::string& inputPortName, TypeCode* type)
292 return getRuntime()->createInputPort(inputPortName, _implementation, this, type);
296 * the input port is also published recursively in ancestors because it may be visible from everywhere.
297 * WARNING: CHECK CASE OF BLOC: ONLY INPUT PORTS NOT INTERNALLY CONNECTED MUST BE VISIBLE.
300 InputPort *ElementaryNode::edAddInputPort(const std::string& inputPortName, TypeCode* type) throw(Exception)
303 if (edCheckAddPort<InputPort, TypeCode*>(inputPortName,_setOfInputPort,type))
305 ret = createInputPort(inputPortName, type);
306 _setOfInputPort.push_back(ret);
309 ComposedNode *iter=_father;
317 OutputPort *ElementaryNode::createOutputPort(const std::string& outputPortName, TypeCode* type)
319 return getRuntime()->createOutputPort(outputPortName, _implementation, this, type);
323 * TO SOLVE : The output port is not published in father. Father must create an output port.
324 * for now, publication is done the same way as input ports
327 OutputPort *ElementaryNode::edAddOutputPort(const std::string& outputPortName, TypeCode* type) throw(Exception)
330 if (edCheckAddPort<OutputPort, TypeCode*>(outputPortName,_setOfOutputPort,type))
332 ret = createOutputPort(outputPortName, type);
333 _setOfOutputPort.push_back(ret);
336 ComposedNode *iter=_father;
344 InputDataStreamPort *ElementaryNode::createInputDataStreamPort(const std::string& inputPortDSName, TypeCode* type)
346 return getRuntime()->createInputDataStreamPort(inputPortDSName, this, type);
349 InputDataStreamPort *ElementaryNode::edAddInputDataStreamPort(const std::string& inputPortDSName, TypeCode* type) throw(Exception)
351 InputDataStreamPort *ret = 0;
352 if (edCheckAddPort<InputDataStreamPort, TypeCode*>(inputPortDSName,_setOfInputDataStreamPort,type))
354 ret = createInputDataStreamPort(inputPortDSName, type);
355 _setOfInputDataStreamPort.push_back(ret);
361 OutputDataStreamPort *ElementaryNode::createOutputDataStreamPort(const std::string& outputPortDSName, TypeCode* type)
363 return getRuntime()->createOutputDataStreamPort(outputPortDSName, this, type);
366 OutputDataStreamPort *ElementaryNode::edAddOutputDataStreamPort(const std::string& outputPortDSName, TypeCode* type) throw(Exception)
368 OutputDataStreamPort *ret = 0;
369 if (edCheckAddPort<OutputDataStreamPort, TypeCode*>(outputPortDSName,_setOfOutputDataStreamPort,type))
371 ret = createOutputDataStreamPort(outputPortDSName, type);
372 _setOfOutputDataStreamPort.push_back(ret);
379 * get the input port name used by the current node (see composed nodes)
382 string ElementaryNode::getInPortName(const InPort * inPort) const throw (Exception)
384 Node *node = inPort->getNode();
387 string what("InputPort "); what += inPort->getName(); what += " does not belong to node "; what += node->getName();
388 throw Exception(what);
390 return inPort->getName();
393 string ElementaryNode::getOutPortName(const OutPort *outPort) const throw (Exception)
395 Node *node = outPort->getNode();
398 string what("OutputPort "); what += outPort->getName(); what += " does not belong to node "; what += node->getName();
399 throw Exception(what);
401 return outPort->getName();
404 void ElementaryNode::begin()
409 bool ElementaryNode::isReady()
411 return _state==TOACTIVATE;
414 void ElementaryNode::finished()
418 void ElementaryNode::aborted()
423 //! Notify this node that it is loaded
425 * When an elementary node has been loaded it goes to TOACTIVATE state
426 * It is then ready to be executed
429 void ElementaryNode::loaded()
432 if(_inGate.exIsReady())
433 if(areAllInputPortsValid())
434 setState(TOACTIVATE);
437 void ElementaryNode::accept(Visitor *visitor)
439 visitor->visitElementaryNode(this);
442 //! Give a description of error when node status is ERROR
446 std::string ElementaryNode::getErrorDetails()
448 return _errorDetails;
451 void ElementaryNode::edUpdateState()
453 DEBTRACE("ElementaryNode::edUpdateState: " << getName());
454 YACS::StatesForNode state=YACS::READY;
457 checkBasicConsistency();
463 _errorDetails=e.what();
465 DEBTRACE("ElementaryNode::edUpdateState: " << _errorDetails);
471 //! Put this node into TOLOAD state when possible
473 * Can be called by another ElementaryNode that is connected to this one by a datastream link
474 * These 2 nodes must be loaded at the same time as they are coupled
475 * It's the other node which requests this node loading
477 void ElementaryNode::ensureLoading()
479 DEBTRACE("ElementaryNode::ensureLoading: " << getName());
480 if(_state != YACS::READY)
482 setState(YACS::TOLOAD);
484 // request loading for all nodes connected to this one by datastream link
485 // Be careful that nodes can be connected in a loop. Put first this node in TOLOAD state to break the loop
486 std::list<OutputDataStreamPort *>::iterator iter;
487 for(iter = _setOfOutputDataStreamPort.begin(); iter != _setOfOutputDataStreamPort.end(); iter++)
489 OutputDataStreamPort *port=(OutputDataStreamPort *)*iter;
490 std::set<InPort *> ports=port->edSetInPort();
491 std::set<InPort *>::iterator iterout;
492 for(iterout=ports.begin();iterout != ports.end(); iterout++)
494 Node* node= (*iterout)->getNode();
495 node->ensureLoading();