From 8cc94c84bd258a4ad85018ca06626feed0174590 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Thu, 27 Oct 2016 11:25:00 +0200 Subject: [PATCH] Issue EDF13268 - link from list[pyobj] inside ForEachLoop to list[pyobj] outside ForEachLoop --- src/engine/ForEachLoop.cxx | 34 +++++++++++++++-- src/engine/ForEachLoop.hxx | 1 + src/engine/TypeCode.cxx | 28 ++++++++++++++ src/engine/TypeCode.hxx | 4 +- src/runtime/RuntimeSALOME.cxx | 5 +++ .../Test/StdAloneYacsLoaderTest1.py | 38 +++++++++++++++++++ 6 files changed, 106 insertions(+), 4 deletions(-) diff --git a/src/engine/ForEachLoop.cxx b/src/engine/ForEachLoop.cxx index 83af9c7e7..b1b86d4f5 100644 --- a/src/engine/ForEachLoop.cxx +++ b/src/engine/ForEachLoop.cxx @@ -915,7 +915,8 @@ 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), @@ -923,7 +924,7 @@ void ForEachLoop::buildDelegateOf(std::pair& port, InPort std::string outputPortName(getPortName(port.first)); InterceptorizeNameOfPort(outputPortName); AnySplitOutputPort *newPort(new AnySplitOutputPort(outputPortName,this,newTc)); - InterceptorInputPort *intercptor(new InterceptorInputPort(outputPortName + "_in",this,port.first->edGetType())); + InterceptorInputPort *intercptor(new InterceptorInputPort(outputPortName + "_in",this,tcTrad)); intercptor->setRepr(newPort); newTc->decrRef(); newPort->addRepr(port.first,intercptor); @@ -1046,7 +1047,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); } @@ -1192,3 +1194,29 @@ void ForEachLoop::assignPassedResults(const std::vector& 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(); + } + work=ne; + int delta(0); + while(work!=co) + { + ForEachLoop *isFE(dynamic_cast(work)); + if(isFE) + delta++; + work=work->getFather(); + } + if(dynamic_cast(start)) + ret--; + return ret-delta; +} diff --git a/src/engine/ForEachLoop.hxx b/src/engine/ForEachLoop.hxx index f2cd2d10a..7c1968d38 100644 --- a/src/engine/ForEachLoop.hxx +++ b/src/engine/ForEachLoop.hxx @@ -195,6 +195,7 @@ namespace YACS std::list getProgressWeight() const; int getCurrentIndex() const { return _currentIndex; } int getNbOfElementsToBeProcessed() const; + static int getFEDeltaBetween(OutPort *start, InPort *end); #ifndef SWIG std::vector getPassedResults(Executor *execut, std::vector& outputs, std::vector& nameOfOutputs) const; void assignPassedResults(const std::vector& passedIds, const std::vector& passedOutputs, const std::vector& nameOfOutputs); diff --git a/src/engine/TypeCode.cxx b/src/engine/TypeCode.cxx index 38560cf0c..f7c477447 100644 --- a/src/engine/TypeCode.cxx +++ b/src/engine/TypeCode.cxx @@ -139,6 +139,11 @@ int TypeCode::isAdaptable(const TypeCode* tc) const } } +std::string TypeCode::getPrintStr() const +{ + return id(); +} + //! Check if this TypeCode can be used in place of tc /*! * this TypeCode is equivalent to tc if they have the same kind @@ -200,6 +205,23 @@ const char *TypeCode::getKindRepr(DynType kind) return KIND_STR_REPR[(int)kind]; } +const TypeCode *TypeCode::subContentType(int lev) const +{ + if(lev<0) + throw YACS::Exception("subContentType: Invalid input val !"); + if(lev==0) + return this; + const TypeCode *ret(this); + for(int i=0;icontentType()); + if(!cand) + throw YACS::Exception("subContentType : Invalid input val 2 !"); + ret=cand; + } + return ret; +} + const char * TypeCode::getKindRepr() const { return KIND_STR_REPR[(int)_kind]; @@ -447,6 +469,12 @@ const char * TypeCodeSeq::shortName() const return _shortName.c_str(); } +std::string TypeCodeSeq::getPrintStr() const +{ + std::ostringstream oss; oss << "seq[" << contentType()->getPrintStr() << "]"; + return oss.str(); +} + const TypeCode * TypeCodeSeq::contentType() const throw(YACS::Exception) { return _content; diff --git a/src/engine/TypeCode.hxx b/src/engine/TypeCode.hxx index 5d16a01ac..1856e73a2 100644 --- a/src/engine/TypeCode.hxx +++ b/src/engine/TypeCode.hxx @@ -71,7 +71,7 @@ namespace YACS DynType kind() const; const char * getKindRepr() const; - + const TypeCode *subContentType(int lev) const; virtual TypeCode *clone() const; virtual void putReprAtPlace(char *pt, const char *val, bool deepCpy) const; virtual void destroyZippedAny(char *data) const; @@ -85,6 +85,7 @@ namespace YACS virtual int isAdaptable(const TypeCode* tc) const; virtual int isEquivalent(const TypeCode* tc) const; virtual unsigned getSizeInByteOfAnyReprInSeq() const; + virtual std::string getPrintStr() const; static const char *getKindRepr(DynType kind); static TypeCode * interfaceTc(const char* id, const char* name); @@ -168,6 +169,7 @@ namespace YACS const char * id() const throw(Exception); const char * name() const throw(Exception); const char * shortName() const; + virtual std::string getPrintStr() const; virtual const TypeCode * contentType() const throw(Exception); virtual int isA(const TypeCode* tc) const ; diff --git a/src/runtime/RuntimeSALOME.cxx b/src/runtime/RuntimeSALOME.cxx index 71afc05a1..7fbeb28d3 100644 --- a/src/runtime/RuntimeSALOME.cxx +++ b/src/runtime/RuntimeSALOME.cxx @@ -806,6 +806,11 @@ InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport, //convertible type return new PyNeutral(inport); } + //last chance : an py output that is seq[objref] can be connected to a neutral input objref (P13268) + else if(type->kind()==Sequence && type->contentType()->kind()==Objref && inport->edGetType()->kind()==Objref) + { + return new PyNeutral(inport); + } //non convertible type stringstream msg; msg << "Cannot connect Python output port with type: " << type->id() ; diff --git a/src/yacsloader_swig/Test/StdAloneYacsLoaderTest1.py b/src/yacsloader_swig/Test/StdAloneYacsLoaderTest1.py index ee7278e6a..76c5bd11f 100644 --- a/src/yacsloader_swig/Test/StdAloneYacsLoaderTest1.py +++ b/src/yacsloader_swig/Test/StdAloneYacsLoaderTest1.py @@ -192,6 +192,44 @@ def sum(i): self.assertEqual(n.getState(),pilot.DISABLED) # <- test is here. pass + def test5(self): + """ Test focusing P13268. If I connect a list[pyobj] output inside a ForEach to a list[pyobj] outside a foreach it works now.""" + #self.assertTrue(False) + fname="testP1328.xml" + p=self.r.createProc("testP1328") + tc0=p.createInterfaceTc("python:obj:1.0","pyobj",[]) + tc1=p.createSequenceTc("list[pyobj]","list[pyobj]",tc0) + n0=self.r.createScriptNode("","n0") + n1=self.r.createForEachLoop("n1",tc0) + n10=self.r.createScriptNode("","n10") + n2=self.r.createScriptNode("","n2") + p.edAddChild(n0) ; p.edAddChild(n1) ; p.edAddChild(n2) ; n1.edAddChild(n10) + n0.setScript("o2=[[elt] for elt in range(10)]") + n10.setScript("o6=2*i5") + n2.setScript("assert(i8==[[0,0],[1,1],[2,2],[3,3],[4,4],[5,5],[6,6],[7,7],[8,8],[9,9]])") + o2=n0.edAddOutputPort("o2",tc1) + i5=n10.edAddInputPort("i5",tc0) + o6=n10.edAddOutputPort("o6",tc1) # the goal of test is here ! tc1 NOT tc0 ! + i8=n2.edAddInputPort("i8",tc1) + # + p.edAddCFLink(n0,n1) + p.edAddCFLink(n1,n2) + # + p.edAddLink(o2,n1.edGetSeqOfSamplesPort()) + p.edAddLink(n1.edGetSamplePort(),i5) + p.edAddLink(o6,i8) # important link for the test ! + # + n1.edGetNbOfBranchesPort().edInitInt(1) + # + p.saveSchema(fname) + # + ex=pilot.ExecutorSwig() + self.assertEqual(p.getState(),pilot.READY) + ex.RunW(p,0) + self.assertEqual(p.getState(),pilot.DONE) + self.assertEqual(p.getChildByName("n2").getInputPort("i8").getPyObj(),[[0,0],[1,1],[2,2],[3,3],[4,4],[5,5],[6,6],[7,7],[8,8],[9,9]]) + pass + def tearDown(self): del self.r del self.l -- 2.39.2