1 // Copyright (C) 2006-2019 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "ElementaryNode.hxx"
21 #include "Runtime.hxx"
22 #include "InputPort.hxx"
23 #include "OutputPort.hxx"
24 #include "ComposedNode.hxx"
25 #include "InputDataStreamPort.hxx"
26 #include "OutputDataStreamPort.hxx"
27 #include "Visitor.hxx"
29 #include "Container.hxx"
34 #include "YacsTrace.hxx"
36 using namespace YACS::ENGINE;
39 /*! \class YACS::ENGINE::ElementaryNode
40 * \brief Base class for all calculation nodes.
42 * This is an abstract class that must be specialized.
47 ElementaryNode::ElementaryNode(const std::string& name):
49 _createDatastreamPorts(false),
50 _multi_port_node(false),
53 _weight.setDefaultElementary();
56 ElementaryNode::ElementaryNode(const ElementaryNode& other, ComposedNode *father):Node(other,father), _weight(other._weight)
58 _createDatastreamPorts = other._createDatastreamPorts;
59 _multi_port_node = other._multi_port_node;
60 for(list<InputPort *>::const_iterator iter1=other._setOfInputPort.begin();iter1!=other._setOfInputPort.end();iter1++)
61 _setOfInputPort.push_back((InputPort *)(*iter1)->clone(this));
62 for(list<OutputPort *>::const_iterator iter2=other._setOfOutputPort.begin();iter2!=other._setOfOutputPort.end();iter2++)
63 _setOfOutputPort.push_back((OutputPort *)(*iter2)->clone(this));
64 for(list<InputDataStreamPort *>::const_iterator iter3=other._setOfInputDataStreamPort.begin();iter3!=other._setOfInputDataStreamPort.end();iter3++)
65 _setOfInputDataStreamPort.push_back((InputDataStreamPort *)(*iter3)->clone(this));
66 for(list<OutputDataStreamPort *>::const_iterator iter4=other._setOfOutputDataStreamPort.begin();iter4!=other._setOfOutputDataStreamPort.end();iter4++)
67 _setOfOutputDataStreamPort.push_back((OutputDataStreamPort *)(*iter4)->clone(this));
70 void ElementaryNode::performDuplicationOfPlacement(const Node& other)
74 void ElementaryNode::performShallowDuplicationOfPlacement(const Node& other)
78 ElementaryNode::~ElementaryNode()
80 for(list<InputPort *>::iterator iter1=_setOfInputPort.begin();iter1!=_setOfInputPort.end();iter1++)
82 for(list<OutputPort *>::iterator iter2=_setOfOutputPort.begin();iter2!=_setOfOutputPort.end();iter2++)
84 for(list<InputDataStreamPort *>::iterator iter3=_setOfInputDataStreamPort.begin();iter3!=_setOfInputDataStreamPort.end();iter3++)
86 for(list<OutputDataStreamPort *>::iterator iter4=_setOfOutputDataStreamPort.begin();iter4!=_setOfOutputDataStreamPort.end();iter4++)
90 void ElementaryNode::initCommonPartWithoutStateManagement(bool start)
92 for(list<OutputPort *>::iterator iter=_setOfOutputPort.begin();iter!=_setOfOutputPort.end();iter++)
94 for(list<InputPort *>::iterator iter2=_setOfInputPort.begin();iter2!=_setOfInputPort.end();iter2++)
95 (*iter2)->exInit(start);
99 void ElementaryNode::init(bool start)
101 DEBTRACE("ElementaryNode::init " << getName() << " " << start << " " << _state);
102 initCommonPartWithoutStateManagement(start);
103 if(_state == YACS::DISABLED)
105 exDisabledState(); // to refresh propagation of DISABLED state
108 setState(YACS::READY);
111 bool ElementaryNode::isDeployable() const
116 ComponentInstance *ElementaryNode::getComponent()
121 const ComponentInstance *ElementaryNode::getComponent() const
126 Container *ElementaryNode::getContainer()
131 YACS::StatesForNode ElementaryNode::getState() const
133 return Node::getState();
136 void ElementaryNode::exUpdateState()
138 DEBTRACE("ElementaryNode::exUpdateState: " << getName() << " " << _state );
139 if(_state==YACS::DISABLED)return;
140 if(_inGate.exIsReady())
141 if(areAllInputPortsValid())
143 if(_state == YACS::READY)
145 else if(_state == YACS::LOADED)
146 setState(YACS::TOACTIVATE);
150 string what("ElementaryNode::exUpdateState : Invalid graph given : Node with name \"");
151 what+=_name; what+="\" ready to run whereas some inputports are not set correctly\nCheck coherence DF/CF";
152 setState(YACS::INTERNALERR);
154 throw Exception(what);
158 int ElementaryNode::getNumberOfInputPorts() const
160 return _setOfInputPort.size();
163 int ElementaryNode::getNumberOfOutputPorts() const
165 return _setOfOutputPort.size();
168 InputPort *ElementaryNode::getInputPort(const std::string& name) const throw(YACS::Exception)
171 return Node::getInputPort(name);
173 catch(Exception& e) {}
174 return getPort<InputPort>(name,_setOfInputPort);
177 OutputPort *ElementaryNode::getOutputPort(const std::string& name) const throw(YACS::Exception)
179 return getPort<OutputPort>(name,_setOfOutputPort);
182 std::set<OutPort *> ElementaryNode::getAllOutPortsLeavingCurrentScope() const
185 list<OutPort *> temp=getSetOfOutPort();
186 for(list<OutPort *>::iterator iter2=temp.begin();iter2!=temp.end();iter2++)
188 set<InPort *> temp2=(*iter2)->edSetInPort();
195 std::set<InPort *> ElementaryNode::getAllInPortsComingFromOutsideOfCurrentScope() const
198 list<InPort *> temp=getSetOfInPort();
199 for(list<InPort *>::iterator iter2=temp.begin();iter2!=temp.end();iter2++)
201 set<OutPort *> temp2=(*iter2)->edSetOutPort();
208 std::vector< std::pair<OutPort *, InPort *> > ElementaryNode::getSetOfLinksLeavingCurrentScope() const
210 vector< pair<OutPort *, InPort *> > ret;
211 std::set<OutPort *> ports=getAllOutPortsLeavingCurrentScope();
212 for(set<OutPort *>::iterator iter2=ports.begin();iter2!=ports.end();iter2++)
214 set<InPort *> temp2=(*iter2)->edSetInPort();
215 for(set<InPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
216 ret.push_back(pair<OutPort *, InPort *>(*iter2,*iter3));
221 std::vector< std::pair<InPort *, OutPort *> > ElementaryNode::getSetOfLinksComingInCurrentScope() const
223 vector< pair<InPort *, OutPort *> > ret;
224 set<InPort *> ports=getAllInPortsComingFromOutsideOfCurrentScope();
225 for(set<InPort *>::iterator iter2=ports.begin();iter2!=ports.end();iter2++)
227 set<OutPort *> temp2=(*iter2)->edSetOutPort();
228 for(set<OutPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
230 std::set<OutPort *> trueOutPorts;
231 (*iter3)->getAllRepresented(trueOutPorts);
232 for(std::set<OutPort *>::iterator iter4=trueOutPorts.begin();iter4!=trueOutPorts.end();++iter4)
233 ret.push_back(pair<InPort *, OutPort *>(*iter2,*iter4));
239 InputDataStreamPort *ElementaryNode::getInputDataStreamPort(const std::string& name) const throw(YACS::Exception)
241 return getPort<InputDataStreamPort>(name,_setOfInputDataStreamPort);
244 OutputDataStreamPort *ElementaryNode::getOutputDataStreamPort(const std::string& name) const throw(YACS::Exception)
246 return getPort<OutputDataStreamPort>(name,_setOfOutputDataStreamPort);
249 void ElementaryNode::edDisconnectAllLinksWithMe()
252 Node::edDisconnectAllLinksWithMe();
255 for(list<InputPort *>::iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
256 (*iter)->edRemoveAllLinksLinkedWithMe();
258 for(list<InputDataStreamPort *>::iterator iter2=_setOfInputDataStreamPort.begin();iter2!=_setOfInputDataStreamPort.end();iter2++)
259 (*iter2)->edRemoveAllLinksLinkedWithMe();
262 for(list<OutputPort *>::iterator iter=_setOfOutputPort.begin();iter!=_setOfOutputPort.end();iter++)
263 (*iter)->edRemoveAllLinksLinkedWithMe();
265 for(list<OutputDataStreamPort *>::iterator iter2=_setOfOutputDataStreamPort.begin();iter2!=_setOfOutputDataStreamPort.end();iter2++)
266 (*iter2)->edRemoveAllLinksLinkedWithMe();
270 * checks if all input ports contains a valid data. Used at execution to change the state of the node
274 bool ElementaryNode::areAllInputPortsValid() const
277 for(list<InputPort *>::const_iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
279 ret=!(*iter)->isEmpty();
286 This method is used by the "multi" property of ElementaryNode to create
287 to create duplicated input and ouput datastream ports.
290 ElementaryNode::createMultiDatastreamPorts()
292 if (!_createDatastreamPorts)
294 _createDatastreamPorts = true;
295 for(list<InputDataStreamPort *>::const_iterator iter3 = _setOfInputDataStreamPort.begin(); iter3!=_setOfInputDataStreamPort.end();iter3++)
297 InputDataStreamPort * port = *iter3;
298 std::string port_name = port->getName();
299 std::map<std::string,std::string>::iterator it=_propertyMap.find(port_name);
301 if(it != _propertyMap.end())
303 std::string multi_str = it->second;
304 std::istringstream iss(multi_str);
306 throw Exception("Property multi port should be set with a stringified int not an: " + multi_str);
311 addDatastreamPortToInitMultiService(port_name, multi);
312 // Change name of first port
313 port->setName(port_name + "_0");
314 for (int i = 2; i <= multi; i++)
316 InputDataStreamPort * new_port = port->clone(this);
317 std::ostringstream number;
319 new_port->setName(port_name + "_" + number.str());
320 _setOfInputDataStreamPort.push_back(new_port);
321 _multi_port_node = true;
325 for(list<OutputDataStreamPort *>::const_iterator iter4 = _setOfOutputDataStreamPort.begin(); iter4!=_setOfOutputDataStreamPort.end();iter4++)
327 OutputDataStreamPort * port = *iter4;
328 std::string port_name = port->getName();
329 std::map<std::string,std::string>::iterator it=_propertyMap.find(port_name);
331 if(it != _propertyMap.end())
333 std::string multi_str = it->second;
334 std::istringstream iss(multi_str);
336 throw Exception("Property multi port should be set with a stringified int not an: " + multi_str);
341 addDatastreamPortToInitMultiService(port_name, multi);
342 // Change name of first port
343 port->setName(port_name + "_0");
344 for (int i = 2; i <= multi; i++)
346 OutputDataStreamPort * new_port = port->clone(this);
347 std::ostringstream number;
349 new_port->setName(port_name + "_" + number.str());
350 _setOfOutputDataStreamPort.push_back(new_port);
351 _multi_port_node = true;
359 * add this node task to a given set of ready tasks, if this task is ready to activate
362 void ElementaryNode::getReadyTasks(std::vector<Task *>& tasks)
364 DEBTRACE("ElementaryNode::getReadyTasks: " << getName() << " " << _state);
367 std::map<std::string,std::string>::iterator it=_propertyMap.find("multi");
368 if(it != _propertyMap.end())
370 std::string multi_str = it->second;
371 std::istringstream iss(multi_str);
373 throw Exception("Property multi should be set with a stringified int not an: " + multi_str);
376 if(_state==YACS::TOACTIVATE || _state==YACS::TOLOAD || _state==YACS::TORECONNECT)
380 std::map<std::string,std::string>::iterator it=_propertyMap.find("multi_working_dir");
381 if(it != _propertyMap.end())
383 std::string working_dir_base = it->second;
384 std::ostringstream working_dir_stream;
385 working_dir_stream << working_dir_base;
386 working_dir_stream << 1;
387 this->getContainer()->setProperty("workingdir", working_dir_stream.str());
389 tasks.push_back(this);
394 // Check output port -> cannot clone an Elementary Node with Output Ports connected
395 std::list<OutputPort *>::iterator it_output = _setOfOutputPort.begin();
396 for (;it_output != _setOfOutputPort.end(); it_output++)
398 if ((*it_output)->isConnected())
400 throw Exception("Property multi cannot be set on nodes with dataflow output ports connected");
405 std::map<std::string,std::string>::iterator it=_propertyMap.find("multi_working_dir");
406 if(it != _propertyMap.end())
408 std::string working_dir_base = it->second;
409 std::ostringstream working_dir_stream;
410 working_dir_stream << working_dir_base;
411 working_dir_stream << 1;
412 this->getContainer()->setProperty("workingdir", working_dir_stream.str());
414 tasks.push_back(this);
416 // Step 1: Create clones
417 for (int i = 1; i < multi; i++)
420 YACS::ENGINE::ElementaryNode * new_node = static_cast<YACS::ENGINE::ElementaryNode *>(clone(_father, false));
421 new_node->createMultiDatastreamPorts();
425 std::stringstream inamess;
426 inamess << getName() << "_" << i;
428 DEBTRACE("Create clone "<< iname << " of node " << getName());
429 new_node->setName(iname);
431 // For each input port connect it with the original output port
432 std::list<InputPort *> clone_list_inputPorts = new_node->getSetOfInputPort();
433 for(list<InputPort *>::const_iterator iter1=clone_list_inputPorts.begin(); iter1!=clone_list_inputPorts.end(); iter1++)
435 std::string input_port_name = (*iter1)->getName();
436 // Get Port Name in master node
437 InputPort * master_port = getInputPort(input_port_name);
438 for (std::set<OutPort *>::const_iterator itt=master_port->_backLinks.begin(); itt!=master_port->_backLinks.end();itt++)
441 getProc()->edAddDFLink((*itt),(*iter1));
445 // InputDataStreamPort connections
446 std::list<InputDataStreamPort *> clone_list_inputDatastreamPorts = new_node->getSetOfInputDataStreamPort();
447 for(list<InputDataStreamPort *>::iterator iter = clone_list_inputDatastreamPorts.begin(); iter != clone_list_inputDatastreamPorts.end(); iter++)
449 std::string port_name = (*iter)->getName();
450 InputDataStreamPort * orig_port = getInputDataStreamPort(port_name);
452 std::set<OutputDataStreamPort *> connected_ports = orig_port->getConnectedOutputDataStreamPort();
454 // Create datastream ports if not created
455 std::set<OutputDataStreamPort *>::const_iterator iter3;
456 for(iter3=connected_ports.begin();iter3!=connected_ports.end();iter3++)
458 ElementaryNode * node = (ElementaryNode *) (*iter3)->getNode();
459 node->createMultiDatastreamPorts();
461 std::string good_port_name;
462 std::stringstream temp_name;
463 std::string out_name = (*iter3)->getName();
464 out_name.erase(out_name.end()-1);
465 temp_name << out_name << i;
466 good_port_name = temp_name.str();
467 getProc()->edAddLink(node->getOutputDataStreamPort(good_port_name), (*iter));
471 // OutputDataStreamPort connections
472 std::list<OutputDataStreamPort *> clone_list_outputDatastreamPorts = new_node->getSetOfOutputDataStreamPort();
473 for(list<OutputDataStreamPort *>::iterator iter = clone_list_outputDatastreamPorts.begin(); iter != clone_list_outputDatastreamPorts.end(); iter++)
475 std::string port_name = (*iter)->getName();
476 OutputDataStreamPort * orig_port = getOutputDataStreamPort(port_name);
477 std::set<InputDataStreamPort *> dest_input_port = orig_port->_setOfInputDataStreamPort;
478 for(set<InputDataStreamPort *>::iterator dest_port = dest_input_port.begin(); dest_port != dest_input_port.end(); dest_port++)
480 ElementaryNode * dest_node = (ElementaryNode *)(*dest_port)->getNode();
481 // Add InputPort to dest node
482 dest_node->createMultiDatastreamPorts();
484 std::string good_port_name;
485 std::stringstream temp_name;
486 std::string in_name = (*dest_port)->getName();
487 in_name.erase(in_name.end()-1);
488 temp_name << in_name << i;
489 good_port_name = temp_name.str();
490 getProc()->edAddLink((*iter), dest_node->getInputDataStreamPort(good_port_name));
495 new_node->init(false);
496 new_node->exUpdateState();
498 // Set Control Link to done
499 std::list<OutGate *> clone_cl_back = new_node->getInGate()->getBackLinks();
500 for(std::list<OutGate *>::const_iterator iter=clone_cl_back.begin(); iter!=clone_cl_back.end(); iter++)
501 new_node->getInGate()->exNotifyFromPrecursor((*iter));
504 std::map<std::string,std::string>::iterator it=_propertyMap.find("multi_working_dir");
505 if(it != _propertyMap.end())
507 std::string working_dir_base = it->second;
508 std::ostringstream working_dir_stream;
509 working_dir_stream << working_dir_base;
510 working_dir_stream << i+1;
511 new_node->getContainer()->setProperty("workingdir", working_dir_stream.str());
513 tasks.push_back(new_node);
520 * remove port from node at edition. Ports are typed.
523 void ElementaryNode::edRemovePort(Port *port) throw(YACS::Exception)
525 DEBTRACE("ElementaryNode::edRemovePort ");
526 if(port->getNode()!=this)
527 throw Exception("ElementaryNode::edRemovePort : Port is not held by this node");
528 if(InputPort *p=dynamic_cast<InputPort *>(port))
529 edRemovePortTypedFromSet<InputPort>(p,_setOfInputPort);
530 else if(OutputPort *p=dynamic_cast<OutputPort *>(port))
531 edRemovePortTypedFromSet<OutputPort>(p,_setOfOutputPort);
532 else if(InputDataStreamPort *p=dynamic_cast<InputDataStreamPort *>(port))
533 edRemovePortTypedFromSet<InputDataStreamPort>(p,_setOfInputDataStreamPort);
534 else if(OutputDataStreamPort *p=dynamic_cast<OutputDataStreamPort *>(port))
535 edRemovePortTypedFromSet<OutputDataStreamPort>(p,_setOfOutputDataStreamPort);
537 throw Exception("ElementaryNode::edRemovePort : unknown port type");
543 * @return a set with only this node. (Same method in composed nodes)
546 list<ElementaryNode *> ElementaryNode::getRecursiveConstituents() const
548 list<ElementaryNode *> ret;
549 ret.push_back((ElementaryNode *)this);
553 //! Get the progress weight for all elementary nodes
555 * Only elementary nodes have weight. At this stage weight is 0 or 1 (it can be modified later following
556 * the kind of father)
558 list<ProgressWeight> ElementaryNode::getProgressWeight() const
560 list<ProgressWeight> ret;
561 ProgressWeight myWeight;
562 myWeight.weightTotal=1;
563 if (getState() == YACS::DONE)
564 myWeight.weightDone=1;
566 myWeight.weightDone=0;
567 ret.push_back(myWeight);
571 Node *ElementaryNode::getChildByName(const std::string& name) const throw(YACS::Exception)
573 string what("ElementaryNode does not agregate any nodes particullary node with name "); what+=name;
574 throw Exception(what);
577 void ElementaryNode::checkBasicConsistency() const throw(YACS::Exception)
579 DEBTRACE("ElementaryNode::checkBasicConsistency");
580 list<InputPort *>::const_iterator iter;
581 for(iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
582 (*iter)->checkBasicConsistency();
585 ComposedNode *ElementaryNode::getDynClonerIfExists(const ComposedNode *levelToStop) const
587 for(ComposedNode *iter=_father;iter!=levelToStop && iter!=0; iter=iter->_father)
588 if(!iter->isPlacementPredictableB4Run())
593 InputPort *ElementaryNode::createInputPort(const std::string& inputPortName, TypeCode* type)
595 return getRuntime()->createInputPort(inputPortName, _implementation, this, type);
599 * the input port is also published recursively in ancestors because it may be visible from everywhere.
600 * WARNING: CHECK CASE OF BLOC: ONLY INPUT PORTS NOT INTERNALLY CONNECTED MUST BE VISIBLE.
603 InputPort *ElementaryNode::edAddInputPort(const std::string& inputPortName, TypeCode* type) throw(YACS::Exception)
606 // Cannot create an InputPort defined with InPropertyPort name.
607 if (inputPortName == "__InPropertyPort__Node__YACS_")
609 string what("ElementaryNode::edAddInputPort: it is forbidden to add an InputPort with the name __InPropertyPort__Node__YACS_\"");
610 throw Exception(what);
614 if (edCheckAddPort<InputPort, TypeCode*>(inputPortName,_setOfInputPort,type))
616 ret = createInputPort(inputPortName, type);
617 _setOfInputPort.push_back(ret);
620 ComposedNode *iter=_father;
628 void ElementaryNode::edOrderInputPorts(const std::list<InputPort*>& ports)
630 std::set<InputPort *> s1;
631 std::set<InputPort *> s2;
632 for(list<InputPort *>::const_iterator it=_setOfInputPort.begin();it != _setOfInputPort.end();it++)
634 for(list<InputPort *>::const_iterator it=ports.begin();it != ports.end();it++)
638 throw Exception("ElementaryNode::edOrderInputPorts : port list must contain same ports as existing ones");
640 _setOfInputPort.clear();
641 for(list<InputPort *>::const_iterator it=ports.begin();it != ports.end();it++)
642 _setOfInputPort.push_back(*it);
645 void ElementaryNode::edOrderOutputPorts(const std::list<OutputPort*>& ports)
647 std::set<OutputPort *> s1;
648 std::set<OutputPort *> s2;
649 for(list<OutputPort *>::const_iterator it=_setOfOutputPort.begin();it != _setOfOutputPort.end();it++)
651 for(list<OutputPort *>::const_iterator it=ports.begin();it != ports.end();it++)
655 throw Exception("ElementaryNode::edOrderOutputPorts : port list must contain same ports as existing ones");
657 _setOfOutputPort.clear();
658 for(list<OutputPort *>::const_iterator it=ports.begin();it != ports.end();it++)
659 _setOfOutputPort.push_back(*it);
662 OutputPort *ElementaryNode::createOutputPort(const std::string& outputPortName, TypeCode* type)
664 return getRuntime()->createOutputPort(outputPortName, _implementation, this, type);
668 * TO SOLVE : The output port is not published in father. Father must create an output port.
669 * for now, publication is done the same way as input ports
672 OutputPort *ElementaryNode::edAddOutputPort(const std::string& outputPortName, TypeCode* type) throw(YACS::Exception)
675 if (edCheckAddPort<OutputPort, TypeCode*>(outputPortName,_setOfOutputPort,type))
677 ret = createOutputPort(outputPortName, type);
678 _setOfOutputPort.push_back(ret);
681 ComposedNode *iter=_father;
689 InputDataStreamPort *ElementaryNode::createInputDataStreamPort(const std::string& inputPortDSName, TypeCode* type)
691 return getRuntime()->createInputDataStreamPort(inputPortDSName, this, type);
694 InputDataStreamPort *ElementaryNode::edAddInputDataStreamPort(const std::string& inputPortDSName, TypeCode* type) throw(YACS::Exception)
696 InputDataStreamPort *ret = 0;
697 if (edCheckAddPort<InputDataStreamPort, TypeCode*>(inputPortDSName,_setOfInputDataStreamPort,type))
699 ret = createInputDataStreamPort(inputPortDSName, type);
700 _setOfInputDataStreamPort.push_back(ret);
706 OutputDataStreamPort *ElementaryNode::createOutputDataStreamPort(const std::string& outputPortDSName, TypeCode* type)
708 return getRuntime()->createOutputDataStreamPort(outputPortDSName, this, type);
711 OutputDataStreamPort *ElementaryNode::edAddOutputDataStreamPort(const std::string& outputPortDSName, TypeCode* type) throw(YACS::Exception)
713 OutputDataStreamPort *ret = 0;
714 if (edCheckAddPort<OutputDataStreamPort, TypeCode*>(outputPortDSName,_setOfOutputDataStreamPort,type))
716 ret = createOutputDataStreamPort(outputPortDSName, type);
717 _setOfOutputDataStreamPort.push_back(ret);
724 * get the input port name used by the current node (see composed nodes)
727 string ElementaryNode::getInPortName(const InPort * inPort) const throw(YACS::Exception)
729 Node *node = inPort->getNode();
732 string what("InputPort "); what += inPort->getName(); what += " does not belong to node "; what += node->getName();
733 throw Exception(what);
735 return inPort->getName();
738 string ElementaryNode::getOutPortName(const OutPort *outPort) const throw(YACS::Exception)
740 Node *node = outPort->getNode();
743 string what("OutputPort "); what += outPort->getName(); what += " does not belong to node "; what += node->getName();
744 throw Exception(what);
746 return outPort->getName();
749 void ElementaryNode::begin()
754 bool ElementaryNode::isReady()
756 return _state==TOACTIVATE;
759 void ElementaryNode::finished()
763 void ElementaryNode::aborted()
768 //! Notify this node that it is loaded
770 * When an elementary node has been loaded
771 * It is ready to be connected
774 void ElementaryNode::loaded()
778 //! Notify this node that it is connected
780 * When an elementary node has been connected it goes to TOACTIVATE state
781 * It is then ready to be executed
784 void ElementaryNode::connected()
786 if(_inGate.exIsReady())
787 if(areAllInputPortsValid())
789 setState(TOACTIVATE);
795 void ElementaryNode::accept(Visitor *visitor)
797 visitor->visitElementaryNode(this);
800 //! Give a description of error when node status is ERROR
804 std::string ElementaryNode::getErrorDetails()
806 return _errorDetails;
809 void ElementaryNode::edUpdateState()
811 DEBTRACE("ElementaryNode::edUpdateState: " << getName());
812 YACS::StatesForNode state=YACS::READY;
815 checkBasicConsistency();
821 _errorDetails=e.what();
823 DEBTRACE("ElementaryNode::edUpdateState: " << _errorDetails);
829 //! Put this node into TOLOAD state when possible
831 * Can be called by another ElementaryNode that is connected to this one by a datastream link
832 * These 2 nodes must be loaded at the same time as they are coupled
833 * It's the other node which requests this node loading
835 void ElementaryNode::ensureLoading()
837 DEBTRACE("ElementaryNode::ensureLoading: " << getName());
838 if(_state != YACS::READY)
840 setState(YACS::TOLOAD);
842 // request loading for all nodes connected to this one by datastream link
843 // Be careful that nodes can be connected in a loop. Put first this node in TOLOAD state to break the loop
844 std::list<OutputDataStreamPort *>::iterator iterout;
845 for(iterout = _setOfOutputDataStreamPort.begin(); iterout != _setOfOutputDataStreamPort.end(); iterout++)
847 OutputDataStreamPort *port=(OutputDataStreamPort *)*iterout;
848 std::set<InPort *> ports=port->edSetInPort();
849 std::set<InPort *>::iterator iter;
850 for(iter=ports.begin();iter != ports.end(); iter++)
852 Node* node= (*iter)->getNode();
853 node->ensureLoading();
856 std::list<InputDataStreamPort *>::iterator iterin;
857 for(iterin = _setOfInputDataStreamPort.begin(); iterin != _setOfInputDataStreamPort.end(); iterin++)
859 InputDataStreamPort *port=(InputDataStreamPort *)*iterin;
860 std::set<OutPort *> ports=port->edSetOutPort();
861 std::set<OutPort *>::iterator iter;
862 for(iter=ports.begin();iter != ports.end(); iter++)
864 Node* node= (*iter)->getNode();
865 node->ensureLoading();
870 //! Calls getCoupledNodes for Task interface
871 void ElementaryNode::getCoupledTasks(std::set<Task*>& coupledSet)
873 getCoupledNodes(coupledSet);
876 //! Put all nodes that are coupled to this node in coupledSet
877 void ElementaryNode::getCoupledNodes(std::set<Task*>& coupledSet)
879 if(coupledSet.find(this) != coupledSet.end())return;
881 coupledSet.insert(this);
883 std::list<OutputDataStreamPort *>::iterator iterout;
884 for(iterout = _setOfOutputDataStreamPort.begin(); iterout != _setOfOutputDataStreamPort.end(); iterout++)
886 OutputDataStreamPort *port=(OutputDataStreamPort *)*iterout;
887 std::set<InPort *> ports=port->edSetInPort();
888 std::set<InPort *>::iterator iter;
889 for(iter=ports.begin();iter != ports.end(); iter++)
891 Node* node= (*iter)->getNode();
892 node->getCoupledNodes(coupledSet);
897 void ElementaryNode::setWeight(double elementaryWeight)
899 if(elementaryWeight<=0.)
900 throw Exception("ElementaryNode::setWeight : invalid input value !");
901 _weight.setElementaryWeight(elementaryWeight);