Salome HOME
Update copyright information
[modules/superv.git] / src / GraphExecutor / DataFlowExecutor_DataFlow.cxx
index 10d4cdb5e87f6917fb8636abee997d0a6753bc7e..f6a6ef54c52942634e01926f53cb6aeb24c97752 100644 (file)
@@ -1,31 +1,31 @@
-//  SUPERV GraphExecutor : contains classes that permit execution of graphs and particularly the execution automaton
+//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  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.
 //
-//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
-// 
-//  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 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 
-// 
-//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//  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
 //
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+//  SUPERV GraphExecutor : contains classes that permit execution of graphs and particularly the execution automaton
 //  File   : DataFlowExecutor_DataFlow.cxx
 //  Module : SUPERV
-
+//
 using namespace std;
 #include "DataFlowExecutor_DataFlow.hxx"
+#include "DataFlowEditor_DataFlow.hxx"
 
 // Implementation de la classe GraphExecutor::Graph
 
@@ -115,94 +115,222 @@ bool GraphExecutor::DataFlow::ContainerKill( const char *aNodeName ) {
 }
 
 bool GraphExecutor::DataFlow::InputOfAny( const char * ToServiceParameterName ,
-                             const CORBA::Any & aValue ) {
-  cdebug_in "GraphExecutor::DataFlow::InputOfAny" << endl ;
+                                          const CORBA::Any & aValue ,
+                                          bool SomeDataReady ) {
+  cdebug_in <<"GraphExecutor::DataFlow::InputOfAny( " << ToServiceParameterName
+            << " SomeDataReady " << SomeDataReady << " )" << endl ;
   bool RetVal = false ;
-  cdebug << pthread_self() << "GraphExecutor::DataFlow::::InputOfAny " << Graph()->Name() << "("
-         << ToServiceParameterName << ")" << endl ;
+  cdebug << pthread_self() << "GraphExecutor::DataFlow::InputOfAny " << Name() << "( "
+         << ToServiceParameterName << " , aValue , SomeDataReady " << SomeDataReady << " ) "
+         << endl ;
   if ( Graph()->GraphMacroLevel() ) {
     GraphBase::OutPort * anOutPort ;
     anOutPort = Graph()->GetChangeInDataNodePort( ToServiceParameterName ) ;
-    cdebug << pthread_self() << "GraphExecutor::DataFlow::InputOfAny " << Graph()->Name()
-           << " " << ToServiceParameterName << " " << anOutPort->State() << " Done " << anOutPort->Done()
-           << endl ;
-    RetVal = AddInputData( Graph()->Name() , ToServiceParameterName , aValue ) ;
-    anOutPort->State(  SUPERV::ReadyState ) ;
-    anOutPort->Done( true ) ;
+    cdebug << pthread_self() << "GraphExecutor::DataFlow::InputOfAny " << Name()
+           << " " << State() << " " << ToServiceParameterName << " " << anOutPort->PortState()
+           << " Done : " << anOutPort->PortDone() << endl ;
+    RetVal = AddInputData( Name() , ToServiceParameterName , aValue ) ;
+    anOutPort->PortState(  SUPERV::ReadyState ) ;
+// There is only one port :
+    anOutPort->ChangeInPorts( 0 )->PortState( SUPERV::ReadyState ) ;
+    anOutPort->PortDone( true ) ;
+// There is only one inport of a Node in an ReversedOutport of a graph :
     GraphExecutor::InNode * anInNode = (GraphExecutor::InNode * ) Graph()->GetChangeGraphNode( anOutPort->InPorts( 0 )->NodeName() )->GetInNode() ;
     cdebug << pthread_self() << "GraphExecutor::DataFlow::InputOfAny : " << anInNode->Name()
-           << "->SendSomeDataReady( " << Graph()->Name() << " ) " << endl ;
-    anInNode->SendSomeDataReady( Graph()->Name() ) ;
-    if ( anInNode->IsReady() ) {
-      cdebug << pthread_self() << "GraphExecutor::DataFlow::InputOfAny : " << anInNode->Name()
-             << "->SendEvent( GraphExecutor::ExecuteEvent ) "
-             << " " << anInNode->Name() << "->IsReady() " << anInNode->IsReady() << " State "
-             << anInNode->State() << endl ;
-      if ( anInNode->IsLockedDataWait() ) {
-        cdebug << pthread_self() << "GraphExecutor::DataFlow::InputOfAny : " << anInNode->Name()
-               << " IsLockedDataWait() ==> UnLockDataWait" << endl ;
-        anInNode->UnLockDataWait() ;
+           << "->SendSomeDataReady( " << Name() << " ) for Port "
+           << anOutPort->InPorts( 0 )->PortName() << " SomeDataReady " << SomeDataReady << endl ;
+    if ( SomeDataReady ) {
+      MESSAGE( "GraphExecutor::InputOfAny " << Name() << " SendSomeDataReady --> " << anInNode->Name()
+               << " " << anInNode->State() << " " << anOutPort->InPorts( 0 )->PortName() ) ;
+      int sts = anInNode->SendSomeDataReady( Name() ) ;
+      cdebug << "GraphExecutor::DataFlow::InputOfAny " << anInNode->Name()
+             << "->SendSomeDataReady( " << Name() << " ) sts " << sts << " State "
+             << anInNode->State() << " IsReady " << anInNode->IsReady()
+             << " SomeDataReady " << SomeDataReady << endl ;
+//JR 15.04.2005 Debug PAL8624 RetroConception :
+      if ( sts && anInNode->HasAllDataReady() ) {
+        cdebug << pthread_self() << "/" << anInNode->ThreadNo()
+               << "GraphExecutor::DataFlow::InputOfAny : "
+               << anInNode->Name() << "->SendEvent( GraphExecutor::ExecuteEvent ) "
+               << " " << anInNode->Name() << "->HasAllDataReady() " << anInNode->HasAllDataReady()
+               << " State " << anInNode->State() << endl ;
+        anInNode->ThreadNo( 0 ) ;
+        anInNode->CreateNewThread( true ) ;
+        if ( !anInNode->SendEvent( GraphExecutor::AllDataReadyEvent ) ) { // ==> Ready to execute
+//JR 06.05.2005 Debug PAL8624 RetroConception :
+#if 0
+        if ( res && anInNode->IsReady() ) {
+          cdebug << pthread_self() << "/" << anInNode->ThreadNo() << "GraphExecutor::DataFlow::InputOfAny : "
+                 << anInNode->Name() << "->SendEvent( GraphExecutor::ExecuteEvent ) "
+                 << " " << anInNode->Name() << "->IsReady() " << anInNode->IsReady() << " State "
+                 << anInNode->State() << endl ;
+//JR 15.04.2005 Debug PAL8624 RetroConception :
+//          if ( anInNode->IsLockedDataWait() ) {
+//            cdebug << pthread_self() << "/" << anInNode->ThreadNo() << "GraphExecutor::DataFlow::InputOfAny : "
+//                   << anInNode->Name() << " IsLockedDataWait() ==> UnLockDataWait" << endl ;
+//            anInNode->UnLockDataWait() ;
+//          }
+          anInNode->ThreadNo( 0 ) ;
+          anInNode->CreateNewThread( true ) ;
+          anInNode->SendEvent( GraphExecutor::ExecuteEvent ) ;
+//          State( GraphExecutor::ExecutingState ) ;
+        }
+        else {
+          RetVal = false ;
+#endif
+          cdebug << pthread_self() << "/" << anInNode->ThreadNo()
+                 << "GraphExecutor::DataFlow::InputOfAny : NotAllDataReady ERROR : "
+                 << anInNode->Name() << "->SendEvent( GraphExecutor::ExecuteEvent ) "
+                 << " " << anInNode->Name() << "->IsReady() " << anInNode->IsReady() << " State "
+                 << anInNode->State() << endl ;
+       }
+      }
+      else {
+        cdebug << pthread_self() << "/" << anInNode->ThreadNo()
+               << "GraphExecutor::DataFlow::InputOfAny : NotAllDataReady : "
+               << anInNode->Name() << "->SendEvent( GraphExecutor::ExecuteEvent ) "
+               << " " << anInNode->Name() << "->IsReady() " << anInNode->IsReady() << " State "
+               << anInNode->State() << endl ;
       }
-      anInNode->CreateNewThread( true ) ;
-      anInNode->SendEvent( GraphExecutor::ExecuteEvent ) ;
-      State( GraphExecutor::ExecutingState ) ;
     }
+    else {
+      cdebug << "GraphExecutor::DataFlow::InputOfAny " << anInNode->Name()
+             << "->SendSomeDataReady( " << Name() << " ) State "
+             << anInNode->State() << " IsReady " << anInNode->IsReady()
+             << " SomeDataReady " << SomeDataReady << endl ;
+    }
+  }
+  else {
+    cdebug << pthread_self() << "GraphExecutor::DataFlow::InputOfAny GraphMacroLevel "
+           << Graph()->GraphMacroLevel() << " ERROR" << endl ;
+    MESSAGE( "GraphExecutor::DataFlow::InputOfAny GraphMacroLevel " << Graph()->GraphMacroLevel()
+             << " ERROR" ) ;
   }
-  cdebug_out << "GraphExecutor::DataFlow::InputOfAny " << RetVal << endl ;
+  cdebug_out << pthread_self() << " GraphExecutor::DataFlow::InputOfAny " << RetVal << endl ;
   return RetVal ;
 }
 
 bool GraphExecutor::DataFlow::OutputOfAny( const char * aNodeName ,
                                            const char * ToServiceParameterName ,
                                            const CORBA::Any & aValue ) {
-  cdebug_in << "GraphExecutor::DataFlow::OutputOfAny" << endl ;
+  cdebug_in << pthread_self() << "/" << ThreadNo() << "GraphExecutor::DataFlow::OutputOfAny( " << aNodeName
+            << " , " << ToServiceParameterName
+            << " , aValue ) from " << Name() << endl ;
   bool RetVal = false ;
-  GraphBase::Graph * aMacroGraph = (GraphBase::Graph * ) Graph()->GetChangeGraphNode( aNodeName ) ;
+  GraphBase::Graph * aMacroNode = (GraphBase::Graph * ) Graph()->GetChangeGraphNode( aNodeName ) ;
 //  GraphExecutor::InNode * anInNode = (GraphExecutor::InNode * ) aMacroGraph->GetInNode() ;
   RetVal = Graph()->AddOutputData( aNodeName , ToServiceParameterName , aValue ) ;
-  GraphBase::OutPort * anOutPort = aMacroGraph->GetChangeOutPort( ToServiceParameterName ) ;
+  GraphBase::OutPort * anOutPort = aMacroNode->GetChangeOutPort( ToServiceParameterName ) ;
   int i ;
+  for ( i = 0 ; i < aMacroNode->GetNodeOutPortsSize() ; i++ ) {
+    cdebug << "Out" << i << " " << aMacroNode->GetNodeOutPort( i )->PortName() << " "
+           << aMacroNode->GetChangeNodeOutPort( i )->PortState() << " Done="
+           << aMacroNode->GetChangeNodeOutPort( i )->PortDone() << " " ;
+    if ( GraphBase::Base::_prof_debug ) {
+      aMacroNode->GetNodeOutPort( i )->StringValue( *GraphBase::Base::_fdebug ) ;
+    }
+    if ( aMacroNode->GetChangeNodeOutPort( i )->IsGate() ) {
+      cdebug << " BoolValue " << aMacroNode->GetChangeNodeOutPort( i )->BoolValue() ;
+    }
+    cdebug << endl ;
+  }
+// Loop over Inports linked to that OutPort of the MacroNode
   for ( i = 0 ; i < anOutPort->InPortsSize() ; i++ ) {
-    if ( strcmp( anOutPort->ChangeInPorts( i )->NodeName() , Graph()->Name() ) ) {
-      cdebug << "GraphExecutor::DataFlow::OutputOfAny toNodeName " << anOutPort->ChangeInPorts( i )->NodeName()
-             << "(" << anOutPort->ChangeInPorts( i )->PortName() << ")" << endl ;
-      GraphExecutor::InNode * aLinkedNode = (GraphExecutor::InNode * ) Graph()->GetChangeGraphNode( anOutPort->ChangeInPorts( i )->NodeName() )->GetInNode() ;
+    const char * ToNodeName = anOutPort->ChangeInPorts( i )->NodeName() ;
+    const char * ToParameterName = anOutPort->ChangeInPorts( i )->PortName() ;
+    if ( strcmp( ToNodeName , Name() ) ) {
+      GraphBase::ComputingNode * aComputingNode = Graph()->GetChangeGraphNode( ToNodeName ) ;
+      GraphExecutor::InNode * aLinkedNode = (GraphExecutor::InNode * ) aComputingNode->GetInNode() ;
+      cdebug << pthread_self() << "/" << aLinkedNode->ThreadNo()
+             << "GraphExecutor::DataFlow::OutputOfAny to Node "
+             << ToNodeName << "(" << ToParameterName << ") from MacroNode " << aNodeName << endl ;
       int sts ;
-      if ( aLinkedNode->IsLockedDataWait() ) {
-        cdebug << "GraphExecutor::DataFlow::OutputOfAny " << aLinkedNode->Name()
-               << " IsLockedDataWait --> UnLockDataWait" << endl ;
-      }
+//JR 15.04.2005 Debug PAL8624 RetroConception :
+//      if ( aLinkedNode->IsLockedDataWait() ) {
+//        cdebug << "GraphExecutor::DataFlow::OutputOfAny " << aLinkedNode->Name()
+//               << " IsLockedDataWait --> UnLockDataWait" << endl ;
+//      }
+      aLinkedNode->LockDataReady() ;
       sts = aLinkedNode->SendSomeDataReady( (char * ) aNodeName ) ;
-      cdebug << "GraphExecutor::DataFlow::OutputOfAny " << aLinkedNode->Name()
-             << "->SendSomeDataReady( " << aNodeName << " ) sts " << sts << endl ;
+      cdebug << pthread_self() << "/" << aLinkedNode->ThreadNo()
+             << "GraphExecutor::DataFlow::OutputOfAny " << aLinkedNode->Name()
+             << "->SendSomeDataReady( " << aNodeName << " ) sts " << sts << " " << aLinkedNode->State() << endl ;
       if ( sts ) {
-        if ( aLinkedNode->State() == GraphExecutor::DataReadyState ) {
-          aLinkedNode->CreateNewThreadIf( true ) ;
-          aLinkedNode->UnLockDataWait() ;
-          int res = aLinkedNode->DataUndef_AllDataReadyAction() ;
+//        if ( aLinkedNode->State() == GraphExecutor::DataReadyState ) {
+        if ( aLinkedNode->HasAllDataReady() ) {
+          cdebug << pthread_self() << "/" << aLinkedNode->ThreadNo()
+                 << "GraphExecutor::DataFlow::OutputOfAny SendEvent(ExecuteEvent) to "
+                 << aLinkedNode->Name() << endl ;
+//JR 15.04.2005 Debug PAL8624 RetroConception :
+//          aLinkedNode->CreateNewThreadIf( true ) ;
+//          aLinkedNode->UnLockDataWait() ;
+          aLinkedNode->CreateNewThread( true ) ;
+          aLinkedNode->UnLockDataReady() ;
+          aLinkedNode->HasAllDataReady( false ) ;
+//          aLinkedNode->SendEvent( GraphExecutor::ExecuteEvent ) ;
+          aLinkedNode->SendEvent( GraphExecutor::AllDataReadyEvent ) ;
+        }
+        else {
+          aLinkedNode->UnLockDataReady() ;
+          cdebug << pthread_self() << "/" << aLinkedNode->ThreadNo()
+                 << "GraphExecutor::DataFlow::OutputOfAny NO SendEvent(ExecuteEvent) to "
+                 << aLinkedNode->Name() << endl ;
         }
       }
+      else {
+        aLinkedNode->UnLockDataReady() ;
+      }
     }
     else if ( Graph()->GraphMacroLevel() != 0 ) {
-      cdebug << "GraphExecutor::DataFlow::OutputOfAny to MacroGraph " << anOutPort->ChangeInPorts( i )->NodeName()
-             << "(" << anOutPort->ChangeInPorts( i )->PortName() << ") " << Graph()->CoupledNodeName () << endl ;
-      Graph()->CoupledNode()->GraphExecutor()->OutputOfAny( Graph()->CoupledNodeName() ,
-                                                            anOutPort->ChangeInPorts( i )->PortName() ,
-                                                            *anOutPort->Value() ) ;
+      cdebug << pthread_self() << "/" << Graph()->CoupledNode()->ThreadNo()
+             << "GraphExecutor::DataFlow::OutputOfAny to that graph "
+             << ToNodeName << "(" << ToParameterName << ") " << State() << " " << Graph()->CoupledNodeName ()
+             << " sended recursively to the MacroNode coupled to that graph" << endl ;
+      Graph()->CoupledNode()->GraphEditor()->Executor()->OutputOfAny( Graph()->CoupledNodeName() ,
+                                                            ToParameterName ,
+//JR 30.03.2005                                                            *anOutPort->Value() ) ;
+                                                            anOutPort->Value() ) ;
     }
     else {
-      cdebug << "GraphExecutor::DataFlow::OutputOfAny to Graph " << anOutPort->ChangeInPorts( i )->NodeName()
-             << "(" << anOutPort->ChangeInPorts( i )->PortName() << ") ignored" << endl ;
+      cdebug << pthread_self() << "GraphExecutor::DataFlow::OutputOfAny to Node "
+             << ToNodeName << "(" << ToParameterName << ") from MacroNode " << aNodeName
+             << ") ignored" << endl ;
     }
   }
-  cdebug_out << "GraphExecutor::DataFlow::OutputOfAny " << RetVal << endl ;
+  cdebug_out << pthread_self() << "/" << ThreadNo() << " GraphExecutor::DataFlow::OutputOfAny " << RetVal
+             << endl ;
+  return RetVal ;
+}
+
+//JR NPAL14110 09.02.2007 : SetWaitingStates was missing in SubGraph of MacroNode !...
+bool GraphExecutor::DataFlow::SetWaitingStates( const char * ToServiceParameterName ) {
+  cdebug_in << pthread_self() << "/" << ThreadNo() << "GraphExecutor::DataFlow::SetWaitingStates( "
+            << ToServiceParameterName << " ) MacroGraph " << Name() << endl ;
+  bool RetVal = true ;
+  State( GraphExecutor::DataWaitingState ) ;
+  Done( false ) ;
+  GraphBase::OutPort * anOutPort ;
+  anOutPort = Graph()->GetChangeInDataNodePort( ToServiceParameterName ) ;
+  anOutPort->PortState(  SUPERV::WaitingState ) ;
+  anOutPort->PortDone( false ) ;
+  cdebug << pthread_self() << "GraphExecutor::DataFlow::SetWaitingStates " << Name()
+         << " " << State() << " " << ToServiceParameterName << " " << anOutPort->PortState()
+         << " Done : " << anOutPort->PortDone() << endl ;
+  if ( ! anOutPort->IsGate() ) {
+    GraphExecutor::InNode * anInNode = (GraphExecutor::InNode * ) Graph()->GetChangeGraphNode( anOutPort->InPorts( 0 )->NodeName() )->GetInNode() ;
+    cdebug << pthread_self() << "GraphExecutor::DataFlow::SetWaitingStates : "
+           << anInNode->Name() << "->SetWaitingStates( NULL ) for Port "
+           << anOutPort->InPorts( 0 )->PortName() << endl ;
+    anInNode->SetWaitingStates( NULL ) ;
+  }
+  cdebug_out << "GraphExecutor::DataFlow::SetWaitingStates() " << RetVal << endl;
   return RetVal ;
 }
 
 bool GraphExecutor::DataFlow::Kill() {
   cdebug_in << "GraphExecutor::DataFlow::Kill()" << endl;
   bool RetVal = GraphExecutor::OutNode::Kill() ;
-  cdebug_out << "GraphExecutor::DataFlow::Kill()" << endl;
+  cdebug_out << "GraphExecutor::DataFlow::Kill() " << RetVal << endl;
   return RetVal ;
 }