1 // Copyright (C) 2006-2022 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 #include "Visitor.hxx"
22 #include "LinkInfo.hxx"
29 #include "YacsTrace.hxx"
31 using namespace YACS::ENGINE;
34 const char Switch::DEFAULT_NODE_NAME[]="default";
35 const int Switch::ID_FOR_DEFAULT_NODE=-1973012217;
36 const char Switch::SELECTOR_INPUTPORT_NAME[]="select";
38 int CollectorSwOutPort::edGetNumberOfOutLinks() const
43 std::set<InPort *> CollectorSwOutPort::edSetInPort() const
47 ret.insert(_consumer);
51 bool CollectorSwOutPort::isAlreadyLinkedWith(InPort *with) const
54 with->getAllRepresentants(s);
55 return s.find(_consumer)!=s.end();
58 std::string CollectorSwOutPort::getNameOfTypeOfCurrentInstance() const
63 void CollectorSwOutPort::edRemoveAllLinksLinkedWithMe()
65 map<int, OutPort *>::iterator pt;
67 for(pt=_potentialProducers.begin();pt!=_potentialProducers.end();pt++)
68 ((*pt).second)->removeInPort(_consumer,true);
71 TypeOfChannel CollectorSwOutPort::getTypeOfChannel() const
73 return (*(_potentialProducers.begin())).second->getTypeOfChannel();
76 void CollectorSwOutPort::getAllRepresented(std::set<OutPort *>& represented) const
78 map<int, OutPort *>::const_iterator pt;
79 for(pt=_potentialProducers.begin();pt!=_potentialProducers.end();pt++)
80 ((*pt).second)->getAllRepresented(represented);
83 bool CollectorSwOutPort::addInPort(InPort *inPort)
87 {//a specific link is beeing done
88 ret=_currentProducer->addInPort(inPort);
91 else//global links asked
92 for(map<int, OutPort *>::iterator iter=_potentialProducers.begin();iter!=_potentialProducers.end();iter++)
93 ret |= (*iter).second->addInPort(inPort);
97 int CollectorSwOutPort::removeInPort(InPort *inPort, bool forward)
101 return _currentProducer->removeInPort(inPort,forward);
104 throw Exception("CollectorSwOutputPort::edRemoveInputPort : internal error on link removal.");
109 * \note : 'master' specifies the instance of Switch of which 'this' collects all of these direct
110 * or indirect outports going to the same port 'port' (which is out of scope of 'master').
112 CollectorSwOutPort::CollectorSwOutPort(Switch *master, InPort *port):OutPort("",master,port->edGetType()),
113 DataPort("",master,port->edGetType()),
115 _consumer(port),_currentProducer(0)
117 _name="Representant_of_"; _name+=master->getName(); _name+="_for_inport_"; _name+=master->getRootNode()->getInPortName(_consumer);
120 CollectorSwOutPort::CollectorSwOutPort(const CollectorSwOutPort& other, Switch *master):OutPort("",master,other.edGetType()),
121 DataPort("",master,other.edGetType()),
123 _consumer(0),_currentProducer(0)
126 Switch *othSw=(Switch *)other._node;
127 for(map<int, OutPort *>::const_iterator iter=other._potentialProducers.begin();iter!=other._potentialProducers.end();iter++)
129 string name=othSw->getOutPortName((*iter).second);
130 _potentialProducers[(*iter).first]=master->getOutPort(name);
134 void CollectorSwOutPort::addPotentialProducerForMaster(OutPort *port)
136 int i=((Switch *)_node)->getRankOfNode(port->getNode());
137 map<int, OutPort *>::iterator pt=_potentialProducers.find(i);
138 if(pt==_potentialProducers.end())
140 _potentialProducers[i]=port;
141 _currentProducer=port;
145 _currentProducer=(*pt).second;
146 if(_currentProducer!=port)
148 string what("CollectorSwOutPort::addPotentialProducerForMaster : In switch node "); what+=_node->getName();
149 what+=" for input named \'"; what+=_consumer->getName(); what+="\' the output "; what+=_currentProducer->getName();
150 what+=" already got out for case of label ";
151 what+=Switch::getRepresentationOfCase((*pt).first);
152 throw Exception(what);
155 _className=port->getNameOfTypeOfCurrentInstance();
158 bool CollectorSwOutPort::removePotentialProducerForMaster()
161 map<int, OutPort *>::iterator result;
162 for(result=_potentialProducers.begin();result!=_potentialProducers.end();result++)
163 if((*result).second==_currentProducer)
168 if(result==_potentialProducers.end())
170 ostringstream stream; stream << "CollectorSwOutPort::removePotentialProducerForMaster : link from the branch whith id ";
171 stream << i << " not defined";
172 throw Exception(stream.str());
174 if((*result).second!=_currentProducer)
176 ostringstream stream; stream << "CollectorSwOutPort::removePotentialProducerForMaster : link from the branch whith id ";
177 stream << i << " defined but the output specified is not compatible";
178 throw Exception(stream.str());
180 _potentialProducers.erase(result);
181 return _potentialProducers.empty();
184 bool CollectorSwOutPort::checkManagementOfPort(OutPort *port)
186 for(map<int, OutPort *>::iterator iter=_potentialProducers.begin();iter!=_potentialProducers.end();iter++)
187 if((*iter).second==port)
189 _currentProducer=port;
190 return _potentialProducers.size()==1;
192 throw Exception("CollectorSwOutPort::checkManagementOfPort : unexported port");
196 * Called by Switch::checkCFLinks.
198 void CollectorSwOutPort::checkConsistency(LinkInfo& info) const
200 if(((Switch *)_node)->getNbOfCases()!=_potentialProducers.size())
201 info.pushErrSwitch((CollectorSwOutPort *)this);
202 for(map<int, OutPort *>::const_iterator iter=_potentialProducers.begin();iter!=_potentialProducers.end();iter++)
203 (*iter).second->checkConsistency(info);
207 * Called by LinkInfo::getErrRepr to have a comprehensible message on throw.
208 * When called, typically checkCompletenessOfCases has detected that some potential producers were laking...
210 void CollectorSwOutPort::getHumanReprOfIncompleteCases(std::ostream& stream) const
212 set<int> lackingCases;
213 for(map< int ,Node * >::const_iterator iter=((Switch *)_node)->_mapOfNode.begin();iter!=((Switch *)_node)->_mapOfNode.end();iter++)
215 if(_potentialProducers.find((*iter).first)==_potentialProducers.end())
216 lackingCases.insert((*iter).first);
218 ostringstream streamForExc;
219 stream << "For link to " << _consumer->getName() << " of node " << _consumer->getNode()->getName()
220 << " the cases of switch node named " << _node->getName()
221 << " do not define links for following cases ids :";
222 for(set<int>::iterator iter=lackingCases.begin();iter!=lackingCases.end();iter++)
223 stream << Switch::getRepresentationOfCase(*iter) << " ";
227 FakeNodeForSwitch::FakeNodeForSwitch(Switch *sw, bool normalFinish, bool internalError):ElementaryNode("thisIsAFakeNode"),
229 _normalFinish(normalFinish),
230 _internalError(internalError)
232 _state=YACS::TOACTIVATE;
233 _father=_sw->getFather();
236 FakeNodeForSwitch::FakeNodeForSwitch(const FakeNodeForSwitch& other):ElementaryNode(other),_sw(0),
237 _normalFinish(false),
242 Node *FakeNodeForSwitch::simpleClone(ComposedNode *father, bool editionOnly) const
244 return new FakeNodeForSwitch(*this);
247 void FakeNodeForSwitch::exForwardFailed()
249 _sw->exForwardFailed();
252 void FakeNodeForSwitch::exForwardFinished()
254 _sw->exForwardFinished();
257 void FakeNodeForSwitch::execute()
260 throw Exception("");//only to trigger ABORT on Executor
263 void FakeNodeForSwitch::aborted()
266 _sw->_state!=YACS::INTERNALERR;
268 _sw->setState(YACS::ERROR);
271 void FakeNodeForSwitch::finished()
273 _sw->setState(YACS::DONE);
276 /*! \class YACS::ENGINE::Switch
277 * \brief Control node that emulates the C switch
282 Switch::Switch(const Switch& other, ComposedNode *father, bool editionOnly):StaticDefinedComposedNode(other,father),_condition(other._condition,this),
283 _undispatchableNotificationNode(0)
285 for(map<int,Node *>::const_iterator iter=other._mapOfNode.begin();iter!=other._mapOfNode.end();iter++)
286 _mapOfNode[(*iter).first]=(*iter).second->clone(this,editionOnly);
288 for(map<InPort *, CollectorSwOutPort * >::const_iterator iter2=other._outPortsCollector.begin();iter2!=other._outPortsCollector.end();iter2++)
290 CollectorSwOutPort *newCol=new CollectorSwOutPort(*((*iter2).second),this);
291 _alreadyExistingCollectors.push_back(newCol);
295 Switch::Switch(const std::string& name):StaticDefinedComposedNode(name),_condition(SELECTOR_INPUTPORT_NAME,this,Runtime::_tc_int),_undispatchableNotificationNode(0)
301 if(_undispatchableNotificationNode)delete _undispatchableNotificationNode;
303 for(map< int , Node * >::iterator iter=_mapOfNode.begin();iter!=_mapOfNode.end();iter++)
304 delete (*iter).second;
305 for(map<InPort *, CollectorSwOutPort * >::iterator iter2=_outPortsCollector.begin();iter2!=_outPortsCollector.end();iter2++)
306 delete (*iter2).second;
307 for(vector<CollectorSwOutPort *>::iterator iter3=_alreadyExistingCollectors.begin();iter3!=_alreadyExistingCollectors.end();iter3++)
311 Node *Switch::simpleClone(ComposedNode *father, bool editionOnly) const
313 return new Switch(*this,father,editionOnly);
316 void Switch::exUpdateState()
318 DEBTRACE("Switch::exUpdateState " << _state);
319 if(_state == YACS::DISABLED)
321 if(_inGate.exIsReady())
323 setState(YACS::ACTIVATED);
324 if(_condition.isEmpty())
325 _undispatchableNotificationNode=new FakeNodeForSwitch(this,false,true);
328 map< int , Node * >::iterator iter=_mapOfNode.find(_condition.getIntValue());
329 if(iter==_mapOfNode.end())
331 iter=_mapOfNode.find(ID_FOR_DEFAULT_NODE);
332 if(iter==_mapOfNode.end())
334 bool normalFinish=getAllOutPortsLeavingCurrentScope().empty();
335 delete _undispatchableNotificationNode;
336 _undispatchableNotificationNode=new FakeNodeForSwitch(this,normalFinish);
339 ((*iter).second)->exUpdateState();
342 ((*iter).second)->exUpdateState();
347 void Switch::init(bool start)
349 DEBTRACE("Switch::init " << start);
350 StaticDefinedComposedNode::init(start);
352 for(map< int , Node * >::iterator iter=_mapOfNode.begin();iter!=_mapOfNode.end();iter++, i++)
356 ostringstream stream;
357 stream << "Switch::init : initialization failed due to unitialized branch of id " << (*iter).first;
358 throw Exception(stream.str());
360 ((*iter).second)->init(start);
364 void Switch::getReadyTasks(std::vector<Task *>& tasks)
367 * To change the way ComposedNode state is handled, uncomment the following line
368 * see Bloc::getReadyTasks
370 if(_state==YACS::TOACTIVATE) setState(YACS::ACTIVATED);
371 if(_state==YACS::TOACTIVATE || _state==YACS::ACTIVATED)
373 map< int , Node * >::iterator iter=_mapOfNode.find(_condition.getIntValue());
374 if(iter!=_mapOfNode.end())
375 ((*iter).second)->getReadyTasks(tasks);
378 iter=_mapOfNode.find(ID_FOR_DEFAULT_NODE);
379 if(iter!=_mapOfNode.end())
380 (*iter).second->getReadyTasks(tasks);//Default Node is returned
382 if(_undispatchableNotificationNode)
383 _undispatchableNotificationNode->getReadyTasks(tasks);
385 throw Exception("Switch::getReadyTasks : internal error");
390 list<Node *> Switch::edGetDirectDescendants() const
393 for(map< int , Node * >::const_iterator iter=_mapOfNode.begin();iter!=_mapOfNode.end();iter++)
395 ret.push_back((*iter).second);
399 int Switch::getNumberOfInputPorts() const
401 return StaticDefinedComposedNode::getNumberOfInputPorts()+1;
404 int Switch::getMaxLevelOfParallelism() const
407 for(std::map< int , Node * >::const_iterator it=_mapOfNode.begin();it!=_mapOfNode.end();it++)
408 ret=std::max(ret,((*it).second)->getMaxLevelOfParallelism());
412 void Switch::getWeightRegardingDPL(ComplexWeight *weight)
414 ComplexWeight localWeight;
415 for(std::map< int , Node * >::const_iterator it=_mapOfNode.begin();it!=_mapOfNode.end();it++)
417 ((*it).second)->getWeightRegardingDPL(&localWeight);
418 weight->max(localWeight);
419 localWeight.setToZero();
423 void Switch::partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap)
425 for(std::map< int , Node * >::const_iterator it=_mapOfNode.begin();it!=_mapOfNode.end();it++)
426 (*it).second->partitionRegardingDPL(pd,zeMap);
429 void Switch::edRemoveChild(Node *node)
431 map< int , Node * >::iterator iter=_mapOfNode.begin();
432 for(;iter!=_mapOfNode.end();iter++)
433 if(node==(*iter).second)
435 edReleaseCase((*iter).first);
438 ostringstream what; what << "Switch::edRemoveChild : node with name " << node->getName() << " is not a direct child of Switch node " << _name;
439 throw Exception(what.str());
442 std::list<InputPort *> Switch::getSetOfInputPort() const
444 list<InputPort *> ret=StaticDefinedComposedNode::getSetOfInputPort();
445 ret.push_back((InputPort *)&_condition);
450 std::list<InputPort *> Switch::getLocalInputPorts() const
452 list<InputPort *> ret=StaticDefinedComposedNode::getLocalInputPorts();
453 ret.push_back((InputPort *)&_condition);
456 OutPort *Switch::getOutPort(const std::string& name) const
458 for(map<InPort *, CollectorSwOutPort * >::const_iterator iter=_outPortsCollector.begin();iter!=_outPortsCollector.end();iter++)
459 if(name==(*iter).second->getName())
460 return (*iter).second;
461 for(vector<CollectorSwOutPort *>::const_iterator iter2=_alreadyExistingCollectors.begin();iter2!=_alreadyExistingCollectors.end();iter2++)
462 if(name==(*iter2)->getName())
464 return StaticDefinedComposedNode::getOutPort(name);
467 InputPort *Switch::getInputPort(const std::string& name) const
469 if(name==SELECTOR_INPUTPORT_NAME)
470 return (InputPort *)&_condition;
471 return StaticDefinedComposedNode::getInputPort(name);
474 Node *Switch::getChildByShortName(const std::string& name) const
476 if(name==DEFAULT_NODE_NAME)
478 map< int , Node * >::const_iterator iter=_mapOfNode.find(ID_FOR_DEFAULT_NODE);
479 if(iter!=_mapOfNode.end())
480 return (Node *)((*iter).second);
483 string what("Switch::getChildByShortName : no default node defined for switch of name "); what+=getName();
484 throw Exception(what);
487 for(map< int , Node * >::const_iterator iter=_mapOfNode.begin();iter!=_mapOfNode.end();iter++)
489 if(name==((*iter).second)->getQualifiedName())
490 return (*iter).second;
492 string what("node "); what+= name ; what+=" is not a child of node switch "; what += getName();
493 throw Exception(what);
496 Node *Switch::edSetDefaultNode(Node *node)
498 return edSetNode(ID_FOR_DEFAULT_NODE,node);
501 Node *Switch::edReleaseDefaultNode()
503 return edReleaseCase(ID_FOR_DEFAULT_NODE);
506 Node *Switch::edReleaseCase(int caseId)
508 map< int , Node * >::iterator iter=_mapOfNode.find(caseId);
509 if(iter==_mapOfNode.end())
511 string what("Switch::edReleaseCase : the case # "); what+=getRepresentationOfCase(caseId); what+=" is not set yet.";
512 throw Exception(what);
516 Node *ret=(*iter).second;
517 StaticDefinedComposedNode::edRemoveChild(ret);
518 _mapOfNode.erase(iter);
524 Node *Switch::edGetNode(int caseId)
526 if (!_mapOfNode.count(caseId)) return 0;
527 return _mapOfNode[caseId];
532 * \param caseId : the case ID chosen to place 'node'
533 * \param node : the node for the specified 'caseId'
534 * \return : If an old node with id equal to 'caseId' exists before, this old node is returned so that to be deallocated.
535 * 0 is returned if caseId is a new ID.
536 * \b WARNING : 'node' is held by 'this' after call, whereas returned node is no more held.
538 Node *Switch::edSetNode(int caseId, Node *node)
541 throw Exception("Switch::edSetNode : null node cannot be set as a case in switch node");
543 throw Exception("Switch::edSetNode : node already held by another father");
544 checkNoCrossHierachyWith(node);
546 map< int , Node * >::iterator iter=_mapOfNode.find(caseId);
547 if(iter==_mapOfNode.end())
549 _mapOfNode[caseId]=node;
555 if(node!=(*iter).second)
557 Node *ret=(*iter).second;
566 //! Change the case of a node
568 * \param oldCase : the case value to change
569 * \param newCase : the new value to set
570 * raise an exception if the old case does not exist or if the new case already exists
572 void Switch::edChangeCase(int oldCase, int newCase)
574 std::map< int , Node * >::iterator iter=_mapOfNode.find(oldCase);
575 if(iter==_mapOfNode.end())
577 //the case does not exists
578 throw Exception("Switch::edChangeCase : case does not exist");
580 iter=_mapOfNode.find(newCase);
581 if(iter != _mapOfNode.end())
583 //the new case exists
584 throw Exception("Switch::edChangeCase : new case exists");
586 Node* node=_mapOfNode[oldCase];
587 _mapOfNode.erase(oldCase);
588 _mapOfNode[newCase]=node;
592 int Switch::getMaxCase()
595 map<int, Node*>::const_iterator it = _mapOfNode.begin();
596 for(; it != _mapOfNode.end(); ++it)
597 if ((*it).first > aCase)
602 //! Get the progress weight of the graph
604 * Only elementary nodes have weight. If the switch node is not done, we add the weight of all his descendants,
605 * otherwise only the weight of the used case count.
607 list<ProgressWeight> Switch::getProgressWeight() const
609 list<ProgressWeight> ret;
610 list<Node *> setOfNode=edGetDirectDescendants();
611 if (getState() == YACS::DONE)
613 for(list<Node *>::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
615 if (getEffectiveState(*iter) == YACS::DONE)
616 ret=(*iter)->getProgressWeight();
621 for(list<Node *>::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
623 list<ProgressWeight> myCurrentSet=(*iter)->getProgressWeight();
624 ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end());
630 bool Switch::edAddChild(Node *node)
632 int aCase = getMaxCase() + 1;
634 bool ret = edSetNode(aCase, node);
639 YACS::Event Switch::updateStateOnFinishedEventFrom(Node *node)
641 setState(YACS::DONE);
642 return YACS::FINISH;//notify to father node that 'this' has becomed finished.
645 std::set<InPort *> Switch::getAllInPortsComingFromOutsideOfCurrentScope() const
647 set<InPort *> ret=StaticDefinedComposedNode::getAllInPortsComingFromOutsideOfCurrentScope();
648 set<OutPort *> temp2=_condition.edSetOutPort();
649 for(set<OutPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
650 if(!isInMyDescendance((*iter3)->getNode()))
652 ret.insert((InPort *)&_condition);
658 void Switch::checkCFLinks(const std::list<OutPort *>& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const
660 map<InPort *, CollectorSwOutPort * >::const_iterator iter=_outPortsCollector.find(end);
661 if(iter!=_outPortsCollector.end())
663 set<OutPort *> represented;
664 (*iter).second->getAllRepresented(represented);
665 list<OutPort *> others;
666 for(list<OutPort *>::const_iterator iter2=starts.begin();iter2!=starts.end();iter2++)
667 if(represented.find(*iter2)==represented.end())
668 others.push_back(*iter2);
672 StaticDefinedComposedNode::checkCFLinks(others,end,alreadyFed,direction,info);//should never happend;
675 StaticDefinedComposedNode::checkCFLinks(starts,end,alreadyFed,direction,info);
678 void Switch::checkControlDependancy(OutPort *start, InPort *end, bool cross,
679 std::map < ComposedNode *, std::list < OutPort * > >& fw,
680 std::vector<OutPort *>& fwCross,
681 std::map< ComposedNode *, std::list < OutPort *> >& bw,
682 LinkInfo& info) const
684 throw Exception("Switch::checkControlDependancy : a link was dectected between 2 cases of a switch. Impossible !");
687 void Switch::checkNoCyclePassingThrough(Node *node)
689 throw Exception("Switch::checkNoCyclePassingThrough : uncorrect control flow link relative to switch");
692 void Switch::checkLinkPossibility(OutPort *start, const std::list<ComposedNode *>& pointsOfViewStart,
693 InPort *end, const std::list<ComposedNode *>& pointsOfViewEnd)
695 throw Exception("Switch::checkLinkPossibility : A link between 2 different cases of a same Switch requested -> Impossible");
698 void Switch::buildDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView)
700 map<InPort *, CollectorSwOutPort * >::iterator result=_outPortsCollector.find(finalTarget);
701 CollectorSwOutPort *newCollector;
702 if(result!=_outPortsCollector.end())
703 newCollector=(*result).second;
706 newCollector=new CollectorSwOutPort(this,finalTarget);
707 newCollector->edSetType((port.first)->edGetType());
708 _outPortsCollector[finalTarget]=newCollector;
710 newCollector->addPotentialProducerForMaster(port.first);
711 port.second=newCollector;
712 port.first=newCollector;
715 void Switch::getDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView)
717 map<InPort *, CollectorSwOutPort * >::iterator iter=_outPortsCollector.find(finalTarget);
718 if(iter==_outPortsCollector.end())
720 string what("Switch::getDelegateOf : not exported OuputPort with name "); what+=(port.first)->getName(); what+=" for target inport of name ";
721 what+=finalTarget->getName();
722 throw Exception(what);
724 ((*iter).second)->checkManagementOfPort(port.first);
725 port.second=(*iter).second;
726 port.first=(*iter).second;
729 void Switch::releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView)
732 portDwn->getAllRepresented(repr);
735 CollectorSwOutPort *portCasted=dynamic_cast<CollectorSwOutPort *>(portUp);
736 if(portCasted->removePotentialProducerForMaster())//normally always true
739 _outPortsCollector.erase(finalTarget);
744 int Switch::getNbOfCases() const
746 return _mapOfNode.size();
749 int Switch::getRankOfNode(Node *node) const
751 Node *directSon=isInMyDescendance(node);
752 for(map< int , Node * >::const_iterator iter=_mapOfNode.begin();iter!=_mapOfNode.end();iter++)
753 if((*iter).second==directSon)
754 return (*iter).first;
755 throw Exception("Switch::getRankOfNode : node not in switch");
758 string Switch::getRepresentationOfCase(int i)
760 if(i!=ID_FOR_DEFAULT_NODE)
762 ostringstream stream;
767 return DEFAULT_NODE_NAME;
770 //! Return the effective state of a node in the context of this switch (its father)
772 * \param node: the node which effective state is queried
773 * \return the effective node state
775 YACS::StatesForNode Switch::getEffectiveState(const Node* node) const
777 YACS::StatesForNode effectiveState=Node::getEffectiveState();
778 if(effectiveState==YACS::READY)
780 if(effectiveState==YACS::TOACTIVATE)
782 if(effectiveState==YACS::DISABLED)
783 return YACS::DISABLED;
785 return node->getState();
787 YACS::StatesForNode Switch::getEffectiveState() const
789 return Node::getEffectiveState();
792 void Switch::writeDot(std::ostream &os) const
794 os << " subgraph cluster_" << getId() << " {\n" ;
795 for(map<int,Node*>::const_iterator iter=_mapOfNode.begin();iter!=_mapOfNode.end();iter++)
797 Node* n=(*iter).second;
799 os << getId() << " -> " << n->getId() << ";\n";
802 os << getId() << "[fillcolor=\"" ;
803 YACS::StatesForNode state=Node::getEffectiveState();
804 os << getColorState(state);
805 os << "\" label=\"" << "Switch:" ;
806 os << getQualifiedName() <<"\"];\n";
809 std::string Switch::getMyQualifiedName(const Node *directSon) const
811 string id=getCaseId(directSon);
812 id+=directSon->getName();
816 std::string Switch::getCaseId(const Node *node) const
819 map<int, Node*>::const_iterator iter;
820 for (iter = _mapOfNode.begin(); iter != _mapOfNode.end(); iter++)
821 if (iter->second == node)
824 if (iter->first == Switch::ID_FOR_DEFAULT_NODE)
825 a << DEFAULT_NODE_NAME << sep;
826 else if (iter->first <0)
827 a << "m" << -iter->first << sep;
828 else a << "p" << iter->first << sep;
831 string what("node "); what+= node->getName() ; what+=" is not a child of node "; what += getName();
832 throw Exception(what);
835 void Switch::accept(Visitor *visitor)
837 visitor->visitSwitch(this);