Version: 9.15.0
ElementaryNode.cxx
Go to the documentation of this file.
1 // Copyright (C) 2006-2025 CEA, EDF
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 
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"
28 #include "Proc.hxx"
29 #include "Container.hxx"
30 #include <iostream>
31 #include <sstream>
32 
33 //#define _DEVDEBUG_
34 #include "YacsTrace.hxx"
35 
36 using namespace YACS::ENGINE;
37 using namespace std;
38 
47 ElementaryNode::ElementaryNode(const std::string& name):
48  Node(name),
49  _createDatastreamPorts(false),
50  _multi_port_node(false),
51  _weight()
52 {
54 }
55 
56 ElementaryNode::ElementaryNode(const ElementaryNode& other, ComposedNode *father):Node(other,father), _weight(other._weight)
57 {
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));
68 }
69 
71 {
72 }
73 
75 {
76 }
77 
79 {
80  for(list<InputPort *>::iterator iter1=_setOfInputPort.begin();iter1!=_setOfInputPort.end();iter1++)
81  delete *iter1;
82  for(list<OutputPort *>::iterator iter2=_setOfOutputPort.begin();iter2!=_setOfOutputPort.end();iter2++)
83  delete *iter2;
84  for(list<InputDataStreamPort *>::iterator iter3=_setOfInputDataStreamPort.begin();iter3!=_setOfInputDataStreamPort.end();iter3++)
85  delete *iter3;
86  for(list<OutputDataStreamPort *>::iterator iter4=_setOfOutputDataStreamPort.begin();iter4!=_setOfOutputDataStreamPort.end();iter4++)
87  delete *iter4;
88 }
89 
91 {
92  for(list<OutputPort *>::iterator iter=_setOfOutputPort.begin();iter!=_setOfOutputPort.end();iter++)
93  (*iter)->exInit();
94  for(list<InputPort *>::iterator iter2=_setOfInputPort.begin();iter2!=_setOfInputPort.end();iter2++)
95  (*iter2)->exInit(start);
96  _inGate.exReset();
97 }
98 
99 void ElementaryNode::init(bool start)
100 {
101  DEBTRACE("ElementaryNode::init " << getName() << " " << start << " " << _state);
103  if(_state == YACS::DISABLED)
104  {
105  exDisabledState(); // to refresh propagation of DISABLED state
106  return ;
107  }
109 }
110 
112 {
113  return false;
114 }
115 
117 {
118  return 0;
119 }
120 
122 {
123  return 0;
124 }
125 
127 {
128  return 0;
129 }
130 
132 {
133  return Node::getState();
134 }
135 
137 {
138  DEBTRACE("ElementaryNode::exUpdateState: " << getName() << " " << _state );
139  if(_state==YACS::DISABLED)return;
140  if(_inGate.exIsReady())
142  {
143  if(_state == YACS::READY)
144  ensureLoading();
145  else if(_state == YACS::LOADED)
147  }
148  else
149  {
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";
153  _errorDetails=what;
154  throw Exception(what);
155  }
156 }
157 
159 {
160  return _setOfInputPort.size();
161 }
162 
164 {
165  return _setOfOutputPort.size();
166 }
167 
168 InputPort *ElementaryNode::getInputPort(const std::string& name) const
169 {
170  try {
171  return Node::getInputPort(name);
172  }
173  catch(Exception& e) {}
174  return getPort<InputPort>(name,_setOfInputPort);
175 }
176 
177 OutputPort *ElementaryNode::getOutputPort(const std::string& name) const
178 {
179  return getPort<OutputPort>(name,_setOfOutputPort);
180 }
181 
183 {
184  set<OutPort *> ret;
185  list<OutPort *> temp=getSetOfOutPort();
186  for(list<OutPort *>::iterator iter2=temp.begin();iter2!=temp.end();iter2++)
187  {
188  set<InPort *> temp2=(*iter2)->edSetInPort();
189  if(temp2.size()!=0)
190  ret.insert(*iter2);
191  }
192  return ret;
193 }
194 
196 {
197  set<InPort *> ret;
198  list<InPort *> temp=getSetOfInPort();
199  for(list<InPort *>::iterator iter2=temp.begin();iter2!=temp.end();iter2++)
200  {
201  set<OutPort *> temp2=(*iter2)->edSetOutPort();
202  if(temp2.size()!=0)
203  ret.insert(*iter2);
204  }
205  return ret;
206 }
207 
208 std::vector< std::pair<OutPort *, InPort *> > ElementaryNode::getSetOfLinksLeavingCurrentScope() const
209 {
210  vector< pair<OutPort *, InPort *> > ret;
211  std::set<OutPort *> ports=getAllOutPortsLeavingCurrentScope();
212  for(set<OutPort *>::iterator iter2=ports.begin();iter2!=ports.end();iter2++)
213  {
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));
217  }
218  return ret;
219 }
220 
221 std::vector< std::pair<InPort *, OutPort *> > ElementaryNode::getSetOfLinksComingInCurrentScope() const
222 {
223  vector< pair<InPort *, OutPort *> > ret;
224  set<InPort *> ports=getAllInPortsComingFromOutsideOfCurrentScope();
225  for(set<InPort *>::iterator iter2=ports.begin();iter2!=ports.end();iter2++)
226  {
227  set<OutPort *> temp2=(*iter2)->edSetOutPort();
228  for(set<OutPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
229  {
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));
234  }
235  }
236  return ret;
237 }
238 
240 {
241  return getPort<InputDataStreamPort>(name,_setOfInputDataStreamPort);
242 }
243 
245 {
246  return getPort<OutputDataStreamPort>(name,_setOfOutputDataStreamPort);
247 }
248 
250 {
251  //CF
253  //Leaving part
254  // - DF
255  for(list<InputPort *>::iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
256  (*iter)->edRemoveAllLinksLinkedWithMe();
257  // - DS
258  for(list<InputDataStreamPort *>::iterator iter2=_setOfInputDataStreamPort.begin();iter2!=_setOfInputDataStreamPort.end();iter2++)
259  (*iter2)->edRemoveAllLinksLinkedWithMe();
260  //Arriving part
261  // - DF
262  for(list<OutputPort *>::iterator iter=_setOfOutputPort.begin();iter!=_setOfOutputPort.end();iter++)
263  (*iter)->edRemoveAllLinksLinkedWithMe();
264  // - DS
265  for(list<OutputDataStreamPort *>::iterator iter2=_setOfOutputDataStreamPort.begin();iter2!=_setOfOutputDataStreamPort.end();iter2++)
266  (*iter2)->edRemoveAllLinksLinkedWithMe();
267 }
268 
275 {
276  bool ret=true;
277  for(list<InputPort *>::const_iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
278  {
279  ret=!(*iter)->isEmpty();
280  if (!ret) break;
281  }
282  return ret;
283 }
284 
285 /*
286  This method is used by the "multi" property of ElementaryNode to create
287  to create duplicated input and ouput datastream ports.
288 */
289 void
291 {
293  {
294  _createDatastreamPorts = true;
295  for(list<InputDataStreamPort *>::const_iterator iter3 = _setOfInputDataStreamPort.begin(); iter3!=_setOfInputDataStreamPort.end();iter3++)
296  {
297  InputDataStreamPort * port = *iter3;
298  std::string port_name = port->getName();
299  std::map<std::string,std::string>::iterator it=_propertyMap.find(port_name);
300  int multi = 1;
301  if(it != _propertyMap.end())
302  {
303  std::string multi_str = it->second;
304  std::istringstream iss(multi_str);
305  if (!(iss >> multi))
306  throw Exception("Property multi port should be set with a stringified int not an: " + multi_str);
307  }
308 
309  if (multi > 1)
310  {
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++)
315  {
316  InputDataStreamPort * new_port = port->clone(this);
317  std::ostringstream number;
318  number << i-1;
319  new_port->setName(port_name + "_" + number.str());
320  _setOfInputDataStreamPort.push_back(new_port);
321  _multi_port_node = true;
322  }
323  }
324  }
325  for(list<OutputDataStreamPort *>::const_iterator iter4 = _setOfOutputDataStreamPort.begin(); iter4!=_setOfOutputDataStreamPort.end();iter4++)
326  {
327  OutputDataStreamPort * port = *iter4;
328  std::string port_name = port->getName();
329  std::map<std::string,std::string>::iterator it=_propertyMap.find(port_name);
330  int multi = 1;
331  if(it != _propertyMap.end())
332  {
333  std::string multi_str = it->second;
334  std::istringstream iss(multi_str);
335  if (!(iss >> multi))
336  throw Exception("Property multi port should be set with a stringified int not an: " + multi_str);
337  }
338 
339  if (multi > 1)
340  {
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++)
345  {
346  OutputDataStreamPort * new_port = port->clone(this);
347  std::ostringstream number;
348  number << i-1;
349  new_port->setName(port_name + "_" + number.str());
350  _setOfOutputDataStreamPort.push_back(new_port);
351  _multi_port_node = true;
352  }
353  }
354  }
355  }
356 }
357 
362 void ElementaryNode::getReadyTasks(std::vector<Task *>& tasks)
363 {
364  DEBTRACE("ElementaryNode::getReadyTasks: " << getName() << " " << _state);
365 
366  int multi = 1;
367  std::map<std::string,std::string>::iterator it=_propertyMap.find("multi");
368  if(it != _propertyMap.end())
369  {
370  std::string multi_str = it->second;
371  std::istringstream iss(multi_str);
372  if (!(iss >> multi))
373  throw Exception("Property multi should be set with a stringified int not an: " + multi_str);
374  }
375 
377  {
378  if (multi == 1)
379  {
380  std::map<std::string,std::string>::iterator it=_propertyMap.find("multi_working_dir");
381  if(it != _propertyMap.end())
382  {
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());
388  }
389  tasks.push_back(this);
390  }
391  else
392  {
393 
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++)
397  {
398  if ((*it_output)->isConnected())
399  {
400  throw Exception("Property multi cannot be set on nodes with dataflow output ports connected");
401  }
402  }
403 
404  // Add my instance
405  std::map<std::string,std::string>::iterator it=_propertyMap.find("multi_working_dir");
406  if(it != _propertyMap.end())
407  {
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());
413  }
414  tasks.push_back(this);
415 
416  // Step 1: Create clones
417  for (int i = 1; i < multi; i++)
418  {
419  // Clone
420  YACS::ENGINE::ElementaryNode * new_node = static_cast<YACS::ENGINE::ElementaryNode *>(clone(_father, false));
421  new_node->createMultiDatastreamPorts();
422 
423  // Change name
424  std::string iname;
425  std::stringstream inamess;
426  inamess << getName() << "_" << i;
427  iname=inamess.str();
428  DEBTRACE("Create clone "<< iname << " of node " << getName());
429  new_node->setName(iname);
430 
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++)
434  {
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 (auto itt : master_port->_backLinks)
439  {
440  // Connect dataflow
441  getProc()->edAddDFLink(itt.first,(*iter1));
442  }
443  }
444 
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++)
448  {
449  std::string port_name = (*iter)->getName();
450  InputDataStreamPort * orig_port = getInputDataStreamPort(port_name);
451 
452  std::set<OutputDataStreamPort *> connected_ports = orig_port->getConnectedOutputDataStreamPort();
453 
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++)
457  {
458  ElementaryNode * node = (ElementaryNode *) (*iter3)->getNode();
460 
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));
468  }
469  }
470 
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++)
474  {
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++)
479  {
480  ElementaryNode * dest_node = (ElementaryNode *)(*dest_port)->getNode();
481  // Add InputPort to dest node
482  dest_node->createMultiDatastreamPorts();
483 
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));
491  }
492  }
493 
494  // Init node
495  new_node->init(false);
496  new_node->exUpdateState();
497 
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));
502 
503  // Add clone
504  std::map<std::string,std::string>::iterator it=_propertyMap.find("multi_working_dir");
505  if(it != _propertyMap.end())
506  {
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());
512  }
513  tasks.push_back(new_node);
514  }
515  }
516  }
517 }
518 
524 {
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);
536  else
537  throw Exception("ElementaryNode::edRemovePort : unknown port type");
538  delete port;
539  modified();
540 }
541 
546 list<ElementaryNode *> ElementaryNode::getRecursiveConstituents() const
547 {
548  list<ElementaryNode *> ret;
549  ret.push_back((ElementaryNode *)this);
550  return ret;
551 }
552 
554 
558 list<ProgressWeight> ElementaryNode::getProgressWeight() const
559 {
560  list<ProgressWeight> ret;
561  ProgressWeight myWeight;
562  myWeight.weightTotal=1;
563  if (getState() == YACS::DONE)
564  myWeight.weightDone=1;
565  else
566  myWeight.weightDone=0;
567  ret.push_back(myWeight);
568  return ret;
569 }
570 
571 Node *ElementaryNode::getChildByName(const std::string& name) const
572 {
573  string what("ElementaryNode does not agregate any nodes particullary node with name "); what+=name;
574  throw Exception(what);
575 }
576 
578 {
579  DEBTRACE("ElementaryNode::checkBasicConsistency");
580  list<InputPort *>::const_iterator iter;
581  for(iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
582  (*iter)->checkBasicConsistency();
583 }
584 
586 {
587  for(ComposedNode *iter=_father;iter!=levelToStop && iter!=0; iter=iter->_father)
588  if(!iter->isPlacementPredictableB4Run())
589  return iter;
590  return 0;
591 }
592 
593 InputPort *ElementaryNode::createInputPort(const std::string& inputPortName, TypeCode* type)
594 {
595  return getRuntime()->createInputPort(inputPortName, _implementation, this, type);
596 }
597 
603 InputPort *ElementaryNode::edAddInputPort(const std::string& inputPortName, TypeCode* type)
604 {
605 
606  // Cannot create an InputPort defined with InPropertyPort name.
607  if (inputPortName == "__InPropertyPort__Node__YACS_")
608  {
609  string what("ElementaryNode::edAddInputPort: it is forbidden to add an InputPort with the name __InPropertyPort__Node__YACS_\"");
610  throw Exception(what);
611  }
612 
613  InputPort *ret = 0;
614  if (edCheckAddPort<InputPort, TypeCode*>(inputPortName,_setOfInputPort,type))
615  {
616  ret = createInputPort(inputPortName, type);
617  _setOfInputPort.push_back(ret);
618  modified();
619  /*
620  ComposedNode *iter=_father;
621  while(iter)
622  iter=iter->_father;
623  */
624  }
625  return ret;
626 }
627 
628 void ElementaryNode::edOrderInputPorts(const std::list<InputPort*>& ports)
629 {
630  std::set<InputPort *> s1;
631  std::set<InputPort *> s2;
632  for(list<InputPort *>::const_iterator it=_setOfInputPort.begin();it != _setOfInputPort.end();it++)
633  s1.insert(*it);
634  for(list<InputPort *>::const_iterator it=ports.begin();it != ports.end();it++)
635  s2.insert(*it);
636 
637  if(s1 != s2)
638  throw Exception("ElementaryNode::edOrderInputPorts : port list must contain same ports as existing ones");
639 
640  _setOfInputPort.clear();
641  for(list<InputPort *>::const_iterator it=ports.begin();it != ports.end();it++)
642  _setOfInputPort.push_back(*it);
643 }
644 
645 void ElementaryNode::edOrderOutputPorts(const std::list<OutputPort*>& ports)
646 {
647  std::set<OutputPort *> s1;
648  std::set<OutputPort *> s2;
649  for(list<OutputPort *>::const_iterator it=_setOfOutputPort.begin();it != _setOfOutputPort.end();it++)
650  s1.insert(*it);
651  for(list<OutputPort *>::const_iterator it=ports.begin();it != ports.end();it++)
652  s2.insert(*it);
653 
654  if(s1 != s2)
655  throw Exception("ElementaryNode::edOrderOutputPorts : port list must contain same ports as existing ones");
656 
657  _setOfOutputPort.clear();
658  for(list<OutputPort *>::const_iterator it=ports.begin();it != ports.end();it++)
659  _setOfOutputPort.push_back(*it);
660 }
661 
662 OutputPort *ElementaryNode::createOutputPort(const std::string& outputPortName, TypeCode* type)
663 {
664  return getRuntime()->createOutputPort(outputPortName, _implementation, this, type);
665 }
666 
672 OutputPort *ElementaryNode::edAddOutputPort(const std::string& outputPortName, TypeCode* type)
673 {
674  OutputPort *ret =0;
675  if (edCheckAddPort<OutputPort, TypeCode*>(outputPortName,_setOfOutputPort,type))
676  {
677  ret = createOutputPort(outputPortName, type);
678  _setOfOutputPort.push_back(ret);
679  modified();
680  /*
681  ComposedNode *iter=_father;
682  while(iter)
683  iter=iter->_father;
684  */
685  }
686  return ret;
687 }
688 
689 InputDataStreamPort *ElementaryNode::createInputDataStreamPort(const std::string& inputPortDSName, TypeCode* type)
690 {
691  return getRuntime()->createInputDataStreamPort(inputPortDSName, this, type);
692 }
693 
694 InputDataStreamPort *ElementaryNode::edAddInputDataStreamPort(const std::string& inputPortDSName, TypeCode* type)
695 {
696  InputDataStreamPort *ret = 0;
697  if (edCheckAddPort<InputDataStreamPort, TypeCode*>(inputPortDSName,_setOfInputDataStreamPort,type))
698  {
699  ret = createInputDataStreamPort(inputPortDSName, type);
700  _setOfInputDataStreamPort.push_back(ret);
701  modified();
702  }
703  return ret;
704 }
705 
707 {
708  return getRuntime()->createOutputDataStreamPort(outputPortDSName, this, type);
709 }
710 
711 OutputDataStreamPort *ElementaryNode::edAddOutputDataStreamPort(const std::string& outputPortDSName, TypeCode* type)
712 {
713  OutputDataStreamPort *ret = 0;
714  if (edCheckAddPort<OutputDataStreamPort, TypeCode*>(outputPortDSName,_setOfOutputDataStreamPort,type))
715  {
716  ret = createOutputDataStreamPort(outputPortDSName, type);
717  _setOfOutputDataStreamPort.push_back(ret);
718  modified();
719  }
720  return ret;
721 }
722 
727 string ElementaryNode::getInPortName(const InPort * inPort) const
728 {
729  Node *node = inPort->getNode();
730  if ( node != this )
731  {
732  string what("InputPort "); what += inPort->getName(); what += " does not belong to node "; what += node->getName();
733  throw Exception(what);
734  }
735  return inPort->getName();
736 }
737 
738 string ElementaryNode::getOutPortName(const OutPort *outPort) const
739 {
740  Node *node = outPort->getNode();
741  if ( node != this )
742  {
743  string what("OutputPort "); what += outPort->getName(); what += " does not belong to node "; what += node->getName();
744  throw Exception(what);
745  }
746  return outPort->getName();
747 }
748 
750 {
752 }
753 
755 {
756  return _state==TOACTIVATE;
757 }
758 
760 {
761  setState(DONE);
762 }
764 {
765  setState(ERROR);
766 }
767 
769 
775 {
776 }
777 
779 
785 {
786  if(_inGate.exIsReady())
788  {
790  return;
791  }
792  setState(LOADED);
793 }
794 
796 {
797  visitor->visitElementaryNode(this);
798 }
799 
801 
805 {
806  return _errorDetails;
807 }
808 
810 {
811  DEBTRACE("ElementaryNode::edUpdateState: " << getName());
813  try
814  {
816  _errorDetails="";
817  }
818  catch(Exception& e)
819  {
821  _errorDetails=e.what();
822  }
823  DEBTRACE("ElementaryNode::edUpdateState: " << _errorDetails);
824  if(state != _state)
825  setState(state);
826  _modified=0;
827 }
828 
830 
836 {
837  DEBTRACE("ElementaryNode::ensureLoading: " << getName());
838  if(_state != YACS::READY)
839  return;
841 
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++)
846  {
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++)
851  {
852  Node* node= (*iter)->getNode();
853  node->ensureLoading();
854  }
855  }
856  std::list<InputDataStreamPort *>::iterator iterin;
857  for(iterin = _setOfInputDataStreamPort.begin(); iterin != _setOfInputDataStreamPort.end(); iterin++)
858  {
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++)
863  {
864  Node* node= (*iter)->getNode();
865  node->ensureLoading();
866  }
867  }
868 }
869 
871 void ElementaryNode::getCoupledTasks(std::set<Task*>& coupledSet)
872 {
873  getCoupledNodes(coupledSet);
874 }
875 
877 void ElementaryNode::getCoupledNodes(std::set<Task*>& coupledSet)
878 {
879  if(coupledSet.find(this) != coupledSet.end())return;
880 
881  coupledSet.insert(this);
882 
883  std::list<OutputDataStreamPort *>::iterator iterout;
884  for(iterout = _setOfOutputDataStreamPort.begin(); iterout != _setOfOutputDataStreamPort.end(); iterout++)
885  {
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++)
890  {
891  Node* node= (*iter)->getNode();
892  node->getCoupledNodes(coupledSet);
893  }
894  }
895 }
896 
897 void ElementaryNode::setWeight(double elementaryWeight)
898 {
899  if(elementaryWeight<=0.)
900  throw Exception("ElementaryNode::setWeight : invalid input value !");
901  _weight.setElementaryWeight(elementaryWeight);
902 }
903 
#define DEBTRACE(msg)
Definition: YacsTrace.hxx:31
void setElementaryWeight(double elementaryWeight)
Base class for all component instances.
Base class for all composed nodes.
virtual bool edAddDFLink(OutPort *start, InPort *end)
Connect an OutPort to an InPort and add the necessary control link.
bool edAddLink(OutPort *start, InPort *end)
Add a dataflow link between two data ports.
virtual void setProperty(const std::string &name, const std::string &value)=0
void setName(std::string theName)
Definition: DataPort.hxx:56
std::string getName() const
Definition: DataPort.hxx:55
Base class for all calculation nodes.
void performDuplicationOfPlacement(const Node &other)
performs a duplication of placement using clone method of containers and components....
std::set< OutPort * > getAllOutPortsLeavingCurrentScope() const
virtual OutputDataStreamPort * edAddOutputDataStreamPort(const std::string &outputPortDSName, TypeCode *type)
virtual std::vector< std::pair< OutPort *, InPort * > > getSetOfLinksLeavingCurrentScope() const
void loaded()
Notify this node that it is loaded.
InputPort * getInputPort(const std::string &name) const
ComposedNode * getDynClonerIfExists(const ComposedNode *levelToStop) const
virtual InputDataStreamPort * createInputDataStreamPort(const std::string &inputPortDSName, TypeCode *type)
virtual void ensureLoading()
Put this node into TOLOAD state when possible.
std::list< ElementaryNode * > getRecursiveConstituents() const
virtual void getCoupledNodes(std::set< Task * > &coupledSet)
Put all nodes that are coupled to this node in coupledSet.
void connected()
Notify this node that it is connected.
OutputDataStreamPort * getOutputDataStreamPort(const std::string &name) const
OutputPort * getOutputPort(const std::string &name) const
std::list< InputPort * > _setOfInputPort
std::list< ProgressWeight > getProgressWeight() const
Get the progress weight for all elementary nodes.
void initCommonPartWithoutStateManagement(bool start)
virtual std::string getErrorDetails()
Give a description of error when node status is ERROR.
void accept(Visitor *visitor)
std::list< OutputDataStreamPort * > _setOfOutputDataStreamPort
virtual void addDatastreamPortToInitMultiService(const std::string &port_name, int number)
virtual std::vector< std::pair< InPort *, OutPort * > > getSetOfLinksComingInCurrentScope() const
std::string getOutPortName(const OutPort *) const
virtual OutputPort * createOutputPort(const std::string &outputPortName, TypeCode *type)
virtual InputPort * edAddInputPort(const std::string &inputPortName, TypeCode *type)
std::list< InputDataStreamPort * > _setOfInputDataStreamPort
std::list< InputPort * > getSetOfInputPort() const
std::list< OutputPort * > _setOfOutputPort
virtual InputDataStreamPort * edAddInputDataStreamPort(const std::string &inputPortDSName, TypeCode *type)
YACS::StatesForNode getState() const
virtual OutputDataStreamPort * createOutputDataStreamPort(const std::string &outputPortDSName, TypeCode *type)
std::list< InputDataStreamPort * > getSetOfInputDataStreamPort() const
void init(bool start=true)
void setWeight(double elementaryWeight)
virtual InputPort * createInputPort(const std::string &inputPortName, TypeCode *type)
InputDataStreamPort * getInputDataStreamPort(const std::string &name) const
virtual void edUpdateState()
update the status of the node
std::set< InPort * > getAllInPortsComingFromOutsideOfCurrentScope() const
virtual void createMultiDatastreamPorts()
std::list< OutputDataStreamPort * > getSetOfOutputDataStreamPort() const
void performShallowDuplicationOfPlacement(const Node &other)
performs a also duplication of placement but here containers and components are not copied at all wha...
virtual void edOrderInputPorts(const std::list< InputPort * > &ports)
Node * getChildByName(const std::string &name) const
void getReadyTasks(std::vector< Task * > &tasks)
void exUpdateState()
Update the node state.
virtual void edOrderOutputPorts(const std::list< OutputPort * > &ports)
virtual void checkBasicConsistency() const
std::string getInPortName(const InPort *) const
ComponentInstance * getComponent()
virtual void getCoupledTasks(std::set< Task * > &coupledSet)
Calls getCoupledNodes for Task interface.
virtual OutputPort * edAddOutputPort(const std::string &outputPortName, TypeCode *type)
std::list< OutGate * > getBackLinks()
Definition: InGate.cxx:134
bool exIsReady() const
Definition: InGate.cxx:126
void exNotifyFromPrecursor(OutGate *fromgate)
Notify this port that an upstream node connected by a control flow link is finished.
Definition: InGate.cxx:68
virtual std::set< OutPort * > edSetOutPort() const
Returns physical backlinks NOT user backlinks.
Definition: InPort.cxx:65
std::set< std::pair< OutPort *, bool > > _backLinks
Definition: InPort.hxx:78
virtual InputDataStreamPort * clone(Node *newHelder) const
std::set< OutputDataStreamPort * > getConnectedOutputDataStreamPort()
Base class for Input Ports.
Definition: InputPort.hxx:44
Base class for all nodes.
Definition: Node.hxx:70
std::string _name
Definition: Node.hxx:89
ComposedNode * _father
Definition: Node.hxx:90
InGate _inGate
Definition: Node.hxx:86
friend class ElementaryNode
Definition: Node.hxx:80
virtual void getCoupledNodes(std::set< Task * > &coupledNodes)
Definition: Node.hxx:199
virtual void modified()
Sets Node in modified state and its father if it exists.
Definition: Node.cxx:805
void setName(const std::string &name)
Change the name of the node.
Definition: Node.cxx:162
Node * clone(ComposedNode *father, bool editionOnly=true) const
This method MUST NEVER BE VIRTUAL
Definition: Node.cxx:131
std::map< std::string, std::string > _propertyMap
Definition: Node.hxx:98
std::list< OutPort * > getSetOfOutPort() const
Definition: Node.cxx:299
std::list< InPort * > getSetOfInPort() const
Definition: Node.cxx:289
void setState(YACS::StatesForNode theState)
Sets the given state for node.
Definition: Node.cxx:652
std::string _implementation
Definition: Node.hxx:97
virtual void exDisabledState()
Notify this node that it has been disabled.
Definition: Node.cxx:232
InGate * getInGate()
Definition: Node.hxx:123
virtual YACS::StatesForNode getState() const
Definition: Node.hxx:118
const std::string & getName() const
Definition: Node.hxx:125
virtual InputPort * getInputPort(const std::string &name) const
Definition: Node.cxx:260
virtual void ensureLoading()
Put this node into TOLOAD state when possible.
Definition: Node.cxx:817
std::string _errorDetails
Definition: Node.hxx:93
YACS::StatesForNode _state
Definition: Node.hxx:91
virtual Proc * getProc()
Definition: Node.cxx:401
virtual void edDisconnectAllLinksWithMe()
Definition: Node.cxx:395
std::set< InputDataStreamPort * > _setOfInputDataStreamPort
virtual OutputDataStreamPort * clone(Node *newHelder) const
std::set< InPort * > edSetInPort() const
Base class for all ports.
Definition: Port.hxx:43
Node * getNode() const
Definition: Port.hxx:46
virtual InputPort * createInputPort(const std::string &name, const std::string &impl, Node *node, TypeCode *type)=0
virtual OutputPort * createOutputPort(const std::string &name, const std::string &impl, Node *node, TypeCode *type)=0
virtual InputDataStreamPort * createInputDataStreamPort(const std::string &name, Node *node, TypeCode *type)
Definition: Runtime.cxx:269
virtual OutputDataStreamPort * createOutputDataStreamPort(const std::string &name, Node *node, TypeCode *type)
Definition: Runtime.cxx:274
Base class for all type objects.
Definition: TypeCode.hxx:68
virtual void visitElementaryNode(ElementaryNode *node)=0
const char * what(void) const noexcept
Definition: Exception.cxx:50
Proc * p
Definition: driver.cxx:216
YACSLIBENGINE_EXPORT Runtime * getRuntime()
Definition: Runtime.cxx:61
StatesForNode
Definition: define.hxx:34
@ INVALID
Definition: define.hxx:36
@ TOLOAD
Definition: define.hxx:38
@ LOADED
Definition: define.hxx:39
@ READY
Definition: define.hxx:37
@ ACTIVATED
Definition: define.hxx:41
@ INTERNALERR
Definition: define.hxx:49
@ DONE
Definition: define.hxx:43
@ TOACTIVATE
Definition: define.hxx:40
@ DISABLED
Definition: define.hxx:50
@ TORECONNECT
Definition: define.hxx:48
@ ERROR
Definition: define.hxx:52