Version: 8.3.0
ElementaryNode.cxx
Go to the documentation of this file.
1 // Copyright (C) 2006-2016 CEA/DEN, EDF R&D
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 {
52 }
53 
54 ElementaryNode::ElementaryNode(const ElementaryNode& other, ComposedNode *father):Node(other,father)
55 {
58  for(list<InputPort *>::const_iterator iter1=other._setOfInputPort.begin();iter1!=other._setOfInputPort.end();iter1++)
59  _setOfInputPort.push_back((InputPort *)(*iter1)->clone(this));
60  for(list<OutputPort *>::const_iterator iter2=other._setOfOutputPort.begin();iter2!=other._setOfOutputPort.end();iter2++)
61  _setOfOutputPort.push_back((OutputPort *)(*iter2)->clone(this));
62  for(list<InputDataStreamPort *>::const_iterator iter3=other._setOfInputDataStreamPort.begin();iter3!=other._setOfInputDataStreamPort.end();iter3++)
63  _setOfInputDataStreamPort.push_back((InputDataStreamPort *)(*iter3)->clone(this));
64  for(list<OutputDataStreamPort *>::const_iterator iter4=other._setOfOutputDataStreamPort.begin();iter4!=other._setOfOutputDataStreamPort.end();iter4++)
65  _setOfOutputDataStreamPort.push_back((OutputDataStreamPort *)(*iter4)->clone(this));
66 }
67 
69 {
70 }
71 
73 {
74 }
75 
77 {
78  for(list<InputPort *>::iterator iter1=_setOfInputPort.begin();iter1!=_setOfInputPort.end();iter1++)
79  delete *iter1;
80  for(list<OutputPort *>::iterator iter2=_setOfOutputPort.begin();iter2!=_setOfOutputPort.end();iter2++)
81  delete *iter2;
82  for(list<InputDataStreamPort *>::iterator iter3=_setOfInputDataStreamPort.begin();iter3!=_setOfInputDataStreamPort.end();iter3++)
83  delete *iter3;
84  for(list<OutputDataStreamPort *>::iterator iter4=_setOfOutputDataStreamPort.begin();iter4!=_setOfOutputDataStreamPort.end();iter4++)
85  delete *iter4;
86 }
87 
89 {
90  for(list<OutputPort *>::iterator iter=_setOfOutputPort.begin();iter!=_setOfOutputPort.end();iter++)
91  (*iter)->exInit();
92  for(list<InputPort *>::iterator iter2=_setOfInputPort.begin();iter2!=_setOfInputPort.end();iter2++)
93  (*iter2)->exInit(start);
94  _inGate.exReset();
95 }
96 
97 void ElementaryNode::init(bool start)
98 {
99  DEBTRACE("ElementaryNode::init " << getName() << " " << start << " " << _state);
101  if(_state == YACS::DISABLED)
102  {
103  exDisabledState(); // to refresh propagation of DISABLED state
104  return ;
105  }
107 }
108 
110 {
111  return false;
112 }
113 
115 {
116  return 0;
117 }
118 
120 {
121  return 0;
122 }
123 
125 {
126  return 0;
127 }
128 
130 {
131  return Node::getState();
132 }
133 
135 {
136  DEBTRACE("ElementaryNode::exUpdateState: " << getName() << " " << _state );
137  if(_state==YACS::DISABLED)return;
138  if(_inGate.exIsReady())
140  {
141  if(_state == YACS::READY)
142  ensureLoading();
143  else if(_state == YACS::LOADED)
145  }
146  else
147  {
148  string what("ElementaryNode::exUpdateState : Invalid graph given : Node with name \"");
149  what+=_name; what+="\" ready to run whereas some inputports are not set correctly\nCheck coherence DF/CF";
151  _errorDetails=what;
152  throw Exception(what);
153  }
154 }
155 
157 {
158  return _setOfInputPort.size();
159 }
160 
162 {
163  return _setOfOutputPort.size();
164 }
165 
166 InputPort *ElementaryNode::getInputPort(const std::string& name) const throw(YACS::Exception)
167 {
168  try {
169  return Node::getInputPort(name);
170  }
171  catch(Exception& e) {}
172  return getPort<InputPort>(name,_setOfInputPort);
173 }
174 
175 OutputPort *ElementaryNode::getOutputPort(const std::string& name) const throw(YACS::Exception)
176 {
177  return getPort<OutputPort>(name,_setOfOutputPort);
178 }
179 
181 {
182  set<OutPort *> ret;
183  list<OutPort *> temp=getSetOfOutPort();
184  for(list<OutPort *>::iterator iter2=temp.begin();iter2!=temp.end();iter2++)
185  {
186  set<InPort *> temp2=(*iter2)->edSetInPort();
187  if(temp2.size()!=0)
188  ret.insert(*iter2);
189  }
190  return ret;
191 }
192 
194 {
195  set<InPort *> ret;
196  list<InPort *> temp=getSetOfInPort();
197  for(list<InPort *>::iterator iter2=temp.begin();iter2!=temp.end();iter2++)
198  {
199  set<OutPort *> temp2=(*iter2)->edSetOutPort();
200  if(temp2.size()!=0)
201  ret.insert(*iter2);
202  }
203  return ret;
204 }
205 
206 std::vector< std::pair<OutPort *, InPort *> > ElementaryNode::getSetOfLinksLeavingCurrentScope() const
207 {
208  vector< pair<OutPort *, InPort *> > ret;
209  std::set<OutPort *> ports=getAllOutPortsLeavingCurrentScope();
210  for(set<OutPort *>::iterator iter2=ports.begin();iter2!=ports.end();iter2++)
211  {
212  set<InPort *> temp2=(*iter2)->edSetInPort();
213  for(set<InPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
214  ret.push_back(pair<OutPort *, InPort *>(*iter2,*iter3));
215  }
216  return ret;
217 }
218 
219 std::vector< std::pair<InPort *, OutPort *> > ElementaryNode::getSetOfLinksComingInCurrentScope() const
220 {
221  vector< pair<InPort *, OutPort *> > ret;
222  set<InPort *> ports=getAllInPortsComingFromOutsideOfCurrentScope();
223  for(set<InPort *>::iterator iter2=ports.begin();iter2!=ports.end();iter2++)
224  {
225  set<OutPort *> temp2=(*iter2)->edSetOutPort();
226  for(set<OutPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
227  {
228  std::set<OutPort *> trueOutPorts;
229  (*iter3)->getAllRepresented(trueOutPorts);
230  for(std::set<OutPort *>::iterator iter4=trueOutPorts.begin();iter4!=trueOutPorts.end();++iter4)
231  ret.push_back(pair<InPort *, OutPort *>(*iter2,*iter4));
232  }
233  }
234  return ret;
235 }
236 
238 {
239  return getPort<InputDataStreamPort>(name,_setOfInputDataStreamPort);
240 }
241 
243 {
244  return getPort<OutputDataStreamPort>(name,_setOfOutputDataStreamPort);
245 }
246 
248 {
249  //CF
251  //Leaving part
252  // - DF
253  for(list<InputPort *>::iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
254  (*iter)->edRemoveAllLinksLinkedWithMe();
255  // - DS
256  for(list<InputDataStreamPort *>::iterator iter2=_setOfInputDataStreamPort.begin();iter2!=_setOfInputDataStreamPort.end();iter2++)
257  (*iter2)->edRemoveAllLinksLinkedWithMe();
258  //Arriving part
259  // - DF
260  for(list<OutputPort *>::iterator iter=_setOfOutputPort.begin();iter!=_setOfOutputPort.end();iter++)
261  (*iter)->edRemoveAllLinksLinkedWithMe();
262  // - DS
263  for(list<OutputDataStreamPort *>::iterator iter2=_setOfOutputDataStreamPort.begin();iter2!=_setOfOutputDataStreamPort.end();iter2++)
264  (*iter2)->edRemoveAllLinksLinkedWithMe();
265 }
266 
273 {
274  bool ret=true;
275  for(list<InputPort *>::const_iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
276  {
277  ret=!(*iter)->isEmpty();
278  if (!ret) break;
279  }
280  return ret;
281 }
282 
283 /*
284  This method is used by the "multi" property of ElementaryNode to create
285  to create duplicated input and ouput datastream ports.
286 */
287 void
289 {
291  {
292  _createDatastreamPorts = true;
293  for(list<InputDataStreamPort *>::const_iterator iter3 = _setOfInputDataStreamPort.begin(); iter3!=_setOfInputDataStreamPort.end();iter3++)
294  {
295  InputDataStreamPort * port = *iter3;
296  std::string port_name = port->getName();
297  std::map<std::string,std::string>::iterator it=_propertyMap.find(port_name);
298  int multi = 1;
299  if(it != _propertyMap.end())
300  {
301  std::string multi_str = it->second;
302  std::istringstream iss(multi_str);
303  if (!(iss >> multi))
304  throw Exception("Property multi port should be set with a stringified int not an: " + multi_str);
305  }
306 
307  if (multi > 1)
308  {
309  addDatastreamPortToInitMultiService(port_name, multi);
310  // Change name of first port
311  port->setName(port_name + "_0");
312  for (int i = 2; i <= multi; i++)
313  {
314  InputDataStreamPort * new_port = port->clone(this);
315  std::ostringstream number;
316  number << i-1;
317  new_port->setName(port_name + "_" + number.str());
318  _setOfInputDataStreamPort.push_back(new_port);
319  _multi_port_node = true;
320  }
321  }
322  }
323  for(list<OutputDataStreamPort *>::const_iterator iter4 = _setOfOutputDataStreamPort.begin(); iter4!=_setOfOutputDataStreamPort.end();iter4++)
324  {
325  OutputDataStreamPort * port = *iter4;
326  std::string port_name = port->getName();
327  std::map<std::string,std::string>::iterator it=_propertyMap.find(port_name);
328  int multi = 1;
329  if(it != _propertyMap.end())
330  {
331  std::string multi_str = it->second;
332  std::istringstream iss(multi_str);
333  if (!(iss >> multi))
334  throw Exception("Property multi port should be set with a stringified int not an: " + multi_str);
335  }
336 
337  if (multi > 1)
338  {
339  addDatastreamPortToInitMultiService(port_name, multi);
340  // Change name of first port
341  port->setName(port_name + "_0");
342  for (int i = 2; i <= multi; i++)
343  {
344  OutputDataStreamPort * new_port = port->clone(this);
345  std::ostringstream number;
346  number << i-1;
347  new_port->setName(port_name + "_" + number.str());
348  _setOfOutputDataStreamPort.push_back(new_port);
349  _multi_port_node = true;
350  }
351  }
352  }
353  }
354 }
355 
360 void ElementaryNode::getReadyTasks(std::vector<Task *>& tasks)
361 {
362  DEBTRACE("ElementaryNode::getReadyTasks: " << getName() << " " << _state);
363 
364  int multi = 1;
365  std::map<std::string,std::string>::iterator it=_propertyMap.find("multi");
366  if(it != _propertyMap.end())
367  {
368  std::string multi_str = it->second;
369  std::istringstream iss(multi_str);
370  if (!(iss >> multi))
371  throw Exception("Property multi should be set with a stringified int not an: " + multi_str);
372  }
373 
375  {
376  if (multi == 1)
377  {
378  std::map<std::string,std::string>::iterator it=_propertyMap.find("multi_working_dir");
379  if(it != _propertyMap.end())
380  {
381  std::string working_dir_base = it->second;
382  std::ostringstream working_dir_stream;
383  working_dir_stream << working_dir_base;
384  working_dir_stream << 1;
385  this->getContainer()->setProperty("workingdir", working_dir_stream.str());
386  }
387  tasks.push_back(this);
388  }
389  else
390  {
391 
392  // Check output port -> cannot clone an Elementary Node with Output Ports connected
393  std::list<OutputPort *>::iterator it_output = _setOfOutputPort.begin();
394  for (;it_output != _setOfOutputPort.end(); it_output++)
395  {
396  if ((*it_output)->isConnected())
397  {
398  throw Exception("Property multi cannot be set on nodes with dataflow output ports connected");
399  }
400  }
401 
402  // Add my instance
403  std::map<std::string,std::string>::iterator it=_propertyMap.find("multi_working_dir");
404  if(it != _propertyMap.end())
405  {
406  std::string working_dir_base = it->second;
407  std::ostringstream working_dir_stream;
408  working_dir_stream << working_dir_base;
409  working_dir_stream << 1;
410  this->getContainer()->setProperty("workingdir", working_dir_stream.str());
411  }
412  tasks.push_back(this);
413 
414  // Step 1: Create clones
415  for (int i = 1; i < multi; i++)
416  {
417  // Clone
418  YACS::ENGINE::ElementaryNode * new_node = static_cast<YACS::ENGINE::ElementaryNode *>(clone(_father, false));
419  new_node->createMultiDatastreamPorts();
420 
421  // Change name
422  std::string iname;
423  std::stringstream inamess;
424  inamess << getName() << "_" << i;
425  iname=inamess.str();
426  DEBTRACE("Create clone "<< iname << " of node " << getName());
427  new_node->setName(iname);
428 
429  // For each input port connect it with the original output port
430  std::list<InputPort *> clone_list_inputPorts = new_node->getSetOfInputPort();
431  for(list<InputPort *>::const_iterator iter1=clone_list_inputPorts.begin(); iter1!=clone_list_inputPorts.end(); iter1++)
432  {
433  std::string input_port_name = (*iter1)->getName();
434  // Get Port Name in master node
435  InputPort * master_port = getInputPort(input_port_name);
436  for (std::set<OutPort *>::const_iterator itt=master_port->_backLinks.begin(); itt!=master_port->_backLinks.end();itt++)
437  {
438  // Connect dataflow
439  getProc()->edAddDFLink((*itt),(*iter1));
440  }
441  }
442 
443  // InputDataStreamPort connections
444  std::list<InputDataStreamPort *> clone_list_inputDatastreamPorts = new_node->getSetOfInputDataStreamPort();
445  for(list<InputDataStreamPort *>::iterator iter = clone_list_inputDatastreamPorts.begin(); iter != clone_list_inputDatastreamPorts.end(); iter++)
446  {
447  std::string port_name = (*iter)->getName();
448  InputDataStreamPort * orig_port = getInputDataStreamPort(port_name);
449 
450  std::set<OutputDataStreamPort *> connected_ports = orig_port->getConnectedOutputDataStreamPort();
451 
452  // Create datastream ports if not created
453  std::set<OutputDataStreamPort *>::const_iterator iter3;
454  for(iter3=connected_ports.begin();iter3!=connected_ports.end();iter3++)
455  {
456  ElementaryNode * node = (ElementaryNode *) (*iter3)->getNode();
458 
459  std::string good_port_name;
460  std::stringstream temp_name;
461  std::string out_name = (*iter3)->getName();
462  out_name.erase(out_name.end()-1);
463  temp_name << out_name << i;
464  good_port_name = temp_name.str();
465  getProc()->edAddLink(node->getOutputDataStreamPort(good_port_name), (*iter));
466  }
467  }
468 
469  // OutputDataStreamPort connections
470  std::list<OutputDataStreamPort *> clone_list_outputDatastreamPorts = new_node->getSetOfOutputDataStreamPort();
471  for(list<OutputDataStreamPort *>::iterator iter = clone_list_outputDatastreamPorts.begin(); iter != clone_list_outputDatastreamPorts.end(); iter++)
472  {
473  std::string port_name = (*iter)->getName();
474  OutputDataStreamPort * orig_port = getOutputDataStreamPort(port_name);
475  std::set<InputDataStreamPort *> dest_input_port = orig_port->_setOfInputDataStreamPort;
476  for(set<InputDataStreamPort *>::iterator dest_port = dest_input_port.begin(); dest_port != dest_input_port.end(); dest_port++)
477  {
478  ElementaryNode * dest_node = (ElementaryNode *)(*dest_port)->getNode();
479  // Add InputPort to dest node
480  dest_node->createMultiDatastreamPorts();
481 
482  std::string good_port_name;
483  std::stringstream temp_name;
484  std::string in_name = (*dest_port)->getName();
485  in_name.erase(in_name.end()-1);
486  temp_name << in_name << i;
487  good_port_name = temp_name.str();
488  getProc()->edAddLink((*iter), dest_node->getInputDataStreamPort(good_port_name));
489  }
490  }
491 
492  // Init node
493  new_node->init(false);
494  new_node->exUpdateState();
495 
496  // Set Control Link to done
497  std::list<OutGate *> clone_cl_back = new_node->getInGate()->getBackLinks();
498  for(std::list<OutGate *>::const_iterator iter=clone_cl_back.begin(); iter!=clone_cl_back.end(); iter++)
499  new_node->getInGate()->exNotifyFromPrecursor((*iter));
500 
501  // Add clone
502  std::map<std::string,std::string>::iterator it=_propertyMap.find("multi_working_dir");
503  if(it != _propertyMap.end())
504  {
505  std::string working_dir_base = it->second;
506  std::ostringstream working_dir_stream;
507  working_dir_stream << working_dir_base;
508  working_dir_stream << i+1;
509  new_node->getContainer()->setProperty("workingdir", working_dir_stream.str());
510  }
511  tasks.push_back(new_node);
512  }
513  }
514  }
515 }
516 
522 {
523  DEBTRACE("ElementaryNode::edRemovePort ");
524  if(port->getNode()!=this)
525  throw Exception("ElementaryNode::edRemovePort : Port is not held by this node");
526  if(InputPort *p=dynamic_cast<InputPort *>(port))
527  edRemovePortTypedFromSet<InputPort>(p,_setOfInputPort);
528  else if(OutputPort *p=dynamic_cast<OutputPort *>(port))
529  edRemovePortTypedFromSet<OutputPort>(p,_setOfOutputPort);
530  else if(InputDataStreamPort *p=dynamic_cast<InputDataStreamPort *>(port))
531  edRemovePortTypedFromSet<InputDataStreamPort>(p,_setOfInputDataStreamPort);
532  else if(OutputDataStreamPort *p=dynamic_cast<OutputDataStreamPort *>(port))
533  edRemovePortTypedFromSet<OutputDataStreamPort>(p,_setOfOutputDataStreamPort);
534  else
535  throw Exception("ElementaryNode::edRemovePort : unknown port type");
536  delete port;
537  modified();
538 }
539 
544 list<ElementaryNode *> ElementaryNode::getRecursiveConstituents() const
545 {
546  list<ElementaryNode *> ret;
547  ret.push_back((ElementaryNode *)this);
548  return ret;
549 }
550 
552 
556 list<ProgressWeight> ElementaryNode::getProgressWeight() const
557 {
558  list<ProgressWeight> ret;
559  ProgressWeight myWeight;
560  myWeight.weightTotal=1;
561  if (getState() == YACS::DONE)
562  myWeight.weightDone=1;
563  else
564  myWeight.weightDone=0;
565  ret.push_back(myWeight);
566  return ret;
567 }
568 
569 Node *ElementaryNode::getChildByName(const std::string& name) const throw(YACS::Exception)
570 {
571  string what("ElementaryNode does not agregate any nodes particullary node with name "); what+=name;
572  throw Exception(what);
573 }
574 
576 {
577  DEBTRACE("ElementaryNode::checkBasicConsistency");
578  list<InputPort *>::const_iterator iter;
579  for(iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
580  (*iter)->checkBasicConsistency();
581 }
582 
584 {
585  for(ComposedNode *iter=_father;iter!=levelToStop && iter!=0; iter=iter->_father)
586  if(!iter->isPlacementPredictableB4Run())
587  return iter;
588  return 0;
589 }
590 
591 InputPort *ElementaryNode::createInputPort(const std::string& inputPortName, TypeCode* type)
592 {
593  return getRuntime()->createInputPort(inputPortName, _implementation, this, type);
594 }
595 
601 InputPort *ElementaryNode::edAddInputPort(const std::string& inputPortName, TypeCode* type) throw(YACS::Exception)
602 {
603 
604  // Cannot create an InputPort defined with InPropertyPort name.
605  if (inputPortName == "__InPropertyPort__Node__YACS_")
606  {
607  string what("ElementaryNode::edAddInputPort: it is forbidden to add an InputPort with the name __InPropertyPort__Node__YACS_\"");
608  throw Exception(what);
609  }
610 
611  InputPort *ret = 0;
612  if (edCheckAddPort<InputPort, TypeCode*>(inputPortName,_setOfInputPort,type))
613  {
614  ret = createInputPort(inputPortName, type);
615  _setOfInputPort.push_back(ret);
616  modified();
617  /*
618  ComposedNode *iter=_father;
619  while(iter)
620  iter=iter->_father;
621  */
622  }
623  return ret;
624 }
625 
626 void ElementaryNode::edOrderInputPorts(const std::list<InputPort*>& ports)
627 {
628  std::set<InputPort *> s1;
629  std::set<InputPort *> s2;
630  for(list<InputPort *>::const_iterator it=_setOfInputPort.begin();it != _setOfInputPort.end();it++)
631  s1.insert(*it);
632  for(list<InputPort *>::const_iterator it=ports.begin();it != ports.end();it++)
633  s2.insert(*it);
634 
635  if(s1 != s2)
636  throw Exception("ElementaryNode::edOrderInputPorts : port list must contain same ports as existing ones");
637 
638  _setOfInputPort.clear();
639  for(list<InputPort *>::const_iterator it=ports.begin();it != ports.end();it++)
640  _setOfInputPort.push_back(*it);
641 }
642 
643 void ElementaryNode::edOrderOutputPorts(const std::list<OutputPort*>& ports)
644 {
645  std::set<OutputPort *> s1;
646  std::set<OutputPort *> s2;
647  for(list<OutputPort *>::const_iterator it=_setOfOutputPort.begin();it != _setOfOutputPort.end();it++)
648  s1.insert(*it);
649  for(list<OutputPort *>::const_iterator it=ports.begin();it != ports.end();it++)
650  s2.insert(*it);
651 
652  if(s1 != s2)
653  throw Exception("ElementaryNode::edOrderOutputPorts : port list must contain same ports as existing ones");
654 
655  _setOfOutputPort.clear();
656  for(list<OutputPort *>::const_iterator it=ports.begin();it != ports.end();it++)
657  _setOfOutputPort.push_back(*it);
658 }
659 
660 OutputPort *ElementaryNode::createOutputPort(const std::string& outputPortName, TypeCode* type)
661 {
662  return getRuntime()->createOutputPort(outputPortName, _implementation, this, type);
663 }
664 
670 OutputPort *ElementaryNode::edAddOutputPort(const std::string& outputPortName, TypeCode* type) throw(YACS::Exception)
671 {
672  OutputPort *ret =0;
673  if (edCheckAddPort<OutputPort, TypeCode*>(outputPortName,_setOfOutputPort,type))
674  {
675  ret = createOutputPort(outputPortName, type);
676  _setOfOutputPort.push_back(ret);
677  modified();
678  /*
679  ComposedNode *iter=_father;
680  while(iter)
681  iter=iter->_father;
682  */
683  }
684  return ret;
685 }
686 
687 InputDataStreamPort *ElementaryNode::createInputDataStreamPort(const std::string& inputPortDSName, TypeCode* type)
688 {
689  return getRuntime()->createInputDataStreamPort(inputPortDSName, this, type);
690 }
691 
693 {
695  if (edCheckAddPort<InputDataStreamPort, TypeCode*>(inputPortDSName,_setOfInputDataStreamPort,type))
696  {
697  ret = createInputDataStreamPort(inputPortDSName, type);
698  _setOfInputDataStreamPort.push_back(ret);
699  modified();
700  }
701  return ret;
702 }
703 
705 {
706  return getRuntime()->createOutputDataStreamPort(outputPortDSName, this, type);
707 }
708 
710 {
712  if (edCheckAddPort<OutputDataStreamPort, TypeCode*>(outputPortDSName,_setOfOutputDataStreamPort,type))
713  {
714  ret = createOutputDataStreamPort(outputPortDSName, type);
715  _setOfOutputDataStreamPort.push_back(ret);
716  modified();
717  }
718  return ret;
719 }
720 
725 string ElementaryNode::getInPortName(const InPort * inPort) const throw(YACS::Exception)
726 {
727  Node *node = inPort->getNode();
728  if ( node != this )
729  {
730  string what("InputPort "); what += inPort->getName(); what += " does not belong to node "; what += node->getName();
731  throw Exception(what);
732  }
733  return inPort->getName();
734 }
735 
736 string ElementaryNode::getOutPortName(const OutPort *outPort) const throw(YACS::Exception)
737 {
738  Node *node = outPort->getNode();
739  if ( node != this )
740  {
741  string what("OutputPort "); what += outPort->getName(); what += " does not belong to node "; what += node->getName();
742  throw Exception(what);
743  }
744  return outPort->getName();
745 }
746 
748 {
750 }
751 
753 {
754  return _state==TOACTIVATE;
755 }
756 
758 {
759  setState(DONE);
760 }
762 {
763  setState(ERROR);
764 }
765 
767 
773 {
774 }
775 
777 
783 {
784  if(_inGate.exIsReady())
786  {
788  return;
789  }
790  setState(LOADED);
791 }
792 
794 {
795  visitor->visitElementaryNode(this);
796 }
797 
799 
803 {
804  return _errorDetails;
805 }
806 
808 {
809  DEBTRACE("ElementaryNode::edUpdateState: " << getName());
811  try
812  {
814  _errorDetails="";
815  }
816  catch(Exception& e)
817  {
818  state=YACS::INVALID;
819  _errorDetails=e.what();
820  }
821  DEBTRACE("ElementaryNode::edUpdateState: " << _errorDetails);
822  if(state != _state)
823  setState(state);
824  _modified=0;
825 }
826 
828 
834 {
835  DEBTRACE("ElementaryNode::ensureLoading: " << getName());
836  if(_state != YACS::READY)
837  return;
839 
840  // request loading for all nodes connected to this one by datastream link
841  // Be careful that nodes can be connected in a loop. Put first this node in TOLOAD state to break the loop
842  std::list<OutputDataStreamPort *>::iterator iterout;
843  for(iterout = _setOfOutputDataStreamPort.begin(); iterout != _setOfOutputDataStreamPort.end(); iterout++)
844  {
845  OutputDataStreamPort *port=(OutputDataStreamPort *)*iterout;
846  std::set<InPort *> ports=port->edSetInPort();
847  std::set<InPort *>::iterator iter;
848  for(iter=ports.begin();iter != ports.end(); iter++)
849  {
850  Node* node= (*iter)->getNode();
851  node->ensureLoading();
852  }
853  }
854  std::list<InputDataStreamPort *>::iterator iterin;
855  for(iterin = _setOfInputDataStreamPort.begin(); iterin != _setOfInputDataStreamPort.end(); iterin++)
856  {
857  InputDataStreamPort *port=(InputDataStreamPort *)*iterin;
858  std::set<OutPort *> ports=port->edSetOutPort();
859  std::set<OutPort *>::iterator iter;
860  for(iter=ports.begin();iter != ports.end(); iter++)
861  {
862  Node* node= (*iter)->getNode();
863  node->ensureLoading();
864  }
865  }
866 }
867 
869 void ElementaryNode::getCoupledTasks(std::set<Task*>& coupledSet)
870 {
871  getCoupledNodes(coupledSet);
872 }
873 
875 void ElementaryNode::getCoupledNodes(std::set<Task*>& coupledSet)
876 {
877  if(coupledSet.find(this) != coupledSet.end())return;
878 
879  coupledSet.insert(this);
880 
881  std::list<OutputDataStreamPort *>::iterator iterout;
882  for(iterout = _setOfOutputDataStreamPort.begin(); iterout != _setOfOutputDataStreamPort.end(); iterout++)
883  {
884  OutputDataStreamPort *port=(OutputDataStreamPort *)*iterout;
885  std::set<InPort *> ports=port->edSetInPort();
886  std::set<InPort *>::iterator iter;
887  for(iter=ports.begin();iter != ports.end(); iter++)
888  {
889  Node* node= (*iter)->getNode();
890  node->getCoupledNodes(coupledSet);
891  }
892  }
893 }
894