X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2Fengine%2FComposedNode.cxx;h=71576cd2bd823ae5dddfee5159f4b3faa827de2b;hb=3699a56026f27b2de384de5944b20e2d27fdda44;hp=bb6a368207755103adba1b74854dd5fd87cedcc8;hpb=f4c10bf1781a76534bb1fa293aef541aef56148b;p=modules%2Fyacs.git diff --git a/src/engine/ComposedNode.cxx b/src/engine/ComposedNode.cxx index bb6a36820..71576cd2b 100644 --- a/src/engine/ComposedNode.cxx +++ b/src/engine/ComposedNode.cxx @@ -1,27 +1,29 @@ -// Copyright (C) 2006-2008 CEA/DEN, EDF R&D +// Copyright (C) 2006-2015 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + #include "ComposedNode.hxx" #include "LinkInfo.hxx" #include "Container.hxx" #include "InputPort.hxx" #include "OutputPort.hxx" #include "ServiceNode.hxx" +#include "InlineNode.hxx" #include "DataFlowPort.hxx" #include "DataStreamPort.hxx" #include "ElementaryNode.hxx" @@ -39,6 +41,14 @@ using namespace YACS::ENGINE; using namespace std; +/*! \class YACS::ENGINE::ComposedNode + * \brief Base class for all composed nodes. + * + * This is an abstract class that must be specialized. + * + * \ingroup Nodes + */ + const char ComposedNode::SEP_CHAR_BTW_LEVEL[]="."; ComposedNode::ComposedNode(const std::string& name):Node(name) @@ -59,12 +69,15 @@ void ComposedNode::performDuplicationOfPlacement(const Node& other) DeploymentTree treeToDup=otherC.getDeploymentTree(); list< ElementaryNode * > clones=otherC.getRecursiveConstituents(); vector conts=treeToDup.getAllContainers(); + //iterate on all containers for(vector::iterator iterCt=conts.begin();iterCt!=conts.end();iterCt++) { vector comps=treeToDup.getComponentsLinkedToContainer(*iterCt); Container *contCloned=0; if((*iterCt)) contCloned=(*iterCt)->clone(); + + //iterate on all component instances linked to the container for(vector::iterator iterCp=comps.begin();iterCp!=comps.end();iterCp++) { vector tasks=treeToDup.getTasksLinkedToComponent(*iterCp); @@ -80,11 +93,61 @@ void ComposedNode::performDuplicationOfPlacement(const Node& other) } curCloned->decrRef(); } + + // iterate on all tasks linked to the container + vector tasks=treeToDup.getTasksLinkedToContainer(*iterCt); + for(vector::iterator iterT=tasks.begin();iterT!=tasks.end();iterT++) + { + std::list< ElementaryNode * >::iterator res=find(clones.begin(),clones.end(),(ElementaryNode *)(*iterT)); + InlineFuncNode *nodeC=(InlineFuncNode *)getChildByName(otherC.getChildName(*res)); + nodeC->setContainer(contCloned); + } + + // ended with current container if(contCloned) contCloned->decrRef(); } } +void ComposedNode::performShallowDuplicationOfPlacement(const Node& other) +{ + const ComposedNode &otherC=*(dynamic_cast(&other)); + DeploymentTree treeToDup=otherC.getDeploymentTree(); + list< ElementaryNode * > clones=otherC.getRecursiveConstituents(); + vector conts=treeToDup.getAllContainers(); + //iterate on all containers + for(vector::iterator iterCt=conts.begin();iterCt!=conts.end();iterCt++) + { + vector comps=treeToDup.getComponentsLinkedToContainer(*iterCt); + Container *contCloned((*iterCt)); + + //iterate on all component instances linked to the container + for(vector::iterator iterCp=comps.begin();iterCp!=comps.end();iterCp++) + { + vector tasks=treeToDup.getTasksLinkedToComponent(*iterCp); + ComponentInstance *curCloned((*iterCp)); + curCloned->setContainer(contCloned); + for(vector::iterator iterT=tasks.begin();iterT!=tasks.end();iterT++) + { + //No risk for static cast : appendTask called by ComposedNode. + list< ElementaryNode * >::iterator res=find(clones.begin(),clones.end(),(ElementaryNode *)(*iterT)); + //No risk here to because called only on cloning process... + ServiceNode *nodeC=(ServiceNode *)getChildByName(otherC.getChildName(*res)); + nodeC->setComponent(curCloned); + } + } + + // iterate on all tasks linked to the container + vector tasks=treeToDup.getTasksLinkedToContainer(*iterCt); + for(vector::iterator iterT=tasks.begin();iterT!=tasks.end();iterT++) + { + std::list< ElementaryNode * >::iterator res=find(clones.begin(),clones.end(),(ElementaryNode *)(*iterT)); + InlineFuncNode *nodeC=(InlineFuncNode *)getChildByName(otherC.getChildName(*res)); + nodeC->setContainer(contCloned); + } + } +} + bool ComposedNode::isFinished() { if(_state==YACS::DONE)return true; @@ -123,7 +186,7 @@ DeploymentTree ComposedNode::getDeploymentTree() const /*! * \param deep if \b true a deep check is perfomed. Typically has to be called by an executor before any attempt to launch an execution. */ -DeploymentTree ComposedNode::checkDeploymentTree(bool deep) const throw(Exception) +DeploymentTree ComposedNode::checkDeploymentTree(bool deep) const throw(YACS::Exception) { DeploymentTree ret; list< ElementaryNode * > tasks=getRecursiveConstituents(); @@ -134,18 +197,18 @@ DeploymentTree ComposedNode::checkDeploymentTree(bool deep) const throw(Exceptio case DeploymentTree::DUP_TASK_NOT_COMPATIBLE_WITH_EXISTING_TREE: { string what("ComposedNode::checkDeploymentTree : ServiceNode with name \""); what+=(*iter)->getName(); - what+="\" coexists in a component with an another Task which context is incorrect with it."; + what+="\" coexists in a component with an another Task which context is incompatible with it."; throw Exception(what); } - case DeploymentTree::DEPLOYABLE_BUT_NOT_SPECIFIED : - { - if(deep) - { - string what("ComposedNode::checkDeploymentTree : ServiceNode with name \""); what+=(*iter)->getName(); - what+="\" is deployable but no component is specified on it."; - throw Exception(what); - } - } + case DeploymentTree::DEPLOYABLE_BUT_NOT_SPECIFIED : + { + if(deep) + { + string what("ComposedNode::checkDeploymentTree : ServiceNode with name \""); what+=(*iter)->getName(); + what+="\" is deployable but no component is specified on it."; + throw Exception(what); + } + } } } return ret; @@ -206,7 +269,7 @@ void ComposedNode::notifyFrom(const Task *sender, //* I : task emitting event * \return true if a new link has been created, false otherwise. */ -bool ComposedNode::edAddLink(OutPort *start, InPort *end) throw(Exception) +bool ComposedNode::edAddLink(OutPort *start, InPort *end) throw(YACS::Exception) { DEBTRACE("ComposedNode::edAddLink"); set represented; @@ -262,7 +325,7 @@ bool ComposedNode::edAddLink(OutPort *start, InPort *end) throw(Exception) * \param end : the InPort to connect * \return true if a new link has been created, false otherwise. */ -bool ComposedNode::edAddDFLink(OutPort *start, InPort *end) throw(Exception) +bool ComposedNode::edAddDFLink(OutPort *start, InPort *end) throw(YACS::Exception) { Node* n1=start->getNode(); Node* n2=end->getNode(); @@ -316,12 +379,12 @@ bool ComposedNode::edAddDFLink(OutPort *start, InPort *end) throw(Exception) * supporting it. * \return true if a new link has been created, false otherwise. */ -bool ComposedNode::edAddLink(OutGate *start, InGate *end) throw(Exception) +bool ComposedNode::edAddLink(OutGate *start, InGate *end) throw(YACS::Exception) { Node* n1=start->getNode(); Node* n2=end->getNode(); if(n1==n2) - throw Exception("ComposedNode::edAddLink: can not add a control link to a node with itself"); + throw Exception("ComposedNode::edAddLink: can not add a control link to a node with itself",1); ComposedNode* father=checkHavingCommonFather(start->getNode(),end->getNode()); if(father==0) throw Exception("ComposedNode::edAddLink: Trying to add CF link on orphan nodes."); @@ -350,13 +413,13 @@ bool ComposedNode::edAddLink(OutGate *start, InGate *end) throw(Exception) /*! * Add a controlflow link between two nodes by calling edAddLink on their control ports */ -bool ComposedNode::edAddCFLink(Node *nodeS, Node *nodeE) throw(Exception) +bool ComposedNode::edAddCFLink(Node *nodeS, Node *nodeE) throw(YACS::Exception) { return edAddLink(nodeS->getOutGate(),nodeE->getInGate()); } //! Remove a controlflow link. -void ComposedNode::edRemoveCFLink(Node *nodeS, Node *nodeE) throw(Exception) +void ComposedNode::edRemoveCFLink(Node *nodeS, Node *nodeE) throw(YACS::Exception) { edRemoveLink(nodeS->getOutGate(),nodeE->getInGate()); } @@ -370,7 +433,7 @@ void ComposedNode::edRemoveCFLink(Node *nodeS, Node *nodeE) throw(Exception) * implies DF/DS gateway. */ -void ComposedNode::edRemoveLink(OutPort *start, InPort *end) throw(Exception) +void ComposedNode::edRemoveLink(OutPort *start, InPort *end) throw(YACS::Exception) { if(!start->isAlreadyLinkedWith(end)) throw Exception("ComposedNode::edRemoveLink : unexisting link"); @@ -390,20 +453,20 @@ void ComposedNode::edRemoveLink(OutPort *start, InPort *end) throw(Exception) { iterS=nodeOTemp->_father; while(iterS!=lwstCmnAnctr) - { - if (!iterS) - { - stringstream what; - what << "ComposedNode::edRemoveLink: " - << start->getNode()->getName() << "." <getName() << "->" - << end->getNode()->getName() << "." << end->getName(); - throw Exception(what.str()); - } - OutPort *tmp=currentPortO.first; - iterS->getDelegateOf(currentPortO, end, allAscendanceOfNodeEnd); - needsToDestroyO.push_back(pair< ComposedNode * , pair < OutPort* , OutPort *> >(iterS,pair (tmp,currentPortO.first))); - iterS=iterS->_father; - } + { + if (!iterS) + { + stringstream what; + what << "ComposedNode::edRemoveLink: " + << start->getNode()->getName() << "." <getName() << "->" + << end->getNode()->getName() << "." << end->getName(); + throw Exception(what.str()); + } + OutPort *tmp=currentPortO.first; + iterS->getDelegateOf(currentPortO, end, allAscendanceOfNodeEnd); + needsToDestroyO.push_back(pair< ComposedNode * , pair < OutPort* , OutPort *> >(iterS,pair (tmp,currentPortO.first))); + iterS=iterS->_father; + } } Node *nodeTemp=end->getNode(); InPort * currentPortI=end; @@ -452,7 +515,7 @@ void ComposedNode::edRemoveLink(OutPort *start, InPort *end) throw(Exception) } //! Remove a controlflow link. -void ComposedNode::edRemoveLink(OutGate *start, InGate *end) throw(Exception) +void ComposedNode::edRemoveLink(OutGate *start, InGate *end) throw(YACS::Exception) { ComposedNode* father=checkHavingCommonFather(start->getNode(),end->getNode()); if(father!=this) @@ -460,13 +523,13 @@ void ComposedNode::edRemoveLink(OutGate *start, InGate *end) throw(Exception) start->edRemoveInGate(end); } -bool ComposedNode::edAddChild(Node *DISOWNnode) throw(Exception) +bool ComposedNode::edAddChild(Node *DISOWNnode) throw(YACS::Exception) { return false; // --- reimplemented in derived classes } //! Remove a child node. -void ComposedNode::edRemoveChild(Node *node) throw(Exception) +void ComposedNode::edRemoveChild(Node *node) throw(YACS::Exception) { if(!node) return; @@ -491,7 +554,7 @@ void ComposedNode::edRemoveChild(Node *node) throw(Exception) * separator was not found). */ bool ComposedNode::splitNamesBySep(const std::string& globalName, const char separator[], - std::string& firstPart, std::string& lastPart, bool priority) throw(Exception) + std::string& firstPart, std::string& lastPart, bool priority) throw(YACS::Exception) { const string delims(separator); string portName, nodeName; @@ -508,7 +571,7 @@ bool ComposedNode::splitNamesBySep(const std::string& globalName, const char sep } firstPart = globalName.substr(0,idx); lastPart = globalName.substr(idx+1); - if ((firstPart.empty()) or (lastPart.empty())) + if ((firstPart.empty()) || (lastPart.empty())) { string what("the name "); what+= globalName ; what+=" is not a valid port name"; throw Exception(what); @@ -544,7 +607,7 @@ std::vector< std::pair > ComposedNode::getSetOfLinksLeaving return ret; } -void ComposedNode::checkConsistency(LinkInfo& info) const throw(Exception) +void ComposedNode::checkConsistency(LinkInfo& info) const throw(YACS::Exception) { info.clearAll(); info.setPointOfView((ComposedNode *)this); @@ -564,10 +627,24 @@ void ComposedNode::checkConsistency(LinkInfo& info) const throw(Exception) } if(!candidateForAdvCheck.empty()) //End of filtering. Now regarding CF constraints for the current InPutPort. - checkLinksCoherenceRegardingControl(candidateForAdvCheck,*iter1,info); + try + { + checkLinksCoherenceRegardingControl(candidateForAdvCheck,*iter1,info); + } + catch(YACS::Exception& ex) + { + std::string what=ex.what(); + what += "\nfor input port: "; + what += (*iter1)->getNode()->getName(); + what += "."; + what += (*iter1)->getName(); + + destructCFComputations(info); + throw YACS::Exception(what); + } else //No backlinks - if(!(*iter1)->edIsManuallyInitialized()) + if(!(*iter1)->canBeNull() && !(*iter1)->edIsManuallyInitialized()) info.pushErrLink(0,*iter1,E_NEVER_SET_INPUTPORT); } destructCFComputations(info); @@ -577,7 +654,7 @@ void ComposedNode::checkConsistency(LinkInfo& info) const throw(Exception) * This method check that G1 <- G2 <- G3 <- G1 does not happened. * Typically called by methods that set a hierarchy (Bloc::edAddChild, Loop::edSetNode, ...). */ -void ComposedNode::checkNoCrossHierachyWith(Node *node) const throw (Exception) +void ComposedNode::checkNoCrossHierachyWith(Node *node) const throw(YACS::Exception) { ComposedNode *nodeC=dynamic_cast(node); if(!nodeC) @@ -632,7 +709,7 @@ Node *ComposedNode::getLowestNodeDealingAll(const std::list& ports) c /*! * call it only for 'starts' to 'end' links \b DEALED by 'this'. */ -void ComposedNode::checkLinksCoherenceRegardingControl(const std::vector& starts, InputPort *end, LinkInfo& info) const throw(Exception) +void ComposedNode::checkLinksCoherenceRegardingControl(const std::vector& starts, InputPort *end, LinkInfo& info) const throw(YACS::Exception) { map < ComposedNode *, list, SortHierarc > outputs;//forward link classical vector outputsCross;//forward link cross @@ -669,8 +746,8 @@ void ComposedNode::checkLinksCoherenceRegardingControl(const std::vector& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const { @@ -714,10 +791,13 @@ void ComposedNode::solveObviousOrDelegateCFLinks(const std::list& sta } } +//! check control flow links /*! * \param starts If different of 0, must aggregate at leat \b 1 element. + * \param end : * \param alreadyFed in/out parameter. Indicates if 'end' ports is already and surely set or fed by an another port. * \param direction If true : forward direction else backward direction. + * \param info : informations collectedduring the check */ void ComposedNode::checkCFLinks(const std::list& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const { @@ -728,11 +808,13 @@ void ComposedNode::checkCFLinks(const std::list& starts, InputPort *e //This case is typically dedicated when direct son is ElementaryNode and self link is defined on this. if(!dynamic_cast(nodeEnd)) throw Exception(what); + list< OutPort *>::const_iterator iter=starts.begin(); Node *nodeStart=(*iter)->getNode(); iter++; if(nodeEnd!=nodeStart) throw Exception(what); + for(;iter!=starts.end();iter++) if((*iter)->getNode()!=nodeStart) throw Exception(what); @@ -753,8 +835,13 @@ std::vector< std::pair > ComposedNode::getSetOfLinksComingI { set temp2=(*iter2)->edSetOutPort(); for(set::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++) - if(!isInMyDescendance((*iter3)->getNode())) - ret.push_back(pair(*iter2,*iter3)); + { + if(isInMyDescendance((*iter3)->getNode()))continue; + std::set trueOutPorts; + (*iter3)->getAllRepresented(trueOutPorts); + for(std::set::iterator iter4=trueOutPorts.begin();iter4!=trueOutPorts.end();++iter4) + ret.push_back(pair(*iter2,*iter4)); + } } return ret; } @@ -832,7 +919,7 @@ void ComposedNode::edDisconnectAllLinksWithMe() } } -ComposedNode *ComposedNode::getRootNode() const throw(Exception) +ComposedNode *ComposedNode::getRootNode() const throw(YACS::Exception) { if(!_father) return (ComposedNode *)this; @@ -873,7 +960,7 @@ Node *ComposedNode::isInMyDescendance(Node *nodeToTest) const return 0; } -string ComposedNode::getChildName(const Node* node) const throw(Exception) +string ComposedNode::getChildName(const Node* node) const throw(YACS::Exception) { string nodeName=node->getQualifiedName(); if (!isNodeAlreadyAggregated(node)) @@ -904,7 +991,7 @@ std::string ComposedNode::getMyQualifiedName(const Node *directSon) const return directSon->getName(); } -Node *ComposedNode::getChildByName(const std::string& name) const throw(Exception) +Node *ComposedNode::getChildByName(const std::string& name) const throw(YACS::Exception) { string potentiallyDirectSonName, remainsPath; bool forwardNeeded=ComposedNode::splitNamesBySep(name, SEP_CHAR_BTW_LEVEL, @@ -922,7 +1009,7 @@ Node *ComposedNode::getChildByName(const std::string& name) const throw(Exceptio * \exception Exception : If 'nodeToTest' is NOT in descendance of 'this' AND not equal to 'this' * \param nodeToTest : the node to check */ -void ComposedNode::checkInMyDescendance(Node *nodeToTest) const throw(Exception) +void ComposedNode::checkInMyDescendance(Node *nodeToTest) const throw(YACS::Exception) { const char whatC[]=" is not the descendance of node "; if(nodeToTest==0) @@ -955,9 +1042,9 @@ void ComposedNode::checkInMyDescendance(Node *nodeToTest) const throw(Exception) * \return The lowest common ancestor if it exists. * */ -ComposedNode *ComposedNode::getLowestCommonAncestor(Node *node1, Node *node2) throw(Exception) +ComposedNode *ComposedNode::getLowestCommonAncestor(Node *node1, Node *node2) throw(YACS::Exception) { - const char what[]="2 nodes does not share the same genealogy"; + const char what[]="The two nodes do not share the same genealogy"; if(node1==0 || node2==0) throw Exception(what); ComposedNode *temp; @@ -987,6 +1074,45 @@ ComposedNode *ComposedNode::getLowestCommonAncestor(Node *node1, Node *node2) th return *iter; } +/*! + * Same as getLowestCommonAncestor method except that absolute string representation is considered here instead of instances. + */ +std::string ComposedNode::getLowestCommonAncestorStr(const std::string& node1, const std::string& node2) +{ + std::string ret; + std::size_t it1_b(0),it1_e(0),it2_b(0),it2_e(0); + while(it1_b!=std::string::npos && it2_b!=std::string::npos) + { + it1_e=node1.find(SEP_CHAR_BTW_LEVEL,it1_b); + it2_e=node2.find(SEP_CHAR_BTW_LEVEL,it2_b); + if(it1_e!=it2_e && it1_e!=std::string::npos && it2_e!=std::string::npos) + break; + std::string elt1(node1.substr(it1_b,it1_e-it1_b)),elt2(node2.substr(it2_b,it2_e-it2_b)); + if(elt1!=elt2) + break; + if(!ret.empty()) + ret+=SEP_CHAR_BTW_LEVEL; + ret+=elt1; + it1_b=node1.find_first_not_of(SEP_CHAR_BTW_LEVEL,it1_e); + it2_b=node2.find_first_not_of(SEP_CHAR_BTW_LEVEL,it2_e); + } + return ret; +} + +/*! + * This method recursively all redundant control links in this. + */ +void ComposedNode::removeRecursivelyRedundantCL() +{ + std::list dd(edGetDirectDescendants()); + for(std::list::const_iterator it=dd.begin();it!=dd.end();it++) + { + ComposedNode *elt(dynamic_cast(*it)); + if(elt) + elt->removeRecursivelyRedundantCL(); + } +} + list ComposedNode::getRecursiveConstituents() const { list ret; @@ -1043,17 +1169,35 @@ list ComposedNode::getAllRecursiveNodes() return ret; } + +//! Get the progress weight for all elementary nodes +/*! + * Only elementary nodes have weight. A simple composed node only sum up weight of all his descendants + * (working is different for loop or switch nodes) + */ +list ComposedNode::getProgressWeight() const +{ + list ret; + list setOfNode=edGetDirectDescendants(); + for(list::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++) + { + list myCurrentSet=((ComposedNode*)(*iter))->getProgressWeight(); + ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end()); + } + return ret; +} + //! Get the input port name /*! * get the input port name used by the current node, recursively built with children names. */ -string ComposedNode::getInPortName(const InPort * inPort) const throw (Exception) +string ComposedNode::getInPortName(const InPort * inPort) const throw(YACS::Exception) { return getPortName(inPort); } -string ComposedNode::getOutPortName(const OutPort *outPort) const throw (Exception) +string ComposedNode::getOutPortName(const OutPort *outPort) const throw(YACS::Exception) { return getPortName(outPort); } @@ -1124,7 +1268,7 @@ list ComposedNode::getSetOfOutputDataStreamPort() const return ret; } -OutPort *ComposedNode::getOutPort(const std::string& name) const throw(Exception) +OutPort *ComposedNode::getOutPort(const std::string& name) const throw(YACS::Exception) { string portName, nodeName; if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,false)) @@ -1145,8 +1289,13 @@ OutPort *ComposedNode::getOutPort(const std::string& name) const throw(Exception * and so the leaf of type ElementaryNode aggregating * this InputPort is directly invoked. */ -InputPort * ComposedNode::getInputPort(const std::string& name) const throw(Exception) +InputPort * ComposedNode::getInputPort(const std::string& name) const throw(YACS::Exception) { + try { + return Node::getInputPort(name); + } + catch(Exception& e) {} + string portName, nodeName; if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,true)) { @@ -1165,7 +1314,7 @@ InputPort * ComposedNode::getInputPort(const std::string& name) const throw(Exce * Contrary to YACS::ENGINE::ComposedNode::getInputPort, this method is recursive and go * down hierarchy step by step to complete its work. */ -OutputPort * ComposedNode::getOutputPort(const std::string& name) const throw(Exception) +OutputPort * ComposedNode::getOutputPort(const std::string& name) const throw(YACS::Exception) { string portName, nodeName; if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,false)) @@ -1180,7 +1329,7 @@ OutputPort * ComposedNode::getOutputPort(const std::string& name) const throw(Ex } } -InputDataStreamPort *ComposedNode::getInputDataStreamPort(const std::string& name) const throw(Exception) +InputDataStreamPort *ComposedNode::getInputDataStreamPort(const std::string& name) const throw(YACS::Exception) { string portName, nodeName; if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,true)) @@ -1195,7 +1344,7 @@ InputDataStreamPort *ComposedNode::getInputDataStreamPort(const std::string& nam } } -OutputDataStreamPort *ComposedNode::getOutputDataStreamPort(const std::string& name) const throw(Exception) +OutputDataStreamPort *ComposedNode::getOutputDataStreamPort(const std::string& name) const throw(YACS::Exception) { string portName, nodeName; if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,true)) @@ -1253,6 +1402,8 @@ YACS::Event ComposedNode::updateStateFrom(Node *node, //* I : node emitti //unexpected exception: probably a bug in engine //try to keep a consistent global state DEBTRACE( "updateStateFrom: " << ex.what() ); + _errorDetails="Internal error: "; + _errorDetails=_errorDetails + ex.what(); setState(YACS::ERROR); exForwardFailed(); return YACS::ABORT; @@ -1288,16 +1439,16 @@ YACS::Event ComposedNode::updateStateOnFailedEventFrom(Node *node) } void ComposedNode::checkLinkPossibility(OutPort *start, const std::list& pointsOfViewStart, - InPort *end, const std::list& pointsOfViewEnd) throw(Exception) + InPort *end, const std::list& pointsOfViewEnd) throw(YACS::Exception) { - if((dynamic_cast(start) or dynamic_cast(end)) - and (dynamic_cast(start) or dynamic_cast(end))) + if((dynamic_cast(start) || dynamic_cast(end)) + && (dynamic_cast(start) || dynamic_cast(end))) {//cross protocol required : deeper check needed bool isOK=false; list::const_iterator iter; - for(iter=pointsOfViewStart.begin();iter!=pointsOfViewStart.end() and !isOK;iter++) + for(iter=pointsOfViewStart.begin();iter!=pointsOfViewStart.end() && !isOK;iter++) isOK=(*iter)->isRepeatedUnpredictablySeveralTimes(); - for(iter=pointsOfViewEnd.begin();iter!=pointsOfViewEnd.end() and !isOK;iter++) + for(iter=pointsOfViewEnd.begin();iter!=pointsOfViewEnd.end() && !isOK;iter++) isOK=(*iter)->isRepeatedUnpredictablySeveralTimes(); if(!isOK) throw Exception("ComposedNode::checkLinkPossibility : Request for cross protocol link impossible."); @@ -1312,19 +1463,19 @@ void ComposedNode::buildDelegateOf(std::pair& port, InPort { } -void ComposedNode::getDelegateOf(InPort * & port, OutPort *initialStart, const std::list& pointsOfView) throw(Exception) +void ComposedNode::getDelegateOf(InPort * & port, OutPort *initialStart, const std::list& pointsOfView) throw(YACS::Exception) { } -void ComposedNode::getDelegateOf(std::pair& port, InPort *finalTarget, const std::list& pointsOfView) throw(Exception) +void ComposedNode::getDelegateOf(std::pair& port, InPort *finalTarget, const std::list& pointsOfView) throw(YACS::Exception) { } -void ComposedNode::releaseDelegateOf(InPort * & port, OutPort *initialStart, const std::list& pointsOfView) throw(Exception) +void ComposedNode::releaseDelegateOf(InPort * & port, OutPort *initialStart, const std::list& pointsOfView) throw(YACS::Exception) { } -void ComposedNode::releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::list& pointsOfView) throw(Exception) +void ComposedNode::releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::list& pointsOfView) throw(YACS::Exception) { } @@ -1432,7 +1583,7 @@ std::string ComposedNode::getErrorReport() -void ComposedNode::checkBasicConsistency() const throw(Exception) +void ComposedNode::checkBasicConsistency() const throw(YACS::Exception) { DEBTRACE("ComposedNode::checkBasicConsistency"); std::list::const_iterator iter; @@ -1440,3 +1591,43 @@ void ComposedNode::checkBasicConsistency() const throw(Exception) for(iter=inports.begin();iter!=inports.end();iter++) (*iter)->checkBasicConsistency(); } + +//! Stop all pending activities of the composed node +/*! + * This method should be called when a Proc is finished and must be deleted from the YACS server + */ +void ComposedNode::shutdown(int level) +{ + if(level==0)return; + DEBTRACE("ComposedNode::shutdown"); + list nodes=edGetDirectDescendants(); + for(list::iterator iter=nodes.begin();iter!=nodes.end();iter++) + (*iter)->shutdown(level); +} + +//! Clean the composed node in case of not clean exit +/*! + * This method should be called on a control-c or sigterm + */ +void ComposedNode::cleanNodes() +{ + DEBTRACE("ComposedNode::cleanNodes"); + list nodes=edGetDirectDescendants(); + for(list::iterator iter=nodes.begin();iter!=nodes.end();iter++) + (*iter)->cleanNodes(); +} + +//! Reset the state of the node and its children depending on the parameter level +void ComposedNode::resetState(int level) +{ + if(level==0)return; + + DEBTRACE("ComposedNode::resetState " << level << "," << _state); + if( _state==YACS::ERROR || _state==YACS::FAILED || _state==YACS::ACTIVATED ) + { + Node::resetState(level); + std::list nodes=edGetDirectDescendants(); + for(std::list::iterator iter=nodes.begin();iter!=nodes.end();iter++) + (*iter)->resetState(level); + } +}