Salome HOME
Issue EDF13268 - link from list[pyobj] inside ForEachLoop to list[pyobj] outside...
authorAnthony Geay <anthony.geay@edf.fr>
Thu, 27 Oct 2016 09:25:00 +0000 (11:25 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Thu, 27 Oct 2016 09:25:00 +0000 (11:25 +0200)
src/engine/ForEachLoop.cxx
src/engine/ForEachLoop.hxx
src/engine/TypeCode.cxx
src/engine/TypeCode.hxx
src/runtime/RuntimeSALOME.cxx
src/yacsloader_swig/Test/StdAloneYacsLoaderTest1.py

index 83af9c7e7c9d5b738338da5a7eef930b71dc19ac..b1b86d4f575a43e38937d084fd76145cee0fe05e 100644 (file)
@@ -915,7 +915,8 @@ void ForEachLoop::buildDelegateOf(std::pair<OutPort *, OutPort *>& 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<OutPort *, OutPort *>& 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<unsigned int>& 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<ForEachLoop *>(work));
+      if(isFE)
+        ret++;
+      work=work->getFather();
+    }
+  work=ne;
+  int delta(0);
+  while(work!=co)
+    {
+      ForEachLoop *isFE(dynamic_cast<ForEachLoop *>(work));
+      if(isFE)
+        delta++;
+      work=work->getFather();
+    }
+  if(dynamic_cast<AnySplitOutputPort *>(start))
+    ret--;
+  return ret-delta;
+}
index f2cd2d10a957000d0fe2eb62926d0f071433a46b..7c1968d38eca47298b28895e43f192aed1679dc7 100644 (file)
@@ -195,6 +195,7 @@ namespace YACS
       std::list<ProgressWeight> getProgressWeight() const;
       int getCurrentIndex() const { return _currentIndex; }
       int getNbOfElementsToBeProcessed() const;
+      static int getFEDeltaBetween(OutPort *start, InPort *end);
 #ifndef SWIG
       std::vector<unsigned int> getPassedResults(Executor *execut, std::vector<SequenceAny *>& outputs, std::vector<std::string>& nameOfOutputs) const;
       void assignPassedResults(const std::vector<unsigned int>& passedIds, const std::vector<SequenceAny *>& passedOutputs, const std::vector<std::string>& nameOfOutputs);
index 38560cf0cf28e265a07644e6d6f7ba60e15ae9df..f7c4774474b2a1a5575d51a67074d753ee8306ef 100644 (file)
@@ -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;i<lev;i++)
+    {
+      const TypeCode *cand(ret->contentType());
+      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;
index 5d16a01ac45f4962f96a5449147efb0e5a69d181..1856e73a2008d6b1d54ca5f73ec2e87a4207a6fa 100644 (file)
@@ -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 ;
index 71afc05a120a00fcb425057710da417c9ca3ba66..7fbeb28d38ca8bc25633b0c89da3c76c3e9629d4 100644 (file)
@@ -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() ;
index ee7278e6affb76549965eb1bc1ab5b67a723667e..76c5bd11fb01cc0c851446219a85c95010201e2b 100644 (file)
@@ -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