Version: 8.3.0
Node.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 "Node.hxx"
21 #include "DynParaLoop.hxx"
22 #include "InputPort.hxx"
23 #include "OutputPort.hxx"
24 #include "InPropertyPort.hxx"
25 #include "ComposedNode.hxx"
26 #include "Dispatcher.hxx"
27 #include "InputDataStreamPort.hxx"
28 #include "OutputDataStreamPort.hxx"
29 #include <iostream>
30 
31 //#define _DEVDEBUG_
32 #include "YacsTrace.hxx"
33 
34 using namespace YACS::ENGINE;
35 using namespace std;
36 
43 const char Node::SEP_CHAR_IN_PORT[]=".";
44 
45 int Node::_total = 0;
46 std::map<int,Node*> Node::idMap;
47 
49 {
50  insert(make_pair(YACS::READY, "READY"));
51  insert(make_pair(YACS::TOLOAD, "TOLOAD"));
52  insert(make_pair(YACS::LOADED, "LOADED"));
53  insert(make_pair(YACS::TOACTIVATE, "TOACTIVATE"));
54  insert(make_pair(YACS::ACTIVATED, "ACTIVATED"));
55  insert(make_pair(YACS::DESACTIVATED, "DESACTIVATED"));
56  insert(make_pair(YACS::DONE, "DONE"));
57  insert(make_pair(YACS::SUSPENDED, "SUSPENDED"));
58  insert(make_pair(YACS::LOADFAILED, "LOADFAILED"));
59  insert(make_pair(YACS::EXECFAILED, "EXECFAILED"));
60  insert(make_pair(YACS::PAUSE, "PAUSE"));
61  insert(make_pair(YACS::INTERNALERR, "INTERNALERR"));
62  insert(make_pair(YACS::DISABLED, "DISABLED"));
63  insert(make_pair(YACS::FAILED, "FAILED"));
64  insert(make_pair(YACS::ERROR, "ERROR"));
65 }
66 
67 
68 Node::Node(const std::string& name):_name(name),_inGate(this),_outGate(this),_father(0),_state(YACS::READY),
69  _implementation(Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME),_modified(1)
70 {
71  // Should be protected by lock ??
72  _numId = _total++;
73  idMap[_numId]=this;
74 
75  // Every node has an InPropertyPort
76  _inPropertyPort = new InPropertyPort("__InPropertyPort__Node__YACS_", this, Runtime::_tc_propvec);
77 }
78 
79 Node::Node(const Node& other, ComposedNode *father):_inGate(this),_outGate(this),_name(other._name),_father(father),
80  _state(YACS::READY),_implementation(other._implementation),
81  _propertyMap(other._propertyMap),_modified(1)
82 {
83  _numId = _total++;
84  idMap[_numId]=this;
85 
86  // Every node has an InPropertyPort
87  _inPropertyPort = new InPropertyPort("__InPropertyPort__Node__YACS_", this, Runtime::_tc_propvec);
88 }
89 
91 {
92  delete _inPropertyPort;
93 }
94 
99 void Node::init(bool start)
100 {
101  _inGate.exReset();
102  _outGate.exReset();
103  if(_state == YACS::DISABLED)
104  {
105  exDisabledState(); // to refresh propagation of DISABLED state
106  return;
107  }
109 }
110 
128 Node *Node::clone(ComposedNode *father, bool editionOnly) const
129 {
130  Node *ret(simpleClone(father,editionOnly));
131  ret->performDuplicationOfPlacement(*this);
132  return ret;
133 }
134 
147 Node *Node::cloneWithoutCompAndContDeepCpy(ComposedNode *father, bool editionOnly) const
148 {
149  Node *ret(simpleClone(father,editionOnly));
151  return ret;
152 }
153 
155 
159 void Node::setName(const std::string& name)
160 {
161  if(_father)
162  {
163  if(_father->isNameAlreadyUsed(name))
164  {
165  if ( _father->getChildByName(name) != this )
166  {
167  std::string what("Name ");
168  what+=name;
169  what+=" already exists in the scope of "; what+=_father->getName();
170  throw Exception(what);
171  }
172  }
173  }
174  _name=name;
175 }
176 
181 list<Node *> Node::getOutNodes() const
182 {
183  list<Node *> ret;
184  list<InGate *> inGates=_outGate.edSetInGate();
185  for(list<InGate *>::iterator iter=inGates.begin();iter!=inGates.end();iter++)
186  ret.push_back((*iter)->getNode());
187  return ret;
188 }
189 
191 {
192  return _inGate.exIsReady();
193 }
194 
196 
203 {
204  if(_state==YACS::DISABLED)return;
205  if(_inGate.exIsReady())
207 }
208 
210 
216 {
217  DEBTRACE( "Node::exFailedState: " << getName() );
220 }
221 
223 
229 {
230  DEBTRACE( "Node::exDisabledState: " << getName() );
233 }
234 
235 InPort *Node::getInPort(const std::string& name) const throw(YACS::Exception)
236 {
237  InPort *ret;
238  try
239  {
240  ret=getInputPort(name);
241  }
242  catch(Exception& e)
243  {
244  ret=getInputDataStreamPort(name);
245  }
246  return ret;
247 }
248 
251 {
252  return _inPropertyPort;
253 }
254 
255 InputPort *
256 Node::getInputPort(const std::string& name) const throw(YACS::Exception)
257 {
258  if (name == "__InPropertyPort__Node__YACS_")
259  return _inPropertyPort;
260  else
261  {
262  std::string what("Node::getInputPort : the port with name "); what+=name; what+=" does not exist on the current level";
263  throw Exception(what);
264  }
265 }
266 
271 OutPort *Node::getOutPort(const std::string& name) const throw(YACS::Exception)
272 {
273  OutPort *ret;
274  try
275  {
276  ret=getOutputPort(name);
277  }
278  catch(Exception& e)
279  {
280  ret=getOutputDataStreamPort(name);
281  }
282  return ret;
283 }
284 
285 std::list<InPort *> Node::getSetOfInPort() const
286 {
287  list<InPort *> ret;
288  list<InputPort *> data=getSetOfInputPort();
289  ret.insert(ret.end(),data.begin(),data.end());
290  list<InputDataStreamPort *> ds=getSetOfInputDataStreamPort();
291  ret.insert(ret.end(),ds.begin(),ds.end());
292  return ret;
293 }
294 
295 std::list<OutPort *> Node::getSetOfOutPort() const
296 {
297  list<OutPort *> ret;
298  list<OutputPort *> data=getSetOfOutputPort();
299  ret.insert(ret.end(),data.begin(),data.end());
300  list<OutputDataStreamPort *> ds=getSetOfOutputDataStreamPort();
301  ret.insert(ret.end(),ds.begin(),ds.end());
302  return ret;
303 }
304 
313 std::list<ComposedNode *> Node::getAllAscendanceOf(ComposedNode *levelToStop) const
314 {
315  list<ComposedNode *> ret;
316  if(this==levelToStop)
317  return ret;
318  for(ComposedNode *iter=_father;iter!=levelToStop && iter!=0; iter=iter->_father)
319  ret.push_back(iter);
320  return ret;
321 }
322 
323 bool Node::operator>(const Node& other) const
324 {
325  const ComposedNode *iter=other._father;
326  while(iter!=0 && iter!=this)
327  iter=iter->_father;
328  return iter==this;
329 }
330 
331 bool Node::operator<(const Node& other) const
332 {
333  const ComposedNode *iter=_father;
334  while(iter!=0 && iter!=(&other))
335  iter=iter->_father;
336  return iter==(&other);
337 }
338 
347 {
348  return _implementation;
349 }
350 
352 set<InputPort *> Node::edGetSetOfUnitializedInputPort() const
353 {
354  set<InputPort *> setOfUnitializedInputPort;
355  list<InputPort *> allOfInputPorts=getSetOfInputPort();
356  for(list<InputPort *>::const_iterator iter=allOfInputPorts.begin();iter!=allOfInputPorts.end();iter++)
357  {
358  if ( ! (*iter)->edIsInitialized() )
359  setOfUnitializedInputPort.insert(*iter);
360  }
361  return setOfUnitializedInputPort;
362 }
363 
366 {
367  set<InputPort *> setOfUnitializedInputPort = edGetSetOfUnitializedInputPort();
368  return ( setOfUnitializedInputPort.size() == 0);
369 }
370 
375 {
377 }
378 
383 {
384  DEBTRACE("Node::exForwardFinished");
386 }
387 
392 {
395 }
396 
398 {
399  if(!_father)
400  return 0;
401  return _father->getProc();
402 }
403 
404 const Proc * Node::getProc() const
405 {
406  if(!_father)
407  return 0;
408  return _father->getProc();
409 }
410 
412 {
413  if(!_father)
414  throw Exception("No root node");
415  ComposedNode *iter=_father;
416  while(iter->_father)
417  iter=iter->_father;
418  return (ComposedNode *)iter;
419 }
420 
426 void Node::checkValidityOfPortName(const std::string& name) throw(YACS::Exception)
427 {
428  if(name.find(SEP_CHAR_IN_PORT, 0 )!=string::npos)
429  {
430  string what("Port name "); what+=name; what+="not valid because it contains character "; what+=SEP_CHAR_IN_PORT;
431  throw Exception(what);
432  }
433 }
434 
440 {
441  if(node1!=0 && node2!=0)
442  {
443  if(node1->_father==node2->_father)
444  return node1->_father;
445  }
446  throw Exception("check failed : nodes have not the same father");
447 }
448 
449 const std::string Node::getId() const
450 {
451  std::string id=getRootNode()->getName();
452  if(getRootNode() != this)
453  id= id+'.'+ getRootNode()->getChildName(this);
454  string::size_type debut =id.find_first_of('.');
455  while(debut != std::string::npos){
456  id[debut]='_';
457  debut=id.find_first_of('.',debut);
458  }
459  return id;
460 }
461 
462 void Node::setProperty(const std::string& name, const std::string& value)
463 {
464  DEBTRACE("Node::setProperty " << name << " " << value);
465  _propertyMap[name]=value;
466 }
467 
468 std::string Node::getProperty(const std::string& name)
469 {
470  std::map<std::string,std::string>::iterator it=_propertyMap.find(name);
471 
472  if(it != _propertyMap.end())
473  return it->second;
474  else if(_father)
475  return _father->getProperty(name);
476  else
477  return "";
478 }
479 
480 std::map<std::string,std::string> Node::getProperties()
481 {
482  std::map<std::string,std::string> amap=_propertyMap;
483  if(_father)
484  {
485  std::map<std::string,std::string> fatherMap=_father->getProperties();
486  amap.insert(fatherMap.begin(),fatherMap.end());
487  }
488 
489  return amap;
490 }
491 
492 void Node::setProperties(std::map<std::string,std::string> properties)
493 {
494  _propertyMap.clear();
495  _propertyMap=properties;
496 }
497 
499 
510 {
511  if(!_father) //the root node
512  return _state;
514  return YACS::DISABLED;
515  return _father->getEffectiveState(this);
516 }
517 
519 
524 {
525  if(node->getState()==YACS::DISABLED)
526  return YACS::DISABLED;
527 
528  YACS::StatesForNode effectiveState=getEffectiveState();
529  switch(effectiveState)
530  {
531  case YACS::READY:
532  return YACS::READY;
533  case YACS::TOACTIVATE:
534  return YACS::READY;
535  case YACS::DISABLED:
536  return YACS::DISABLED;
537  case YACS::ERROR:
538  return YACS::FAILED;
539  default:
540  return node->getState();
541  }
542 }
543 
545 
550 {
551  switch(state)
552  {
553  case YACS::READY:
554  return "pink";
555  case YACS::TOLOAD:
556  return "magenta";
557  case YACS::LOADED:
558  return "magenta";
559  case YACS::TOACTIVATE:
560  return "purple";
561  case YACS::ACTIVATED:
562  return "blue";
563  case YACS::DONE:
564  return "green";
565  case YACS::ERROR:
566  return "red";
567  case YACS::FAILED:
568  return "orange";
569  case YACS::DISABLED:
570  return "grey";
571  case YACS::PAUSE:
572  return "white";
573  default:
574  return "white";
575  }
576 }
577 
579 
582 void Node::writeDot(std::ostream &os) const
583 {
584  os << getId() << "[fillcolor=\"" ;
586  os << getColorState(state);
587  os << "\" label=\"" << getImplementation() << "Node:" ;
588  os << getQualifiedName() <<"\"];\n";
589 }
590 
592 
597 std::string Node::getQualifiedName() const
598 {
599  if(_father)
600  return _father->getMyQualifiedName(this);
601  return getName();
602 }
603 
605 
609 {
610  return _numId;
611 }
612 
614 
618 {
619  DEBTRACE("Node::setState: " << getName() << " " << theState);
620  _state = theState;
621  // emit notification to all observers registered with the dispatcher on any change of the node's state
622  sendEvent("status");
623 }
624 
625 std::vector<std::pair<std::string,int> > Node::getDPLScopeInfo(ComposedNode *gfn)
626 {
627  std::vector< std::pair<std::string,int> > ret;
628  Node *work2(this);
629  ComposedNode *work(getFather());
630  while(work!=gfn && work!=0)
631  {
632  DynParaLoop *workc(dynamic_cast<DynParaLoop *>(work));
633  if(workc)
634  {
635  std::pair<std::string,int> p(gfn->getChildName(workc),workc->getBranchIDOfNode(work2));
636  ret.push_back(p);
637  }
638  work2=work;
639  work=work->getFather();
640  }
641  return ret;
642 }
643 
649 {
650 }
651 
653 
656 void Node::sendEvent(const std::string& event)
657 {
658  DEBTRACE("Node::sendEvent " << event);
660  disp->dispatch(this,event);
661 }
662 
664 
667 void Node::sendEvent2(const std::string& event, void *something)
668 {
670  disp->dispatch2(this,event,something);
671 }
672 
678 {
679  node->setState(state);
680 }
681 
683 
689 {
690  if(_modified)
691  edUpdateState();
692  if(_state > YACS::INVALID)
693  return 1;
694  else
695  return 0;
696 }
697 
699 
704 {
705  DEBTRACE("Node::edUpdateState(): " << _modified);
706  _modified=0;
707 }
708 
710 
713 std::string Node::getErrorReport()
714 {
715  if(getState()==YACS::DISABLED)
716  return "<error node= "+getName()+ "state= DISABLED/>\n";
717 
718  YACS::StatesForNode effectiveState=getEffectiveState();
719 
720  DEBTRACE("Node::getErrorReport: " << getName() << " " << effectiveState << " " << _errorDetails);
721  if(effectiveState != YACS::INVALID && effectiveState != YACS::ERROR &&
722  effectiveState != YACS::FAILED && effectiveState != YACS::INTERNALERR)
723  return "";
724 
725  std::string report="<error node= " ;
726  report=report + getName() ;
727  switch(effectiveState)
728  {
729  case YACS::INVALID:
730  report=report+" state= INVALID";
731  break;
732  case YACS::ERROR:
733  report=report+" state= ERROR";
734  break;
735  case YACS::FAILED:
736  report=report+" state= FAILED";
737  break;
738  case YACS::INTERNALERR:
739  report=report+" state= INTERNALERR";
740  break;
741  default:
742  break;
743  }
744  report=report + ">\n" ;
745  report=report+_errorDetails;
746  report=report+"\n</error>";
747  return report;
748 }
749 
751 
755 {
756  return "";
757 }
758 
760 
764 {
765  DEBTRACE("Node::modified() " << getName());
766  _modified=1;
767  if(_father)
768  _father->modified();
769 }
770 
772 
776 {
777  if(_state == YACS::READY)
779 }
780 
782 
786 {
787  static NodeStateNameMap nodeStateNameMap;
788  return nodeStateNameMap[state];
789 }
790 
792 
795 void Node::shutdown(int level)
796 {
797  if(level==0)return;
798 }
799 
801 
805 {
806 }
807 
809 void Node::resetState(int level)
810 {
811  DEBTRACE("Node::resetState " << getName() << "," << level << "," << _state);
813  {
815  InGate* inGate = getInGate();
816  std::list<OutGate*> backlinks = inGate->getBackLinks();
817  for (std::list<OutGate*>::iterator io = backlinks.begin(); io != backlinks.end(); io++)
818  {
819  Node* fromNode = (*io)->getNode();
820  if(fromNode->getState() == YACS::DONE)
821  {
822  inGate->setPrecursorDone(*io);
823  }
824  }
825  }
826 }