Version: 9.16.0
ComposedNode.cxx
Go to the documentation of this file.
1// Copyright (C) 2006-2026 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 "ComposedNode.hxx"
21#include "LinkInfo.hxx"
22#include "Container.hxx"
23#include "InputPort.hxx"
24#include "OutputPort.hxx"
25#include "ServiceNode.hxx"
26#include "InlineNode.hxx"
27#include "DataFlowPort.hxx"
28#include "DataStreamPort.hxx"
29#include "ElementaryNode.hxx"
30#include "ComponentInstance.hxx"
31
32#include <iostream>
33#include <set>
34#include <string>
35#include <sstream>
36#include <algorithm>
37
38//#define _DEVDEBUG_
39#include "YacsTrace.hxx"
40
41using namespace YACS::ENGINE;
42using namespace std;
43
52const char ComposedNode::SEP_CHAR_BTW_LEVEL[]=".";
53
54ComposedNode::ComposedNode(const std::string& name):Node(name)
55{
56}
57
58ComposedNode::ComposedNode(const ComposedNode& other, ComposedNode *father):Node(other,father)
59{
60}
61
63{
64}
65
67{
68 const ComposedNode &otherC=*(dynamic_cast<const ComposedNode *>(&other));
69 DeploymentTree treeToDup=otherC.getDeploymentTree();
70 list< ElementaryNode * > clones=otherC.getRecursiveConstituents();
71 vector<Container *> conts=treeToDup.getAllContainers();
72 //iterate on all containers
73 for(vector<Container *>::iterator iterCt=conts.begin();iterCt!=conts.end();iterCt++)
74 {
75 vector<ComponentInstance *> comps=treeToDup.getComponentsLinkedToContainer(*iterCt);
76 Container *contCloned=0;
77 if((*iterCt))
78 contCloned=(*iterCt)->clone();
79
80 //iterate on all component instances linked to the container
81 for(vector<ComponentInstance *>::iterator iterCp=comps.begin();iterCp!=comps.end();iterCp++)
82 {
83 vector<Task *> tasks=treeToDup.getTasksLinkedToComponent(*iterCp);
84 ComponentInstance *curCloned=(*iterCp)->clone();
85 curCloned->setContainer(contCloned);
86 for(vector<Task *>::iterator iterT=tasks.begin();iterT!=tasks.end();iterT++)
87 {
88 //No risk for static cast : appendTask called by ComposedNode.
89 list< ElementaryNode * >::iterator res=find(clones.begin(),clones.end(),(ElementaryNode *)(*iterT));
90 //No risk here to because called only on cloning process...
91 ServiceNode *nodeC=(ServiceNode *)getChildByName(otherC.getChildName(*res));
92 nodeC->setComponent(curCloned);
93 }
94 curCloned->decrRef();
95 }
96
97 // iterate on all tasks linked to the container
98 vector<Task *> tasks=treeToDup.getTasksLinkedToContainer(*iterCt);
99 for(vector<Task *>::iterator iterT=tasks.begin();iterT!=tasks.end();iterT++)
100 {
101 std::list< ElementaryNode * >::iterator res=find(clones.begin(),clones.end(),(ElementaryNode *)(*iterT));
103 nodeC->setContainer(contCloned);
104 }
105
106 // ended with current container
107 if(contCloned)
108 contCloned->decrRef();
109 }
110}
111
113{
114 const ComposedNode &otherC=*(dynamic_cast<const ComposedNode *>(&other));
115 DeploymentTree treeToDup=otherC.getDeploymentTree();
116 list< ElementaryNode * > clones=otherC.getRecursiveConstituents();
117 vector<Container *> conts=treeToDup.getAllContainers();
118 //iterate on all containers
119 for(vector<Container *>::iterator iterCt=conts.begin();iterCt!=conts.end();iterCt++)
120 {
121 vector<ComponentInstance *> comps=treeToDup.getComponentsLinkedToContainer(*iterCt);
122 Container *contCloned((*iterCt));
123
124 //iterate on all component instances linked to the container
125 for(vector<ComponentInstance *>::iterator iterCp=comps.begin();iterCp!=comps.end();iterCp++)
126 {
127 vector<Task *> tasks=treeToDup.getTasksLinkedToComponent(*iterCp);
128 ComponentInstance *curCloned((*iterCp));
129 curCloned->setContainer(contCloned);
130 for(vector<Task *>::iterator iterT=tasks.begin();iterT!=tasks.end();iterT++)
131 {
132 //No risk for static cast : appendTask called by ComposedNode.
133 list< ElementaryNode * >::iterator res=find(clones.begin(),clones.end(),(ElementaryNode *)(*iterT));
134 //No risk here to because called only on cloning process...
135 ServiceNode *nodeC=(ServiceNode *)getChildByName(otherC.getChildName(*res));
136 nodeC->setComponent(curCloned);
137 }
138 }
139
140 // iterate on all tasks linked to the container
141 vector<Task *> tasks=treeToDup.getTasksLinkedToContainer(*iterCt);
142 for(vector<Task *>::iterator iterT=tasks.begin();iterT!=tasks.end();iterT++)
143 {
144 std::list< ElementaryNode * >::iterator res=find(clones.begin(),clones.end(),(ElementaryNode *)(*iterT));
146 nodeC->setContainer(contCloned);
147 }
148 }
149}
150
152{
153 if(_state==YACS::DONE)return true;
154 if(_state==YACS::ERROR)return true;
155 if(_state==YACS::FAILED)return true;
156 if(_state==YACS::DISABLED)return true;
157 return false;
158}
159
160void ComposedNode::init(bool start)
161{
162 Node::init(start);
163}
164
165std::string ComposedNode::getName() const
166{
167 return Node::getName();
168}
169
170std::string ComposedNode::getTaskName(Task *task) const
171{
172 return getChildName(dynamic_cast<ElementaryNode *>(task));
173}
174
177{
178 DeploymentTree ret;
179 list< ElementaryNode * > tasks=getRecursiveConstituents();
180 for(list< ElementaryNode * >::iterator iter=tasks.begin();iter!=tasks.end();iter++)
181 ret.appendTask(*iter,(*iter)->getDynClonerIfExists(this));
182 return ret;
183}
184
186
190{
191 DeploymentTree ret;
192 list< ElementaryNode * > tasks=getRecursiveConstituents();
193 for(list< ElementaryNode * >::iterator iter=tasks.begin();iter!=tasks.end();iter++)
194 {
195 switch(ret.appendTask(*iter,(*iter)->getDynClonerIfExists(this)))
196 {
198 {
199 string what("ComposedNode::checkDeploymentTree : ServiceNode with name \""); what+=(*iter)->getName();
200 what+="\" coexists in a component with an another Task which context is incompatible with it.";
201 throw Exception(what);
202 }
204 {
205 if(deep)
206 {
207 string what("ComposedNode::checkDeploymentTree : ServiceNode with name \""); what+=(*iter)->getName();
208 what+="\" is deployable but no component is specified on it.";
209 throw Exception(what);
210 }
211 }
212 }
213 }
214 return ret;
215}
216
217std::vector<Task *> ComposedNode::getNextTasks(bool& isMore)
218{
219 vector<Task *> ret;
220 isMore=false;
221 getReadyTasks(ret);
222 isMore=!ret.empty();
223 return ret;
224}
225
227
243void ComposedNode::notifyFrom(const Task *sender, //* I : task emitting event
244 YACS::Event event, //* I : event emitted
245 const Executor *execInst
246 )
247{
248 DEBTRACE("ComposedNode::notifyFrom " << event);
249 ElementaryNode *taskTyped=dynamic_cast<ElementaryNode *>((Task *)sender);
250 YACS::Event curEvent=event;
251 Node *lminus1LevelNode=taskTyped;
252 ComposedNode *curLevelNode=taskTyped->_father;
253 if(!curLevelNode)//Specific case of loop when 0 turn is specified without any enclosing bloc.
254 return ;
255 curEvent=curLevelNode->updateStateFrom(lminus1LevelNode,curEvent,execInst);
256 while(curEvent!=YACS::NOEVENT && curLevelNode!=this)
257 {
258 lminus1LevelNode=curLevelNode;
259 curLevelNode=curLevelNode->_father;
260 curEvent=curLevelNode->updateStateFrom(lminus1LevelNode,curEvent,execInst);
261 }
262}
263
265
274{
275 DEBTRACE("ComposedNode::edAddLink");
276 set<OutPort *> represented;
277
278 start->getAllRepresented(represented);
279 if(represented.size()!=1)
280 {
281 bool ret=false;
282 for(set<OutPort *>::iterator iter=represented.begin();iter!=represented.end();iter++)
283 ret|=edAddLink(*iter,end);
284 return ret;
285 }
286 if(start->isAlreadyLinkedWith(end))
287 return false;
288 ComposedNode* lwstCmnAnctr=getLowestCommonAncestor(start->getNode(),end->getNode());
289 list<ComposedNode *> allAscendanceOfNodeStart=start->getNode()->getAllAscendanceOf(lwstCmnAnctr);
290 list<ComposedNode *> allAscendanceOfNodeEnd=end->getNode()->getAllAscendanceOf(lwstCmnAnctr);
291 checkInMyDescendance(lwstCmnAnctr);
292 lwstCmnAnctr->checkLinkPossibility(start,allAscendanceOfNodeStart,end,allAscendanceOfNodeEnd);
293 ComposedNode *iterS;
294 if(dynamic_cast<ComposedNode *>(start->getNode()))
295 iterS=(ComposedNode *)start->getNode();
296 else
297 iterS=start->getNode()->_father;
298 pair<OutPort *, OutPort *> pO(start,start);
299 while(iterS!=lwstCmnAnctr)
300 {
301 iterS->buildDelegateOf(pO, end, allAscendanceOfNodeEnd);
302 iterS=iterS->_father;
303 }
304 if(dynamic_cast<ComposedNode *>(end->getNode()))
305 iterS=(ComposedNode *)end->getNode();
306 else
307 iterS=end->getNode()->_father;
308
309 InPort *currentPortI=end;
310 bool isLoopProofLink(true),isFirstTurn(true);
311 while(iterS!=lwstCmnAnctr)
312 {
313 if(!isFirstTurn && iterS->isLoop())// isFirstTurn is a way to filter special inputs like nbBranches, splitPort... These special inputs are loopProof -> they must not be realeased by ForEachLoop::exUpdateState
314 isLoopProofLink=false;
315 iterS->buildDelegateOf(currentPortI, start, allAscendanceOfNodeStart);
316 iterS=iterS->_father;
317 isFirstTurn=false;
318 }
319 bool ret=(pO.first)->addInPort(currentPortI);
320 end->edNotifyReferencedBy(pO.second,isLoopProofLink);
321 return ret;
322}
323
325
334{
335 Node* n1=start->getNode();
336 Node* n2=end->getNode();
337 DEBTRACE( n1->getName() << ":" << n2->getName())
339 DEBTRACE( "ComposedNode::edAddDFLink: this="<<this->getName()
340 << " father=" << father->getName() )
341 DEBTRACE( "ComposedNode::edAddDFLink: OutPort=" << start->getName()
342 << " InPort=" << end->getName() )
343 if (father != this)
344 {
345 bool ret = father->edAddDFLink(start,end); // special treatement for loop
346 return ret;
347 }
348 if(n2 == father)
349 throw Exception("Back link authorized only in special context (loop for example)");
350
351 bool ret= edAddLink(start,end);
352 if(n1 != father)
353 {
354 //add a control link only if nodes are not in the same descendance
355 //if n1 == father (n2 is after n1) : the control link is not needed
356 //if n2 == father (n1 is after n2) : it's a back link authorized only in loop context
357 while(n1->getFather() != father)
358 n1=n1->getFather();
359 while(n2->getFather() != father)
360 n2=n2->getFather();
361 try
362 {
363 edAddCFLink(n1,n2);
364 }
365 catch (Exception& ex)
366 {
367 // --- remove DF link already created in case of cycle dtection
368 DEBTRACE("Cycle detected, remove CF link");
369 if(start->isAlreadyLinkedWith(end))
370 edRemoveLink(start, end);
371 throw ex;
372 }
373 }
374 return ret;
375}
376
378
388{
389 Node* n1=start->getNode();
390 Node* n2=end->getNode();
391 if(n1==n2)
392 throw Exception("ComposedNode::edAddLink: can not add a control link to a node with itself",1);
393 ComposedNode* father=checkHavingCommonFather(start->getNode(),end->getNode());
394 if(father==0)
395 throw Exception("ComposedNode::edAddLink: Trying to add CF link on orphan nodes.");
396 if(father!=this)
397 {
398 checkInMyDescendance(father);
399 return father->edAddLink(start,end);
400 }
401 bool ret=start->edAddInGate(end);
402 if(ret)
403 try
404 {
406 }
407 catch (Exception& ex)
408 {
409 // --- remove created CF link in case of cycle detection
410 DEBTRACE("Cycle detected, remove CF link");
411 edRemoveCFLink(start->getNode(), end->getNode());
412 throw ex;
413 }
414 return ret;
415}
416
418
422{
423 return edAddLink(nodeS->getOutGate(),nodeE->getInGate());
424}
425
428{
429 edRemoveLink(nodeS->getOutGate(),nodeE->getInGate());
430}
431
433
442{
443 if(!start->isAlreadyLinkedWith(end))
444 throw Exception("ComposedNode::edRemoveLink : unexisting link");
445 ComposedNode* lwstCmnAnctr=getLowestCommonAncestor(start->getNode(),end->getNode());
446 checkInMyDescendance(lwstCmnAnctr);
447 list<ComposedNode *> allAscendanceOfNodeStart=start->getNode()->getAllAscendanceOf(lwstCmnAnctr);
448 list<ComposedNode *> allAscendanceOfNodeEnd=end->getNode()->getAllAscendanceOf(lwstCmnAnctr);
449
450 // --- Part of test if the link from 'start' to 'end' really exist particulary all eventually intermediate ports created
451
452 ComposedNode *iterS=start->getNode()->_father;
453 pair<OutPort *,OutPort *> currentPortO(start,start);
454 vector<pair< ComposedNode * , pair < OutPort* , OutPort *> > > needsToDestroyO;
455
456 Node *nodeOTemp=start->getNode();
457 if(*nodeOTemp<*lwstCmnAnctr)
458 {
459 iterS=nodeOTemp->_father;
460 while(iterS!=lwstCmnAnctr)
461 {
462 if (!iterS)
463 {
464 stringstream what;
465 what << "ComposedNode::edRemoveLink: "
466 << start->getNode()->getName() << "." <<start->getName() << "->"
467 << end->getNode()->getName() << "." << end->getName();
468 throw Exception(what.str());
469 }
470 OutPort *tmp=currentPortO.first;
471 iterS->getDelegateOf(currentPortO, end, allAscendanceOfNodeEnd);
472 needsToDestroyO.push_back(pair< ComposedNode * , pair < OutPort* , OutPort *> >(iterS,pair<OutPort* , OutPort *> (tmp,currentPortO.first)));
473 iterS=iterS->_father;
474 }
475 }
476 Node *nodeTemp=end->getNode();
477 InPort * currentPortI=end;
478 if(*nodeTemp<*lwstCmnAnctr)
479 {
480 iterS=nodeTemp->_father;
481 while(iterS!=lwstCmnAnctr)
482 {
483 if (!iterS)
484 {
485 stringstream what;
486 what << "ComposedNode::edRemoveLink: "
487 << start->getNode()->getName() << "." <<start->getName() << "->"
488 << end->getNode()->getName() << "." << end->getName();
489 throw Exception(what.str());
490 }
491 iterS->getDelegateOf(currentPortI, start, allAscendanceOfNodeStart);
492 iterS=iterS->_father;
493 }
494 }
495 // --- End of test for evt intermediate ports created
496
497 (currentPortO.first)->removeInPort(currentPortI,false);
498 set<OutPort *> repr;
499 (currentPortO.second)->getAllRepresented(repr);
500 if(repr.size()==1)
501 end->edNotifyDereferencedBy(currentPortO.second);
502
503 // --- Performing deletion of intermediate ports
504
505 iterS=start->getNode()->_father;
506 vector<pair< ComposedNode * , pair < OutPort* , OutPort *> > >::reverse_iterator iter;
507 for(iter=needsToDestroyO.rbegin();iter!=needsToDestroyO.rend();iter++)
508 (*iter).first->releaseDelegateOf(((*iter).second).first, ((*iter).second).second, end,allAscendanceOfNodeEnd);
509 nodeTemp=end->getNode();
510 if(*nodeTemp<*lwstCmnAnctr)
511 {
512 iterS=end->getNode()->_father;
513 currentPortI=end;
514 while(iterS!=lwstCmnAnctr)
515 {
516 iterS->releaseDelegateOf(currentPortI, start, allAscendanceOfNodeStart);
517 iterS=iterS->_father;
518 }
519 }
520}
521
524{
525 ComposedNode* father=checkHavingCommonFather(start->getNode(),end->getNode());
526 if(father!=this)
527 throw Exception("edRemoveLink : nodes not in direct descendance of this");
528 start->edRemoveInGate(end);
529}
530
532{
533 return false; // --- reimplemented in derived classes
534}
535
538{
539 if(!node)
540 return;
541 if (node->_father!=this)
542 {
543 string what("node "); what+= node->getName() ; what+=" is not a child of node "; what += getName();
544 throw Exception(what);
545 }
547 node->_father = 0;
548 //set _modified flag so edUpdateState() can refresh state
549 modified();
550}
551
553
561bool ComposedNode::splitNamesBySep(const std::string& globalName, const char separator[],
562 std::string& firstPart, std::string& lastPart, bool priority)
563{
564 const string delims(separator);
565 string portName, nodeName;
566 string::size_type idx;
567 if(priority)
568 idx = globalName.find_last_of(delims);
569 else
570 idx = globalName.find_first_of(delims);
571 if (idx == string::npos)
572 {
573 firstPart=globalName;
574 lastPart="";
575 return false;
576 }
577 firstPart = globalName.substr(0,idx);
578 lastPart = globalName.substr(idx+1);
579 if ((firstPart.empty()) || (lastPart.empty()))
580 {
581 string what("the name "); what+= globalName ; what+=" is not a valid port name";
582 throw Exception(what);
583 }
584 return true;
585}
586
587std::vector< std::pair<OutPort *, InPort *> > ComposedNode::getSetOfInternalLinks() const
588{
589 vector< pair<OutPort *, InPort *> > ret;
590 list<OutPort *> temp=getSetOfOutPort();
591 for(list<OutPort *>::const_iterator iter2=temp.begin();iter2!=temp.end();iter2++)
592 {
593 set<InPort *> temp2=(*iter2)->edSetInPort();
594 for(set<InPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
595 if(isInMyDescendance((*iter3)->getNode()))
596 ret.push_back(pair<OutPort *, InPort *>((*iter2),(*iter3)));
597 }
598 return ret;
599}
600
601std::vector< std::pair<OutPort *, InPort *> > ComposedNode::getSetOfLinksLeavingCurrentScope() const
602{
603 vector< pair<OutPort *, InPort *> > ret;
604 std::set<OutPort *> ports=getAllOutPortsLeavingCurrentScope();
605 for(set<OutPort *>::iterator iter2=ports.begin();iter2!=ports.end();iter2++)
606 {
607 set<InPort *> temp2=(*iter2)->edSetInPort();
608 for(set<InPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
609 if(!isInMyDescendance((*iter3)->getNode()))
610 ret.push_back(pair<OutPort *, InPort *>(*iter2,*iter3));
611 }
612 return ret;
613}
614
616{
617 info.clearAll();
618 info.setPointOfView((ComposedNode *)this);
620 list<InputPort *> setOfInToTest=getSetOfInputPort();
621 for(list<InputPort *>::iterator iter1=setOfInToTest.begin();iter1!=setOfInToTest.end();iter1++)
622 {
623 vector<OutPort *> candidateForAdvCheck;
624 set<OutPort *> outPorts=(*iter1)->edSetOutPort();
625 //Filtering among outPorts, which of them, are candidates to fill *iter1 at the current scope.
626 for(set<OutPort *>::iterator iter2=outPorts.begin();iter2!=outPorts.end();iter2++)
627 {
628 (*iter2)->checkConsistency(info);
629 ComposedNode *manager=getLowestCommonAncestor((*iter2)->getNode(),(*iter1)->getNode());
630 if(isInMyDescendance(manager))
631 candidateForAdvCheck.push_back(*iter2);
632 }
633 if(!candidateForAdvCheck.empty())
634 //End of filtering. Now regarding CF constraints for the current InPutPort.
635 try
636 {
637 checkLinksCoherenceRegardingControl(candidateForAdvCheck,*iter1,info);
638 }
639 catch(YACS::Exception& ex)
640 {
641 std::string what=ex.what();
642 what += "\nfor input port: ";
643 what += (*iter1)->getNode()->getName();
644 what += ".";
645 what += (*iter1)->getName();
646
648 throw YACS::Exception(what);
649 }
650 else
651 //No backlinks
652 if(!(*iter1)->canBeNull() && !(*iter1)->edIsManuallyInitialized())
653 info.pushErrLink(0,*iter1,E_NEVER_SET_INPUTPORT);
654 }
656}
657
663{
664 ComposedNode *nodeC=dynamic_cast<ComposedNode *>(node);
665 if(!nodeC)
666 return ;
667 list<ComposedNode *> ascendants=getAllAscendanceOf();
668 if(find(ascendants.begin(),ascendants.end(),nodeC)!=ascendants.end())
669 {
670 const char what[]="ComposedNode::checkNoCrossHierachyWith : ComposedNode with name \"";
671 string stream(what); stream+=node->getName(); stream+="\" is already in hierarchy ascendance of node with name \"";
672 stream+=_name; stream+="\" ; So it can't be now in its descendance !";
673 throw Exception(stream);
674 }
675}
676
679{
680 list<Node *> nodes=edGetDirectDescendants();
681 for(list<Node *>::iterator iter=nodes.begin();iter!=nodes.end();iter++)
682 if(dynamic_cast<ComposedNode *>(*iter))
683 ((ComposedNode *)(*iter))->performCFComputations(info);
684}
685
688{
689 list<Node *> nodes=edGetDirectDescendants();
690 for(list<Node *>::iterator iter=nodes.begin();iter!=nodes.end();iter++)
691 if(dynamic_cast<ComposedNode *>(*iter))
692 ((ComposedNode *)(*iter))->destructCFComputations(info);
693}
694
700Node *ComposedNode::getLowestNodeDealingAll(const std::list<OutPort *>& ports) const
701{
702 list< OutPort *>::const_iterator iter=ports.begin();
703 Node *ret=(*iter)->getNode();
704 iter++;
705 for(;iter!=ports.end();iter++)
706 {
707 Node *tmp=(*iter)->getNode();
708 if(*tmp>*ret)
709 ret=tmp;
710 }
711 return ret;
712}
713
717void ComposedNode::checkLinksCoherenceRegardingControl(const std::vector<OutPort *>& starts, InputPort *end, LinkInfo& info) const
718{
719 map < ComposedNode *, list<OutPort *>, SortHierarc > outputs;//forward link classical
720 vector<OutPort *> outputsCross;//forward link cross
721 map < ComposedNode *, list<OutPort *>, SortHierarc > outputsBw;//backward
722 vector<OutPort *>::const_iterator iter1;
723 //vector<DataPort *> history=((*iter1).second)[0]->calculateHistoryOfLinkWith(end);
724 //DataPort *cross=DataPort::isCrossingType(history);
725 for(iter1=starts.begin();iter1!=starts.end();iter1++)
726 {
727 ComposedNode *manager=getLowestCommonAncestor((*iter1)->getNode(),end->getNode());
728 manager->checkControlDependancy((*iter1), end, false, outputs, outputsCross, outputsBw, info);
729 }
730 //Ok now let's regarding outputs all combinations : (outputs.size())*(outputs.size()-1)/2
731 unsigned char isAlreadyFed=FREE_ST;
732 //Dealing excusively with DS. Level is useless here because simultaneity is required for DS.
733 if(outputsCross.size()>0)
734 {
735 isAlreadyFed=FED_DS_ST;
736 if(outputsCross.size()>1)
737 for(vector< OutPort *>::const_iterator iter1=outputsCross.begin();iter1!=(outputsCross.end()-2);iter1++)
738 info.pushErrLink(*iter1,end,E_COLLAPSE_DS);
739 }
740 map < ComposedNode *, list<OutPort *>, SortHierarc >::iterator iter3=outputs.begin();
741 for(;iter3!=outputs.end();iter3++)
742 ((*iter3).first)->checkCFLinks((*iter3).second,end,isAlreadyFed,true,info);
743 if(isAlreadyFed==FREE_ST)
744 if(!end->edIsManuallyInitialized())
746 isAlreadyFed=FREE_ST;
747 //
748 map < ComposedNode *, list<OutPort *>, SortHierarc >::reverse_iterator iter5=outputsBw.rbegin();
749 for(;iter5!=outputsBw.rend();iter5++)
750 ((*iter5).first)->checkCFLinks((*iter5).second,end,isAlreadyFed,false,info);
751}
752
757void ComposedNode::solveObviousOrDelegateCFLinks(const std::list<OutPort *>& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const
758{
759 static const char what[]="ComposedNode::solveObviousOrDelegateCFLinks : Internal error occured - uncorrect hierarchy detected !";
760 if(starts.size()==1)
761 {
762 if(alreadyFed==FREE_ST)
763 {
764 if(!direction)
765 info.pushInfoLink(*(starts.begin()),end,I_BACK);
766 alreadyFed=FED_ST;
767 }
768 else if(alreadyFed==FED_ST)
769 info.pushInfoLink(*(starts.begin()),end,direction ? I_USELESS : I_BACK_USELESS);
770 else
771 info.pushErrLink(*(starts.begin()),end,E_COLLAPSE_DFDS);
772 }
773 else
774 {
775 Node *levelOfDecision=getLowestNodeDealingAll(starts);
776 if(levelOfDecision==this)
777 throw Exception(what);
778 if(dynamic_cast<ElementaryNode *>(levelOfDecision))
779 {
780 WarnReason reason;
781 if(alreadyFed==FREE_ST || alreadyFed==FED_ST)
782 {
783 if(alreadyFed==FREE_ST)
784 {
785 reason=direction ? W_COLLAPSE_EL : W_BACK_COLLAPSE_EL;
786 alreadyFed=FED_ST;
787 }
788 else
790 for(list< OutPort *>::const_iterator iter=starts.begin();iter!=starts.end();iter++)
791 info.pushWarnLink(*iter,end,reason);
792 }
793 }
794 else
795 ((ComposedNode *)levelOfDecision)->checkCFLinks(starts,end,alreadyFed,direction,info);
796 }
797}
798
800
807void ComposedNode::checkCFLinks(const std::list<OutPort *>& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const
808{
809 static const char what[]="ComposedNode::checkCFLinks : Internal error occured - uncorrect hierarchy detected !";
810 Node *nodeEnd=isInMyDescendance(end->getNode());
811 if(!nodeEnd)
812 return solveObviousOrDelegateCFLinks(starts,end,alreadyFed,direction,info);
813 //This case is typically dedicated when direct son is ElementaryNode and self link is defined on this.
814 if(!dynamic_cast<ElementaryNode *>(nodeEnd))
815 throw Exception(what);
816
817 list< OutPort *>::const_iterator iter=starts.begin();
818 Node *nodeStart=(*iter)->getNode();
819 iter++;
820 if(nodeEnd!=nodeStart)
821 throw Exception(what);
822
823 for(;iter!=starts.end();iter++)
824 if((*iter)->getNode()!=nodeStart)
825 throw Exception(what);
826 //Ok at this step we are sure that we have back links on the same elementary node.
827 if(starts.size()>1)
828 for(iter=starts.begin();iter!=starts.end();iter++)
829 info.pushWarnLink(*iter,end,W_BACK_COLLAPSE_EL);
830 else//here no need to look at 'alreadyFed' var because it is waranteed to be equal to FREE_ST by construction.
831 info.pushInfoLink(*(starts.begin()),end,I_BACK);
832 alreadyFed=FED_ST;
833}
834
835std::vector< std::pair<InPort *, OutPort *> > ComposedNode::getSetOfLinksComingInCurrentScope() const
836{
837 vector< pair<InPort *, OutPort *> > ret;
839 for(set<InPort *>::iterator iter2=ports.begin();iter2!=ports.end();iter2++)
840 {
841 set<OutPort *> temp2=(*iter2)->edSetOutPort();
842 for(set<OutPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
843 {
844 if(isInMyDescendance((*iter3)->getNode()))continue;
845 std::set<OutPort *> trueOutPorts;
846 (*iter3)->getAllRepresented(trueOutPorts);
847 for(std::set<OutPort *>::iterator iter4=trueOutPorts.begin();iter4!=trueOutPorts.end();++iter4)
848 ret.push_back(pair<InPort *, OutPort *>(*iter2,*iter4));
849 }
850 }
851 return ret;
852}
853
855
862{
863 set<OutPort *> ret;
864 list<OutPort *> temp=getSetOfOutPort();
865 for(list<OutPort *>::iterator iter2=temp.begin();iter2!=temp.end();iter2++)
866 {
867 set<InPort *> temp2=(*iter2)->edSetInPort();
868 for(set<InPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
869 if(!isInMyDescendance((*iter3)->getNode()))
870 {
871 ret.insert(*iter2);
872 break;
873 }
874 }
875 return ret;
876}
877
879
886{
887 set<InPort *> ret;
888 list<InPort *> temp=getSetOfInPort();
889 for(list<InPort *>::iterator iter2=temp.begin();iter2!=temp.end();iter2++)
890 {
891 set<OutPort *> temp2=(*iter2)->edSetOutPort();
892 for(set<OutPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
893 if(*iter3)
894 if(!isInMyDescendance((*iter3)->getNode()))
895 {
896 ret.insert(*iter2);
897 break;
898 }
899 }
900 return ret;
901}
902
904{
905 //CF
906 DEBTRACE("-");
908 //Leaving part
909 DEBTRACE("--");
910 vector< pair<OutPort *, InPort *> > linksToDestroy=getSetOfLinksLeavingCurrentScope();
911 vector< pair<OutPort *, InPort *> >::iterator iter;
912 for(iter=linksToDestroy.begin();iter!=linksToDestroy.end();iter++)
913 {
914 DEBTRACE("---");
915 (*iter).first->removeInPort((*iter).second,true);
916 }
917 //Arriving part
918 vector< pair<InPort *, OutPort *> > linksToDestroy2=getSetOfLinksComingInCurrentScope();
919 vector< pair<InPort *, OutPort *> >::iterator iter2;
920 for(iter2=linksToDestroy2.begin();iter2!=linksToDestroy2.end();iter2++)
921 {
922 DEBTRACE("----");
923 (*iter2).second->removeInPort((*iter2).first,true);
924 }
925}
926
928{
929 if(!_father)
930 return (ComposedNode *)this;
931 return Node::getRootNode();
932}
933
936{
937 list<ComposedNode *> nodeAncestors = node->getAllAscendanceOf();
938 return find(nodeAncestors.begin(),nodeAncestors.end(),(ComposedNode *)this)!=nodeAncestors.end();
939}
940
942
950{
951 if(nodeToTest==0)
952 return 0;
953 if((ComposedNode *)nodeToTest==this)
954 return (Node *)this;
955 Node *iterBack=nodeToTest;
956 ComposedNode *iter=nodeToTest->_father;
957 while(iter!=0 && iter!=this)
958 {
959 iterBack=iter;
960 iter=iter->_father;
961 }
962 if(iter!=0)
963 return iterBack;
964 else
965 return 0;
966}
967
968string ComposedNode::getChildName(const Node* node) const
969{
970 string nodeName=node->getQualifiedName();
971 if (!isNodeAlreadyAggregated(node))
972 {
973 if (node->getName() == "thisIsAFakeNode")
974 {
975 string child = node->getName()+".thisIsAFakeNode";
976 return child;
977 }
978 else
979 {
980 string what("node "); what+= node->getName() ; what+=" is not a child of node "; what += getName();
981 throw Exception(what);
982 }
983 }
984
985 const Node *father = node->_father;
986 while (father != this)
987 {
988 nodeName = father->getQualifiedName() + SEP_CHAR_BTW_LEVEL + nodeName;
989 father = father->_father;
990 }
991 return nodeName;
992}
993
994std::string ComposedNode::getMyQualifiedName(const Node *directSon) const
995{
996 return directSon->getName();
997}
998
999Node *ComposedNode::getChildByName(const std::string& name) const
1000{
1001 string potentiallyDirectSonName, remainsPath;
1002 bool forwardNeeded=ComposedNode::splitNamesBySep(name, SEP_CHAR_BTW_LEVEL,
1003 potentiallyDirectSonName,remainsPath,false);
1004 Node *child=getChildByShortName(potentiallyDirectSonName);
1005 if(!forwardNeeded)
1006 return child;
1007 else
1008 return child->getChildByName(remainsPath);
1009}
1010
1012
1018{
1019 const char whatC[]=" is not the descendance of node ";
1020 if(nodeToTest==0)
1021 {
1022 string what("node "); what+= nodeToTest->getName(); what+=" ";
1023 what+=whatC; what+=_name;
1024 throw Exception(what);
1025 }
1026 if((ComposedNode *)nodeToTest==this)
1027 return;
1028 ComposedNode *iter=nodeToTest->_father;
1029 while(iter!=0 && iter!=this)
1030 iter=iter->_father;
1031 if(iter==0)
1032 {
1033 string what("node "); what+= nodeToTest->getName(); what+=" ";
1034 what+=whatC; what+=_name;
1035 throw Exception(what);
1036 }
1037}
1038
1040
1051{
1052 const char what[]="The two nodes do not share the same genealogy";
1053 if(node1==0 || node2==0)
1054 throw Exception(what);
1055 ComposedNode *temp;
1056 if(dynamic_cast<ComposedNode *>(node1))
1057 temp=(ComposedNode *)node1;//->_father;
1058 else
1059 temp=(ComposedNode *)node1->_father;
1060 set<ComposedNode *> s;
1061 while(temp)
1062 {
1063 s.insert(temp);
1064 temp=temp->_father;
1065 }
1066 //
1067 if(dynamic_cast<ComposedNode *>(node2))
1068 temp=(ComposedNode *)node2;//->_father;
1069 else
1070 temp=(ComposedNode *)node2->_father;
1071 set<ComposedNode *>::iterator iter=s.find(temp);
1072 while(temp && iter==s.end())
1073 {
1074 iter=s.find(temp);
1075 temp=temp->_father;
1076 }
1077 if(iter==s.end())
1078 throw Exception(what);
1079 return *iter;
1080}
1081
1085std::string ComposedNode::getLowestCommonAncestorStr(const std::string& node1, const std::string& node2)
1086{
1087 std::string ret;
1088 std::size_t it1_b(0),it1_e(0),it2_b(0),it2_e(0);
1089 while(it1_b!=std::string::npos && it2_b!=std::string::npos)
1090 {
1091 it1_e=node1.find(SEP_CHAR_BTW_LEVEL,it1_b);
1092 it2_e=node2.find(SEP_CHAR_BTW_LEVEL,it2_b);
1093 if(it1_e!=it2_e && it1_e!=std::string::npos && it2_e!=std::string::npos)
1094 break;
1095 std::string elt1(node1.substr(it1_b,it1_e-it1_b)),elt2(node2.substr(it2_b,it2_e-it2_b));
1096 if(elt1!=elt2)
1097 break;
1098 if(!ret.empty())
1099 ret+=SEP_CHAR_BTW_LEVEL;
1100 ret+=elt1;
1101 it1_b=node1.find_first_not_of(SEP_CHAR_BTW_LEVEL,it1_e);
1102 it2_b=node2.find_first_not_of(SEP_CHAR_BTW_LEVEL,it2_e);
1103 }
1104 return ret;
1105}
1106
1111{
1112 std::list<Node *> dd(edGetDirectDescendants());
1113 for(std::list<Node *>::const_iterator it=dd.begin();it!=dd.end();it++)
1114 {
1115 ComposedNode *elt(dynamic_cast<ComposedNode *>(*it));
1116 if(elt)
1118 }
1119}
1120
1121list<ElementaryNode *> ComposedNode::getRecursiveConstituents() const
1122{
1123 list<ElementaryNode *> ret;
1124 list<Node *> setOfNode=edGetDirectDescendants();
1125 for(list<Node *>::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1126 {
1127 list<ElementaryNode *> myCurrentSet=(*iter)->getRecursiveConstituents();
1128 ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end());
1129 }
1130 return ret;
1131}
1132
1135{
1136 list<Node *> ret;
1137 list<Node *> setOfNode=edGetDirectDescendants();
1138 for(list<Node *>::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1139 {
1140 if ( dynamic_cast<ComposedNode*> (*iter) )
1141 {
1142 list<Node *> myCurrentSet=((ComposedNode*)(*iter))->getAllRecursiveConstituents();
1143 ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end());
1144 ret.push_back(*iter);
1145 }
1146 else
1147 {
1148 list<ElementaryNode *> myCurrentSet=(*iter)->getRecursiveConstituents();
1149 ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end());
1150 }
1151 }
1152 return ret;
1153}
1154
1157{
1158 list<Node *> ret;
1159 list<Node *> setOfNode=edGetDirectDescendants();
1160 for(list<Node *>::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1161 {
1162 if ( dynamic_cast<ElementaryNode*> (*iter) )
1163 {
1164 list<ElementaryNode *> myCurrentSet=(*iter)->getRecursiveConstituents();
1165 ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end());
1166 }
1167 else
1168 {
1169 list<Node *> myCurrentSet=((ComposedNode*)(*iter))->getAllRecursiveNodes();
1170 ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end());
1171 }
1172 }
1173 ret.push_back(this);
1174 return ret;
1175}
1176
1177
1179
1183list<ProgressWeight> ComposedNode::getProgressWeight() const
1184{
1185 list<ProgressWeight> ret;
1186 list<Node *> setOfNode=edGetDirectDescendants();
1187 for(list<Node *>::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1188 {
1189 list<ProgressWeight> myCurrentSet=((ComposedNode*)(*iter))->getProgressWeight();
1190 ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end());
1191 }
1192 return ret;
1193}
1194
1196
1200string ComposedNode::getInPortName(const InPort * inPort) const
1201{
1202 return getPortName<InPort>(inPort);
1203}
1204
1205string ComposedNode::getOutPortName(const OutPort *outPort) const
1206{
1207 return getPortName<OutPort>(outPort);
1208}
1209
1211{
1212 list<Node *> constituents=edGetDirectDescendants();
1213 int ret=0;
1214 for(list<Node *>::iterator iter=constituents.begin();iter!=constituents.end();iter++)
1215 ret+=(*iter)->getNumberOfInputPorts();
1216 return ret;
1217}
1218
1220{
1221 list<Node *> constituents=edGetDirectDescendants();
1222 int ret=0;
1223 for(list<Node *>::iterator iter=constituents.begin();iter!=constituents.end();iter++)
1224 ret+=(*iter)->getNumberOfOutputPorts();
1225 return ret;
1226}
1227
1228list<InputPort *> ComposedNode::getSetOfInputPort() const
1229{
1230 list<Node *> constituents=edGetDirectDescendants();
1231 list<InputPort *> ret;
1232 for(list<Node *>::iterator iter=constituents.begin();iter!=constituents.end();iter++)
1233 {
1234 list<InputPort *> currentsPorts=(*iter)->getSetOfInputPort();
1235 ret.insert(ret.end(),currentsPorts.begin(),currentsPorts.end());
1236 }
1237 return ret;
1238}
1239
1240list<OutputPort *> ComposedNode::getSetOfOutputPort() const
1241{
1242 list<Node *> constituents=edGetDirectDescendants();
1243 list<OutputPort *> ret;
1244 for(list<Node *>::iterator iter=constituents.begin();iter!=constituents.end();iter++)
1245 {
1246 list<OutputPort *> currentsPorts=(*iter)->getSetOfOutputPort();
1247 ret.insert(ret.end(),currentsPorts.begin(),currentsPorts.end());
1248 }
1249 return ret;
1250}
1251
1252list<InputDataStreamPort *> ComposedNode::getSetOfInputDataStreamPort() const
1253{
1254 list<Node *> constituents=edGetDirectDescendants();
1255 list<InputDataStreamPort *> ret;
1256 for(list<Node *>::iterator iter=constituents.begin();iter!=constituents.end();iter++)
1257 {
1258 list<InputDataStreamPort *> currentsPorts=(*iter)->getSetOfInputDataStreamPort();
1259 ret.insert(ret.end(),currentsPorts.begin(),currentsPorts.end());
1260 }
1261 return ret;
1262}
1263
1264list<OutputDataStreamPort *> ComposedNode::getSetOfOutputDataStreamPort() const
1265{
1266 list<Node *> constituents=edGetDirectDescendants();
1267 list<OutputDataStreamPort *> ret;
1268 for(list<Node *>::iterator iter=constituents.begin();iter!=constituents.end();iter++)
1269 {
1270 list<OutputDataStreamPort *> currentsPorts=(*iter)->getSetOfOutputDataStreamPort();
1271 ret.insert(ret.end(),currentsPorts.begin(),currentsPorts.end());
1272 }
1273 return ret;
1274}
1275
1276OutPort *ComposedNode::getOutPort(const std::string& name) const
1277{
1278 string portName, nodeName;
1279 if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,false))
1280 {
1281 Node *child = getChildByShortName(nodeName);
1282 return child->getOutPort(portName);
1283 }
1284 else
1285 {
1286 string what("ComposedNode::getOutPort : the port with name "); what+=name; what+=" does not exist on the current level";
1287 throw Exception(what);
1288 }
1289}
1290
1292
1297InputPort * ComposedNode::getInputPort(const std::string& name) const
1298{
1299 try {
1300 return Node::getInputPort(name);
1301 }
1302 catch(Exception& e) {}
1303
1304 string portName, nodeName;
1305 if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,true))
1306 {
1307 Node *child = getChildByName(nodeName);
1308 return child->getInputPort(portName);
1309 }
1310 else
1311 {
1312 string what("ComposedNode::getInputPort : the port with name "); what+=name; what+=" does not exist on the current level";
1313 throw Exception(what);
1314 }
1315}
1316
1318
1322OutputPort * ComposedNode::getOutputPort(const std::string& name) const
1323{
1324 string portName, nodeName;
1325 if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,false))
1326 {
1327 Node *child = getChildByShortName(nodeName);
1328 return child->getOutputPort(portName);
1329 }
1330 else
1331 {
1332 string what("ComposedNode::getOutputPort : the port with name "); what+=name; what+=" does not exist on the current level";
1333 throw Exception(what);
1334 }
1335}
1336
1338{
1339 string portName, nodeName;
1340 if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,true))
1341 {
1342 Node *child = getChildByName(nodeName);
1343 return child->getInputDataStreamPort(portName);
1344 }
1345 else
1346 {
1347 string what("ComposedNode::getInputDataStreamPort : the port with name "); what+=name; what+=" does not exist on the current level";
1348 throw Exception(what);
1349 }
1350}
1351
1353{
1354 string portName, nodeName;
1355 if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,true))
1356 {
1357 Node *child = getChildByName(nodeName);
1358 return child->getOutputDataStreamPort(portName);
1359 }
1360 else
1361 {
1362 string what("ComposedNode::getOutputDataStreamPort : the port with name "); what+=name; what+=" does not exist on the current level";
1363 throw Exception(what);
1364 }
1365}
1366
1368
1382YACS::Event ComposedNode::updateStateFrom(Node *node, //* I : node emitting event
1383 YACS::Event event, //* I : event emitted
1384 const Executor *execInst
1385 )
1386{
1387 DEBTRACE("updateStateFrom: " << node->getName() << " " << event);
1388 try
1389 {
1390 switch(event)
1391 {
1392 case YACS::START:
1393 return updateStateOnStartEventFrom(node);
1394 break;
1395 case YACS::FINISH:
1396 return updateStateOnFinishedEventFrom(node);
1397 break;
1398 case YACS::ABORT:
1399 return updateStateOnFailedEventFrom(node,execInst);
1400 break;
1401 default:
1402 return YACS::NOEVENT;//TODO unexpected type of event
1403 break;
1404 }
1405 }
1406 catch(YACS::Exception& ex)
1407 {
1408 //unexpected exception: probably a bug in engine
1409 //try to keep a consistent global state
1410 DEBTRACE( "updateStateFrom: " << ex.what() );
1411 _errorDetails="Internal error: ";
1415 return YACS::ABORT;
1416 }
1417 catch(...)
1418 {
1419 //unexpected exception: probably a bug in engine
1420 //try to keep a consistent global state
1423 return YACS::ABORT;
1424 }
1425}
1426
1428
1435{
1437 return YACS::START;
1438}
1439
1442{
1444 return YACS::ABORT;
1445}
1446
1447void ComposedNode::checkLinkPossibility(OutPort *start, const std::list<ComposedNode *>& pointsOfViewStart,
1448 InPort *end, const std::list<ComposedNode *>& pointsOfViewEnd)
1449{
1450 if((dynamic_cast<DataFlowPort *>(start) || dynamic_cast<DataFlowPort *>(end))
1451 && (dynamic_cast<DataStreamPort *>(start) || dynamic_cast<DataStreamPort *>(end)))
1452 {//cross protocol required : deeper check needed
1453 bool isOK=false;
1454 list<ComposedNode *>::const_iterator iter;
1455 for(iter=pointsOfViewStart.begin();iter!=pointsOfViewStart.end() && !isOK;iter++)
1456 isOK=(*iter)->isRepeatedUnpredictablySeveralTimes();
1457 for(iter=pointsOfViewEnd.begin();iter!=pointsOfViewEnd.end() && !isOK;iter++)
1458 isOK=(*iter)->isRepeatedUnpredictablySeveralTimes();
1459 if(!isOK)
1460 throw Exception("ComposedNode::checkLinkPossibility : Request for cross protocol link impossible.");
1461 }
1462}
1463
1464void ComposedNode::buildDelegateOf(InPort * & port, OutPort *initialStart, const std::list<ComposedNode *>& pointsOfView)
1465{
1466}
1467
1468void ComposedNode::buildDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView)
1469{
1470}
1471
1472void ComposedNode::getDelegateOf(InPort * & port, OutPort *initialStart, const std::list<ComposedNode *>& pointsOfView)
1473{
1474}
1475
1476void ComposedNode::getDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView)
1477{
1478}
1479
1480void ComposedNode::releaseDelegateOf(InPort * & port, OutPort *initialStart, const std::list<ComposedNode *>& pointsOfView)
1481{
1482}
1483
1484void ComposedNode::releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView)
1485{
1486}
1487
1489{
1490}
1492{
1493}
1494
1496{
1497 list<Node *> constituents=edGetDirectDescendants();
1498 for(list<Node *>::iterator iter=constituents.begin(); iter!=constituents.end(); iter++)
1499 {
1500 (*iter)->accept(visitor);
1501 }
1502}
1503
1504void ComposedNode::setProperty(const std::string& name,const std::string& value)
1505{
1506 Node::setProperty(name, value);
1507}
1508
1509std::string ComposedNode::getProperty(const std::string& name)
1510{
1511 return Node::getProperty(name);
1512}
1513
1514
1516std::list<InputPort *> ComposedNode::getLocalInputPorts() const
1517{
1518 std::list<InputPort *> lip; return lip; // empty list
1519}
1520
1522std::list<OutputPort *> ComposedNode::getLocalOutputPorts() const
1523{
1524 std::list<OutputPort *> lop; return lop; // empty list
1525}
1526
1527bool ComposedNode::isNameAlreadyUsed(const std::string& name) const
1528{
1529 return false;
1530}
1531
1533{
1534 DEBTRACE("ComposedNode::edUpdateState(): " << _state << " " << _modified);
1536
1537 try
1538 {
1540 _errorDetails="";
1541 }
1542 catch(Exception& e)
1543 {
1545 _errorDetails=e.what();
1546 }
1547 DEBTRACE("ComposedNode::edUpdateState: " << _errorDetails);
1548
1549 //update children if needed
1550 list<Node *> constituents=edGetDirectDescendants();
1551 for(list<Node *>::iterator iter=constituents.begin(); iter!=constituents.end(); iter++)
1552 {
1553 if(!(*iter)->isValid())
1555 }
1556 if(state != _state)
1557 setState(state);
1558 _modified=0;
1559}
1560
1562{
1563 DEBTRACE("ComposedNode::getErrorReport: " << getName() << " " << _state);
1564 YACS::StatesForNode effectiveState=getEffectiveState();
1565
1566 if(effectiveState != YACS::INVALID && effectiveState != YACS::ERROR && effectiveState != YACS::FAILED)
1567 return "";
1568
1569 std::string report="<error node= " + getName();
1570 switch(effectiveState)
1571 {
1572 case YACS::INVALID:
1573 report=report+" state= INVALID";
1574 break;
1575 case YACS::ERROR:
1576 report=report+" state= ERROR";
1577 break;
1578 case YACS::FAILED:
1579 report=report+" state= FAILED";
1580 break;
1581 default:
1582 break;
1583 }
1584 report=report + ">\n" ;
1585 if(_errorDetails != "")
1586 report=report+_errorDetails+"\n";
1587
1588 list<Node *> constituents=edGetDirectDescendants();
1589 for(list<Node *>::iterator iter=constituents.begin(); iter!=constituents.end(); iter++)
1590 {
1591 std::string rep=(*iter)->getErrorReport();
1592 if(rep != "")
1593 {
1594 report=report+rep+"\n";
1595 }
1596 }
1597 report=report+"</error>";
1598 return report;
1599}
1600
1601
1602
1604{
1605 DEBTRACE("ComposedNode::checkBasicConsistency");
1606 std::list<InputPort *>::const_iterator iter;
1607 std::list<InputPort *> inports=getLocalInputPorts();
1608 for(iter=inports.begin();iter!=inports.end();iter++)
1609 (*iter)->checkBasicConsistency();
1610}
1611
1613
1617{
1618 if(level==0)return;
1619 DEBTRACE("ComposedNode::shutdown");
1620 list<Node *> nodes=edGetDirectDescendants();
1621 for(list<Node *>::iterator iter=nodes.begin();iter!=nodes.end();iter++)
1622 (*iter)->shutdown(level);
1623}
1624
1626
1630{
1631 DEBTRACE("ComposedNode::cleanNodes");
1632 list<Node *> nodes=edGetDirectDescendants();
1633 for(list<Node *>::iterator iter=nodes.begin();iter!=nodes.end();iter++)
1634 (*iter)->cleanNodes();
1635}
1636
1639{
1640 if(level==0)return;
1641
1642 DEBTRACE("ComposedNode::resetState " << level << "," << _state);
1644 {
1645 Node::resetState(level);
1646 std::list<Node *> nodes=edGetDirectDescendants();
1647 for(std::list<Node *>::iterator iter=nodes.begin();iter!=nodes.end();iter++)
1648 (*iter)->resetState(level);
1649 }
1650}
#define DEBTRACE(msg)
Definition: YacsTrace.hxx:31
Base class for all component instances.
virtual bool setContainer(Container *cont)
virtual ComponentInstance * clone() const =0
Base class for all composed nodes.
std::list< InputDataStreamPort * > getSetOfInputDataStreamPort() const
std::string getChildName(const Node *node) const
Node * getChildByName(const std::string &name) const
static const unsigned char FREE_ST
DeploymentTree checkDeploymentTree(bool deep) const
Perform check of deployment consistency of the current graph.
std::list< ProgressWeight > getProgressWeight() const
Get the progress weight for all elementary nodes.
std::list< InputPort * > getSetOfInputPort() const
virtual void buildDelegateOf(InPort *&port, OutPort *initialStart, const std::list< ComposedNode * > &pointsOfView)
std::list< ElementaryNode * > getRecursiveConstituents() const
std::list< Node * > getAllRecursiveNodes()
Get all children nodes elementary and composed including this node.
void performDuplicationOfPlacement(const Node &other)
performs a duplication of placement using clone method of containers and components....
std::list< OutputPort * > getLocalOutputPorts() const
redefined on derived class of ComposedNode. by default a ComposedNode has no port by itself
virtual void getDelegateOf(InPort *&port, OutPort *initialStart, const std::list< ComposedNode * > &pointsOfView)
OutPort * getOutPort(const std::string &name) const
DeploymentTree getDeploymentTree() const
Essentially for test. Use checkDeploymentTree instead to be sure that returned DeploymentTree is cons...
std::vector< std::pair< OutPort *, InPort * > > getSetOfInternalLinks() const
void checkNoCrossHierachyWith(Node *node) const
virtual bool isNameAlreadyUsed(const std::string &name) const
std::string getName() const
void edRemoveCFLink(Node *nodeS, Node *nodeE)
Remove a controlflow link.
void solveObviousOrDelegateCFLinks(const std::list< OutPort * > &starts, InputPort *end, unsigned char &alreadyFed, bool direction, LinkInfo &info) const
void performShallowDuplicationOfPlacement(const Node &other)
performs a also duplication of placement but here containers and components are not copied at all wha...
OutputPort * getOutputPort(const std::string &name) const
Get an output port given its name.
static const char SEP_CHAR_BTW_LEVEL[]
InputPort * getInputPort(const std::string &name) const
Get an input port given its name.
virtual std::list< Node * > getAllRecursiveConstituents()
Idem getAllRecursiveNodes, but this node is NOT included.
std::list< OutputPort * > getSetOfOutputPort() const
std::list< InputPort * > getLocalInputPorts() const
redefined on derived class of ComposedNode. by default a ComposedNode has no port by itself
Node * getLowestNodeDealingAll(const std::list< OutPort * > &ports) const
virtual void edRemoveChild(Node *node)
Remove a child node.
virtual void edUpdateState()
update the status of the node
virtual void checkBasicConsistency() const
bool isNodeAlreadyAggregated(const Node *node) const
Check that Node 'node' is already a direct son of this.
virtual std::string getErrorReport()
returns a string that contains an error report if the node is in error
std::set< OutPort * > getAllOutPortsLeavingCurrentScope() const
List all output ports of children nodes that are linked to out of scope input ports.
static std::string getLowestCommonAncestorStr(const std::string &node1, const std::string &node2)
YACS::Event updateStateFrom(Node *node, YACS::Event event, const Executor *execInst)
Update node state on receiving event from a node.
void checkLinksCoherenceRegardingControl(const std::vector< OutPort * > &starts, InputPort *end, LinkInfo &info) const
std::list< OutputDataStreamPort * > getSetOfOutputDataStreamPort() const
virtual void removeRecursivelyRedundantCL()
virtual bool isLoop() const
virtual std::vector< std::pair< OutPort *, InPort * > > getSetOfLinksLeavingCurrentScope() const
virtual void shutdown(int level)
Stop all pending activities of the composed node.
virtual void performCFComputations(LinkInfo &info) const
perform recursively all CF computations.
std::string getProperty(const std::string &name) override
virtual std::string getMyQualifiedName(const Node *directSon) const
static bool splitNamesBySep(const std::string &globalName, const char separator[], std::string &firstPart, std::string &lastPart, bool priority)
Splits name globalName in 2 parts using separator.
void checkInMyDescendance(Node *nodeToTest) const
Check if a node is in the descendance of this node.
static const unsigned char FED_ST
virtual bool edAddDFLink(OutPort *start, InPort *end)
Connect an OutPort to an InPort and add the necessary control link.
std::string getOutPortName(const OutPort *) const
std::string getInPortName(const InPort *) const
Get the input port name.
virtual void resetState(int level)
Reset the state of the node and its children depending on the parameter level.
std::set< InPort * > getAllInPortsComingFromOutsideOfCurrentScope() const
List all input ports that are linked to out of scope ports.
virtual void releaseDelegateOf(InPort *&port, OutPort *initialStart, const std::list< ComposedNode * > &pointsOfView)
virtual void checkNoCyclePassingThrough(Node *node)=0
virtual std::list< Node * > edGetDirectDescendants() const =0
OutputDataStreamPort * getOutputDataStreamPort(const std::string &name) const
virtual YACS::Event updateStateOnFailedEventFrom(Node *node, const Executor *execInst)
Method used to notify the node that a child node has failed.
virtual YACS::Event updateStateOnFinishedEventFrom(Node *node)=0
std::string getTaskName(Task *task) const
virtual void checkControlDependancy(OutPort *start, InPort *end, bool cross, std::map< ComposedNode *, std::list< OutPort * >, SortHierarc > &fw, std::vector< OutPort * > &fwCross, std::map< ComposedNode *, std::list< OutPort * >, SortHierarc > &bw, LinkInfo &info) const =0
void accept(Visitor *visitor)
virtual void cleanNodes()
Clean the composed node in case of not clean exit.
virtual bool edAddChild(Node *DISOWNnode)
void init(bool start=true)
static const unsigned char FED_DS_ST
bool edAddCFLink(Node *nodeS, Node *nodeE)
Add a controlflow link between two nodes.
bool edAddLink(OutPort *start, InPort *end)
Add a dataflow link between two data ports.
virtual void destructCFComputations(LinkInfo &info) const
destroy recursively all results of initial computations.
void setProperty(const std::string &name, const std::string &value) override
void checkConsistency(LinkInfo &info) const
void edRemoveLink(OutPort *start, InPort *end)
Remove a dataflow link.
std::vector< Task * > getNextTasks(bool &isMore)
Node * isInMyDescendance(Node *nodeToTest) const
Returns the parent of a node that is the direct child of this node.
virtual void checkLinkPossibility(OutPort *start, const std::list< ComposedNode * > &pointsOfViewStart, InPort *end, const std::list< ComposedNode * > &pointsOfViewEnd)
static ComposedNode * getLowestCommonAncestor(Node *node1, Node *node2)
Retrieves the lowest common ancestor of 2 nodes.
InputDataStreamPort * getInputDataStreamPort(const std::string &name) const
virtual Node * getChildByShortName(const std::string &name) const =0
virtual std::vector< std::pair< InPort *, OutPort * > > getSetOfLinksComingInCurrentScope() const
ComposedNode * getRootNode() const
virtual void checkCFLinks(const std::list< OutPort * > &starts, InputPort *end, unsigned char &alreadyFed, bool direction, LinkInfo &info) const
check control flow links
void notifyFrom(const Task *sender, YACS::Event event, const Executor *execInst)
Notify the node a task has emitted an event.
virtual YACS::Event updateStateOnStartEventFrom(Node *node)
Method used to notify the node that a child node has started.
virtual Container * clone() const =0
WARNING ! clone behaviour MUST be in coherence with what is returned by isAttachedOnCloning() method
std::string getName() const
Definition: DataPort.hxx:55
std::vector< Task * > getTasksLinkedToComponent(ComponentInstance *comp) const
std::vector< ComponentInstance * > getComponentsLinkedToContainer(Container *cont) const
std::vector< Task * > getTasksLinkedToContainer(Container *cont) const
static const unsigned char DUP_TASK_NOT_COMPATIBLE_WITH_EXISTING_TREE
static const unsigned char DEPLOYABLE_BUT_NOT_SPECIFIED
unsigned char appendTask(Task *task, Scheduler *cloner)
std::vector< Container * > getAllContainers() const
Base class for all calculation nodes.
Threaded Executor.
Definition: Executor.hxx:63
virtual void edNotifyDereferencedBy(OutPort *fromPort)
Definition: InPort.cxx:102
virtual void edNotifyReferencedBy(OutPort *fromPort, bool isLoopProof=true)
Definition: InPort.cxx:93
Class for calculation node (function) inlined (and executed) in the schema.
Definition: InlineNode.hxx:93
virtual void setContainer(Container *container)
Definition: InlineNode.cxx:105
Base class for Input Ports.
Definition: InputPort.hxx:44
virtual bool edIsManuallyInitialized() const
Specifies if this port has been manually set by the call of InputPort::edInit.
Definition: InputPort.cxx:76
Class that deal with list of semantics links for high level analysis.
Definition: LinkInfo.hxx:83
void pushErrLink(OutPort *semStart, InPort *end, ErrReason reason)
Definition: LinkInfo.cxx:86
void pushInfoLink(OutPort *semStart, InPort *end, InfoReason reason)
Definition: LinkInfo.cxx:71
void pushWarnLink(OutPort *semStart, InPort *end, WarnReason reason)
Definition: LinkInfo.cxx:76
void setPointOfView(ComposedNode *pov)
Definition: LinkInfo.cxx:66
Base class for all nodes.
Definition: Node.hxx:70
std::string _name
Definition: Node.hxx:89
friend class ComposedNode
Definition: Node.hxx:79
virtual ComposedNode * getRootNode() const
Definition: Node.cxx:431
ComposedNode * _father
Definition: Node.hxx:90
virtual void setProperty(const std::string &name, const std::string &value)
Definition: Node.cxx:491
virtual void getReadyTasks(std::vector< Task * > &tasks)=0
const std::string & getName() const
Definition: Node.hxx:125
ComposedNode * getFather() const
Definition: Node.hxx:127
virtual void modified()
Sets Node in modified state and its father if it exists.
Definition: Node.cxx:805
std::string getQualifiedName() const
same as Node::getName() in most cases, but differs for children of switch
Definition: Node.cxx:632
static ComposedNode * checkHavingCommonFather(Node *node1, Node *node2)
Definition: Node.cxx:468
virtual Node * getChildByName(const std::string &name) const =0
virtual void init(bool start=true)
Definition: Node.cxx:102
virtual OutPort * getOutPort(const std::string &name) const
Definition: Node.cxx:275
OutGate * getOutGate()
Definition: Node.hxx:124
virtual OutputPort * getOutputPort(const std::string &name) const =0
InGate * getInGate()
Definition: Node.hxx:123
std::list< OutPort * > getSetOfOutPort() const
Definition: Node.cxx:299
std::list< ComposedNode * > getAllAscendanceOf(ComposedNode *levelToStop=0) const
Definition: Node.cxx:317
virtual void resetState(int level)
Reset the node state depending on the parameter level.
Definition: Node.cxx:851
std::list< InPort * > getSetOfInPort() const
Definition: Node.cxx:289
void setState(YACS::StatesForNode theState)
Sets the given state for node.
Definition: Node.cxx:652
virtual OutputDataStreamPort * getOutputDataStreamPort(const std::string &name) const =0
static const char SEP_CHAR_IN_PORT[]
Definition: Node.hxx:94
virtual InputPort * getInputPort(const std::string &name) const
Definition: Node.cxx:260
virtual void exForwardFailed()
Definition: Node.cxx:378
virtual InputDataStreamPort * getInputDataStreamPort(const std::string &name) const =0
std::string _errorDetails
Definition: Node.hxx:93
virtual YACS::StatesForNode getEffectiveState() const
Return the node state in the context of its father.
Definition: Node.cxx:538
YACS::StatesForNode _state
Definition: Node.hxx:91
virtual std::string getProperty(const std::string &name)
Definition: Node.cxx:497
virtual void edDisconnectAllLinksWithMe()
Definition: Node.cxx:395
void edRemoveInGate(InGate *inGate, bool coherenceWithInGate=true)
Definition: OutGate.cxx:120
bool edAddInGate(InGate *inGate)
Definition: OutGate.cxx:98
virtual bool isAlreadyLinkedWith(InPort *withp) const =0
virtual void getAllRepresented(std::set< OutPort * > &represented) const
Definition: OutPort.cxx:45
Node * getNode() const
Definition: Port.hxx:46
Class for calculation node associated with a component service.
Definition: ServiceNode.hxx:35
virtual void setComponent(ComponentInstance *compo)
Associate an existing component instance to this service node AND check the consistency regarding the...
const char * what(void) const noexcept
Definition: Exception.cxx:50
@ E_NEVER_SET_INPUTPORT
Definition: LinkInfo.hxx:69
@ E_ONLY_BACKWARD_DEFINED
Definition: LinkInfo.hxx:70
@ W_COLLAPSE_EL_AND_USELESS
Definition: LinkInfo.hxx:59
@ W_BACK_COLLAPSE_EL
Definition: LinkInfo.hxx:62
@ W_BACK_COLLAPSE_EL_AND_USELESS
Definition: LinkInfo.hxx:63
Event
Definition: define.hxx:56
@ ABORT
Definition: define.hxx:60
@ NOEVENT
Definition: define.hxx:57
@ START
Definition: define.hxx:58
@ FINISH
Definition: define.hxx:59
StatesForNode
Definition: define.hxx:34
@ INVALID
Definition: define.hxx:36
@ FAILED
Definition: define.hxx:51
@ READY
Definition: define.hxx:37
@ ACTIVATED
Definition: define.hxx:41
@ DONE
Definition: define.hxx:43
@ DISABLED
Definition: define.hxx:50
@ ERROR
Definition: define.hxx:52