X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fengine%2FForEachLoop.cxx;h=838bfb338fb4c6e00c5b4bc58598214db93a10a0;hb=4c94156d7cf2269f0a4a5d01981436a5c045b35d;hp=3b9dec62cb8baa4e7fe63f4971cda31e067cb6ab;hpb=db4d00ca029d8827b60c70d3650943eca9f66831;p=modules%2Fyacs.git diff --git a/src/engine/ForEachLoop.cxx b/src/engine/ForEachLoop.cxx index 3b9dec62c..838bfb338 100644 --- a/src/engine/ForEachLoop.cxx +++ b/src/engine/ForEachLoop.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2006-2015 CEA/DEN, EDF R&D +// Copyright (C) 2006-2016 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 @@ -49,6 +49,8 @@ const char ForEachLoop::NAME_OF_SPLITTERNODE[]="splitter"; const int ForEachLoop::NOT_RUNNING_BRANCH_ID=-1; +const char ForEachLoop::INTERCEPTOR_STR[]="_interceptor"; + InterceptorInputPort::InterceptorInputPort(const std::string& name, Node *node, TypeCode* type):AnyInputPort(name,node,type), DataPort(name,node,type),Port(node), _repr(0) @@ -316,6 +318,14 @@ ForEachLoopPassedData::ForEachLoopPassedData(const std::vector& pa } } +ForEachLoopPassedData::ForEachLoopPassedData(const ForEachLoopPassedData& copy) +: _passedIds(copy._passedIds), + _passedOutputs(copy._passedOutputs), + _nameOfOutputs(copy._nameOfOutputs), + _flagsIds(copy._flagsIds) +{ +} + ForEachLoopPassedData::~ForEachLoopPassedData() { for(std::vector::iterator it=_passedOutputs.begin();it!=_passedOutputs.end();it++) @@ -759,8 +769,16 @@ YACS::Event ForEachLoop::updateStateForWorkNodeOnFinishedEventFrom(Node *node, u int globalId(_execIds[id]); if(_passedData) globalId=_passedData->toAbsId(globalId); + sendEvent2("progress_ok",&globalId); storeOutValsInSeqForOutOfScopeUse(globalId,id); } + else + { + int globalId(_execIds[id]); + if(_passedData) + globalId=_passedData->toAbsId(globalId); + sendEvent2("progress_ko",&globalId); + } // if(_execCurrentId==getFinishedId()) {//No more elements of _dataPortToDispatch to treat @@ -868,6 +886,7 @@ YACS::Event ForEachLoop::updateStateOnFailedEventFrom(Node *node, const Executor { unsigned int id; DynParaLoop::TypeOfNode ton(getIdentityOfNotifyerNode(node,id)); + // TODO: deal with keepgoing without the dependency to Executor if(ton!=WORK_NODE || !execInst->getKeepGoingProperty()) return DynParaLoop::updateStateOnFailedEventFrom(node,execInst); else @@ -877,6 +896,12 @@ YACS::Event ForEachLoop::updateStateOnFailedEventFrom(Node *node, const Executor } } +void ForEachLoop::InterceptorizeNameOfPort(std::string& portName) +{ + std::replace_if(portName.begin(), portName.end(), std::bind1st(std::equal_to(), '.'), '_'); + portName += INTERCEPTOR_STR; +} + void ForEachLoop::buildDelegateOf(std::pair& port, InPort *finalTarget, const std::list& pointsOfView) { DynParaLoop::buildDelegateOf(port,finalTarget,pointsOfView); @@ -899,17 +924,16 @@ void ForEachLoop::buildDelegateOf(std::pair& port, InPort } else { - TypeCodeSeq *newTc=(TypeCodeSeq *)TypeCode::sequenceTc("","",port.first->edGetType()); + TypeCode *tcTrad((YACS::ENGINE::TypeCode*)finalTarget->edGetType()->subContentType(getFEDeltaBetween(port.first,finalTarget))); + TypeCodeSeq *newTc=(TypeCodeSeq *)TypeCode::sequenceTc("","",tcTrad); // The out going ports belong to the ForEachLoop, whereas // the delegated port belongs to a node child of the ForEachLoop. // The name of the delegated port contains dots (bloc.node.outport), // whereas the name of the out going port shouldn't do. - std::string outputPortName = getPortName(port.first); - std::replace_if (outputPortName.begin(), outputPortName.end(), - std::bind1st(std::equal_to(), '.'), '_'); - outputPortName += "_interceptor"; - AnySplitOutputPort *newPort=new AnySplitOutputPort(outputPortName,this,newTc); - InterceptorInputPort *intercptor=new InterceptorInputPort(outputPortName + "_in",this,port.first->edGetType()); + std::string outputPortName(getPortName(port.first)); + InterceptorizeNameOfPort(outputPortName); + AnySplitOutputPort *newPort(new AnySplitOutputPort(outputPortName,this,newTc)); + InterceptorInputPort *intercptor(new InterceptorInputPort(outputPortName + "_in",this,tcTrad)); intercptor->setRepr(newPort); newTc->decrRef(); newPort->addRepr(port.first,intercptor); @@ -1032,7 +1056,8 @@ void ForEachLoop::createOutputOutOfScopeInterceptors(int branchNb) //AnyInputPort *interceptor=new AnyInputPort((*iter)->getName(),this,(*iter)->edGetType()); OutPort *portOut=getDynOutPortByAbsName(branchNb,getOutPortName(((*iter)->getRepr()))); DEBTRACE( portOut->getName() ); - AnyInputPort *interceptor=new AnyInputPort((*iter)->getName(),this,portOut->edGetType()); + TypeCode *tc((TypeCode *)(*iter)->edGetType()->contentType()); + AnyInputPort *interceptor=new AnyInputPort((*iter)->getName(),this,tc); portOut->addInPort(interceptor); _execOutGoingPorts[branchNb].push_back(interceptor); } @@ -1157,7 +1182,9 @@ std::vector ForEachLoop::getPassedResults(Executor *execut, std::v return std::vector(); if(_execOutGoingPorts.empty()) return std::vector(); - std::size_t sz(_execVals.size()); outputs.resize(sz); nameOfOutputs.resize(sz); + std::size_t sz(_execVals.size()); + outputs.resize(sz); + nameOfOutputs.resize(sz); const std::vector& ports(_execOutGoingPorts[0]); for(std::size_t i=0;i& passedIds _passedData=new ForEachLoopPassedData(passedIds,passedOutputs,nameOfOutputs); } +int ForEachLoop::getFEDeltaBetween(OutPort *start, InPort *end) +{ + Node *ns(start->getNode()),*ne(end->getNode()); + ComposedNode *co(getLowestCommonAncestor(ns,ne)); + int ret(0); + Node *work(ns); + while(work!=co) + { + ForEachLoop *isFE(dynamic_cast(work)); + if(isFE) + ret++; + work=work->getFather(); + } + if(dynamic_cast(start)) + ret--; + return ret; +} + +/*! + * This method is used to obtain the values already processed by the ForEachLoop. + * A new ForEachLoopPassedData object is returned. You have to delete it. + */ +ForEachLoopPassedData* ForEachLoop::getProcessedData()const +{ + std::vector outputs; + std::vector nameOfOutputs; + if(_execVals.empty() || _execOutGoingPorts.empty()) + return new ForEachLoopPassedData(std::vector(), outputs, nameOfOutputs); + std::size_t sz(_execVals.size()); + outputs.resize(sz); + nameOfOutputs.resize(sz); + const std::vector& ports(_execOutGoingPorts[0]); + for(std::size_t i=0;iremoveUnsetItemsFromThis(); + nameOfOutputs[i]=ports[i]->getName(); + } + return new ForEachLoopPassedData(_execVals[0]->getSetItems(), outputs, nameOfOutputs); +} + +void ForEachLoop::setProcessedData(ForEachLoopPassedData* processedData) +{ + if(_passedData) + delete _passedData; + _passedData = processedData; +} + +/*! + * \param portName : "interceptorized" name of port. + */ +const YACS::ENGINE::TypeCode* ForEachLoop::getOutputPortType(const std::string& portName)const +{ + const YACS::ENGINE::TypeCode* ret=NULL; + vector::const_iterator it; + for(it=_outGoingPorts.begin();it!=_outGoingPorts.end() && ret==NULL;it++) + { + std::string originalPortName(getPortName(*it)); + //InterceptorizeNameOfPort(originalPortName); + DEBTRACE("ForEachLoop::getOutputPortType compare " << portName << " == " << originalPortName); + if(originalPortName == portName) + { + ret = (*it)->edGetType()->contentType(); + } + } + return ret; +}