Salome HOME
MacroNodes
[modules/superv.git] / src / GraphExecutor / DataFlowExecutor_DataFlow.cxx
1 //  SUPERV GraphExecutor : contains classes that permit execution of graphs and particularly the execution automaton
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : DataFlowExecutor_DataFlow.cxx
25 //  Module : SUPERV
26
27 using namespace std;
28 #include "DataFlowExecutor_DataFlow.hxx"
29 #include "DataFlowEditor_DataFlow.hxx"
30
31 // Implementation de la classe GraphExecutor::Graph
32
33 GraphExecutor::DataFlow::DataFlow() :
34   OutNode() {
35   cdebug_in << "GraphExecutor::DataFlow::DataFlowExecutor()" << endl;
36
37   _theNamingService = NULL ;
38   
39   cdebug_out << "GraphExecutor::DataFlow::DataFlowExecutor()" << endl;
40 }
41
42 GraphExecutor::DataFlow::DataFlow( CORBA::ORB_ptr ORB,
43                                    SALOME_NamingService* ptrNamingService ,
44                                    const char *DataFlowName ,
45                                    const char * DebugFileName ,
46                                    const SUPERV::KindOfNode aKindOfNode ) :
47   OutNode( ORB, ptrNamingService , DataFlowName , DebugFileName , aKindOfNode ) {
48   cdebug_in << "GraphExecutor::DataFlow::DataFlow(" ;
49   if ( DataFlowName ) {
50     cdebug << DataFlowName ;
51   }
52   cdebug << ")" << endl;
53
54   _theNamingService = ptrNamingService ;
55
56   cdebug_out << "GraphExecutor::DataFlow::DataFlow" << endl;
57 }
58
59 GraphExecutor::DataFlow::DataFlow( CORBA::ORB_ptr ORB,
60                                    SALOME_NamingService* ptrNamingService ,
61                                    const SALOME_ModuleCatalog::Service& DataFlowService ,
62                                    const char *DataFlowComponentName ,
63                                    const char *DataFlowInterfaceName ,
64                                    const char *DataFlowName ,
65                                    const SUPERV::KindOfNode DataFlowkind ,
66                                    const SUPERV::SDate DataFlowFirstCreation ,
67                                    const SUPERV::SDate DataFlowLastModification ,
68                                    const char * DataFlowExecutorRelease ,
69                                    const char * DataFlowAuthor ,
70                                    const char * DataFlowComputer ,
71                                    const char * DataFlowComment ,
72                                    const char * DebugFileName ) :
73      OutNode( ORB, ptrNamingService , DataFlowService , DataFlowComponentName ,
74               DataFlowInterfaceName , DataFlowName , DataFlowkind ,
75               DataFlowFirstCreation , DataFlowLastModification  ,
76               DataFlowExecutorRelease , DataFlowAuthor ,
77               DataFlowComputer , DataFlowComment , DebugFileName ) {
78   cdebug_in << "GraphExecutor::DataFlow::DataFlow(" << DataFlowName << ")" << endl;
79
80   _theNamingService = ptrNamingService ;
81
82   cdebug_out << "GraphExecutor::DataFlow::DataFlow" << endl;
83 } ;
84
85 GraphExecutor::DataFlow::~DataFlow() {
86 //  delete _DataFlowNode ;
87 //  delete _DataFlowDatas ;
88 //  delete _GT ;
89 }
90
91 bool GraphExecutor::DataFlow::Ping( const char *aNodeName ) {
92   cdebug_in << "GraphExecutor::DataFlow::Ping" << aNodeName << " )" << endl;
93   bool RetVal = false ;
94   if ( Graph()->GetGraphNode( aNodeName ) )
95     RetVal = ((GraphExecutor::InNode *) Graph()->GetGraphNode( aNodeName )->GetInNode())->Ping() ;
96   cdebug_out << "GraphExecutor::DataFlow::Ping" << endl;
97   return RetVal ;
98 }
99
100 bool GraphExecutor::DataFlow::ContainerKill() {
101   cdebug_in << "GraphExecutor::DataFlow::ContainerKill()" << endl;
102   bool RetVal = GraphExecutor::OutNode::ContainerKill() ;
103   cdebug_out << "GraphExecutor::DataFlow::ContainerKill()" << endl;
104   return RetVal ;
105 }
106
107 bool GraphExecutor::DataFlow::ContainerKill( const char *aNodeName ) {
108 //  cdebug_in << "GraphExecutor::DataFlow::ContainerKill( " << aNodeName << " )"<< endl;
109   bool RetVal = false ;
110   GraphExecutor::InNode * aNode = ((GraphExecutor::InNode *) Graph()->GetGraphNode( aNodeName )->GetInNode()) ;
111   if ( aNode ) {
112     RetVal = aNode->ContainerKill() ;
113   }
114 //  cdebug_out << "GraphExecutor::DataFlow::ContainerKill" << endl;
115   return RetVal ;
116 }
117
118 bool GraphExecutor::DataFlow::InputOfAny( const char * ToServiceParameterName ,
119                                           const CORBA::Any & aValue ,
120                                           bool SomeDataReady ) {
121   cdebug_in <<"GraphExecutor::DataFlow::InputOfAny( " << ToServiceParameterName
122             << " SomeDataReady " << SomeDataReady << " )" << endl ;
123   bool RetVal = false ;
124   cdebug << pthread_self() << "GraphExecutor::DataFlow::InputOfAny " << Name() << "( "
125          << ToServiceParameterName << " , aValue , SomeDataReady " << SomeDataReady << " ) "
126          << endl ;
127   if ( Graph()->GraphMacroLevel() ) {
128     GraphBase::OutPort * anOutPort ;
129     anOutPort = Graph()->GetChangeInDataNodePort( ToServiceParameterName ) ;
130     cdebug << pthread_self() << "GraphExecutor::DataFlow::InputOfAny " << Name()
131            << " " << State() << " " << ToServiceParameterName << " " << anOutPort->PortState()
132            << " Done : " << anOutPort->PortDone() << endl ;
133     RetVal = AddInputData( Name() , ToServiceParameterName , aValue ) ;
134     anOutPort->PortState(  SUPERV::ReadyState ) ;
135 // There is only one port :
136     anOutPort->ChangeInPorts( 0 )->PortState( SUPERV::ReadyState ) ;
137     anOutPort->PortDone( true ) ;
138 // There is only one inport of a Node in an ReversedOutport of a graph :
139     GraphExecutor::InNode * anInNode = (GraphExecutor::InNode * ) Graph()->GetChangeGraphNode( anOutPort->InPorts( 0 )->NodeName() )->GetInNode() ;
140     cdebug << pthread_self() << "GraphExecutor::DataFlow::InputOfAny : " << anInNode->Name()
141            << "->SendSomeDataReady( " << Name() << " ) for Port "
142            << anOutPort->InPorts( 0 )->PortName() << " SomeDataReady " << SomeDataReady << endl ;
143     if ( SomeDataReady ) {
144       MESSAGE( "GraphExecutor::InputOfAny " << Name() << " SendSomeDataReady --> " << anInNode->Name()
145                << " " << anInNode->State() << " " << anOutPort->InPorts( 0 )->PortName() ) ;
146       int sts = anInNode->SendSomeDataReady( Name() ) ;
147       cdebug << "GraphExecutor::DataFlow::InputOfAny " << anInNode->Name()
148              << "->SendSomeDataReady( " << Name() << " ) sts " << sts << " State "
149              << anInNode->State() << " IsReady " << anInNode->IsReady()
150              << " SomeDataReady " << SomeDataReady << endl ;
151 //JR 15.04.2005 Debug PAL8624 RetroConception :
152       if ( sts && anInNode->HasAllDataReady() ) {
153         cdebug << pthread_self() << "/" << anInNode->ThreadNo()
154                << "GraphExecutor::DataFlow::InputOfAny : "
155                << anInNode->Name() << "->SendEvent( GraphExecutor::ExecuteEvent ) "
156                << " " << anInNode->Name() << "->HasAllDataReady() " << anInNode->HasAllDataReady()
157                << " State " << anInNode->State() << endl ;
158         anInNode->ThreadNo( 0 ) ;
159         anInNode->CreateNewThread( true ) ;
160         if ( !anInNode->SendEvent( GraphExecutor::AllDataReadyEvent ) ) { // ==> Ready to execute
161 //JR 06.05.2005 Debug PAL8624 RetroConception :
162 #if 0
163         if ( res && anInNode->IsReady() ) {
164           cdebug << pthread_self() << "/" << anInNode->ThreadNo() << "GraphExecutor::DataFlow::InputOfAny : "
165                  << anInNode->Name() << "->SendEvent( GraphExecutor::ExecuteEvent ) "
166                  << " " << anInNode->Name() << "->IsReady() " << anInNode->IsReady() << " State "
167                  << anInNode->State() << endl ;
168 //JR 15.04.2005 Debug PAL8624 RetroConception :
169 //          if ( anInNode->IsLockedDataWait() ) {
170 //            cdebug << pthread_self() << "/" << anInNode->ThreadNo() << "GraphExecutor::DataFlow::InputOfAny : "
171 //                   << anInNode->Name() << " IsLockedDataWait() ==> UnLockDataWait" << endl ;
172 //            anInNode->UnLockDataWait() ;
173 //          }
174           anInNode->ThreadNo( 0 ) ;
175           anInNode->CreateNewThread( true ) ;
176           anInNode->SendEvent( GraphExecutor::ExecuteEvent ) ;
177 //          State( GraphExecutor::ExecutingState ) ;
178         }
179         else {
180           RetVal = false ;
181 #endif
182           cdebug << pthread_self() << "/" << anInNode->ThreadNo()
183                  << "GraphExecutor::DataFlow::InputOfAny : NotAllDataReady ERROR : "
184                  << anInNode->Name() << "->SendEvent( GraphExecutor::ExecuteEvent ) "
185                  << " " << anInNode->Name() << "->IsReady() " << anInNode->IsReady() << " State "
186                  << anInNode->State() << endl ;
187         }
188       }
189       else {
190         cdebug << pthread_self() << "/" << anInNode->ThreadNo()
191                << "GraphExecutor::DataFlow::InputOfAny : NotAllDataReady : "
192                << anInNode->Name() << "->SendEvent( GraphExecutor::ExecuteEvent ) "
193                << " " << anInNode->Name() << "->IsReady() " << anInNode->IsReady() << " State "
194                << anInNode->State() << endl ;
195       }
196     }
197     else {
198       cdebug << "GraphExecutor::DataFlow::InputOfAny " << anInNode->Name()
199              << "->SendSomeDataReady( " << Name() << " ) State "
200              << anInNode->State() << " IsReady " << anInNode->IsReady()
201              << " SomeDataReady " << SomeDataReady << endl ;
202     }
203   }
204   else {
205     cdebug << pthread_self() << "GraphExecutor::DataFlow::InputOfAny GraphMacroLevel "
206            << Graph()->GraphMacroLevel() << " ERROR" << endl ;
207     MESSAGE( "GraphExecutor::DataFlow::InputOfAny GraphMacroLevel " << Graph()->GraphMacroLevel()
208              << " ERROR" ) ;
209   }
210   cdebug_out << pthread_self() << " GraphExecutor::DataFlow::InputOfAny " << RetVal << endl ;
211   return RetVal ;
212 }
213
214 bool GraphExecutor::DataFlow::OutputOfAny( const char * aNodeName ,
215                                            const char * ToServiceParameterName ,
216                                            const CORBA::Any & aValue ) {
217   cdebug_in << pthread_self() << "/" << ThreadNo() << "GraphExecutor::DataFlow::OutputOfAny( " << aNodeName
218             << " , " << ToServiceParameterName
219             << " , aValue ) from " << Name() << endl ;
220   bool RetVal = false ;
221   GraphBase::Graph * aMacroNode = (GraphBase::Graph * ) Graph()->GetChangeGraphNode( aNodeName ) ;
222 //  GraphExecutor::InNode * anInNode = (GraphExecutor::InNode * ) aMacroGraph->GetInNode() ;
223   RetVal = Graph()->AddOutputData( aNodeName , ToServiceParameterName , aValue ) ;
224   GraphBase::OutPort * anOutPort = aMacroNode->GetChangeOutPort( ToServiceParameterName ) ;
225   int i ;
226   for ( i = 0 ; i < aMacroNode->GetNodeOutPortsSize() ; i++ ) {
227     cdebug << "Out" << i << " " << aMacroNode->GetNodeOutPort( i )->PortName() << " "
228            << aMacroNode->GetChangeNodeOutPort( i )->PortState() << " Done="
229            << aMacroNode->GetChangeNodeOutPort( i )->PortDone() << " " ;
230     if ( GraphBase::Base::_prof_debug ) {
231       aMacroNode->GetNodeOutPort( i )->StringValue( *GraphBase::Base::_fdebug ) ;
232     }
233     if ( aMacroNode->GetChangeNodeOutPort( i )->IsGate() ) {
234       cdebug << " BoolValue " << aMacroNode->GetChangeNodeOutPort( i )->BoolValue() ;
235     }
236     cdebug << endl ;
237   }
238 // Loop over Inports linked to that OutPort of the MacroNode
239   for ( i = 0 ; i < anOutPort->InPortsSize() ; i++ ) {
240     const char * ToNodeName = anOutPort->ChangeInPorts( i )->NodeName() ;
241     const char * ToParameterName = anOutPort->ChangeInPorts( i )->PortName() ;
242     GraphBase::ComputingNode * aComputingNode = Graph()->GetChangeGraphNode( ToNodeName ) ;
243     if ( strcmp( ToNodeName , Name() ) ) {
244       GraphExecutor::InNode * aLinkedNode = (GraphExecutor::InNode * ) aComputingNode->GetInNode() ;
245       cdebug << pthread_self() << "/" << aLinkedNode->ThreadNo()
246              << "GraphExecutor::DataFlow::OutputOfAny to Node "
247              << ToNodeName << "(" << ToParameterName << ") from MacroNode " << aNodeName << endl ;
248       int sts ;
249 //JR 15.04.2005 Debug PAL8624 RetroConception :
250 //      if ( aLinkedNode->IsLockedDataWait() ) {
251 //        cdebug << "GraphExecutor::DataFlow::OutputOfAny " << aLinkedNode->Name()
252 //               << " IsLockedDataWait --> UnLockDataWait" << endl ;
253 //      }
254       aLinkedNode->LockDataReady() ;
255       sts = aLinkedNode->SendSomeDataReady( (char * ) aNodeName ) ;
256       cdebug << pthread_self() << "/" << aLinkedNode->ThreadNo()
257              << "GraphExecutor::DataFlow::OutputOfAny " << aLinkedNode->Name()
258              << "->SendSomeDataReady( " << aNodeName << " ) sts " << sts << " " << aLinkedNode->State() << endl ;
259       if ( sts ) {
260 //        if ( aLinkedNode->State() == GraphExecutor::DataReadyState ) {
261         if ( aLinkedNode->HasAllDataReady() ) {
262           cdebug << pthread_self() << "/" << aLinkedNode->ThreadNo()
263                  << "GraphExecutor::DataFlow::OutputOfAny SendEvent(ExecuteEvent) to "
264                  << aLinkedNode->Name() << endl ;
265 //JR 15.04.2005 Debug PAL8624 RetroConception :
266 //          aLinkedNode->CreateNewThreadIf( true ) ;
267 //          aLinkedNode->UnLockDataWait() ;
268           aLinkedNode->CreateNewThread( true ) ;
269           aLinkedNode->UnLockDataReady() ;
270           aLinkedNode->HasAllDataReady( false ) ;
271 //          aLinkedNode->SendEvent( GraphExecutor::ExecuteEvent ) ;
272           aLinkedNode->SendEvent( GraphExecutor::AllDataReadyEvent ) ;
273         }
274         else {
275           aLinkedNode->UnLockDataReady() ;
276           cdebug << pthread_self() << "/" << aLinkedNode->ThreadNo()
277                  << "GraphExecutor::DataFlow::OutputOfAny NO SendEvent(ExecuteEvent) to "
278                  << aLinkedNode->Name() << endl ;
279         }
280       }
281       else {
282         aLinkedNode->UnLockDataReady() ;
283       }
284     }
285     else if ( Graph()->GraphMacroLevel() != 0 ) {
286       cdebug << pthread_self() << "/" << Graph()->CoupledNode()->ThreadNo()
287              << "GraphExecutor::DataFlow::OutputOfAny to that graph "
288              << ToNodeName << "(" << ToParameterName << ") " << State() << " " << Graph()->CoupledNodeName ()
289              << " sended recursively to the MacroNode coupled to that graph" << endl ;
290       Graph()->CoupledNode()->GraphEditor()->Executor()->OutputOfAny( Graph()->CoupledNodeName() ,
291                                                             ToParameterName ,
292 //JR 30.03.2005                                                            *anOutPort->Value() ) ;
293                                                             anOutPort->Value() ) ;
294     }
295     else {
296       cdebug << "GraphExecutor::DataFlow::OutputOfAny to Graph " << ToNodeName
297              << "(" << ToParameterName << ") ignored" << endl ;
298     }
299   }
300   cdebug_out << pthread_self() << "/" << ThreadNo() << " GraphExecutor::DataFlow::OutputOfAny " << RetVal
301              << endl ;
302   return RetVal ;
303 }
304
305 bool GraphExecutor::DataFlow::Kill() {
306   cdebug_in << "GraphExecutor::DataFlow::Kill()" << endl;
307   bool RetVal = GraphExecutor::OutNode::Kill() ;
308   cdebug_out << "GraphExecutor::DataFlow::Kill() " << RetVal << endl;
309   return RetVal ;
310 }
311
312 bool GraphExecutor::DataFlow::Kill( const char *aNodeName ) {
313 //  cdebug_in << "GraphExecutor::DataFlow::Kill( " << aNodeName << " )"<< endl;
314   bool RetVal = false ;
315   GraphExecutor::InNode * aNode = ((GraphExecutor::InNode *) Graph()->GetGraphNode( aNodeName )->GetInNode()) ;
316   if ( aNode ) {
317     RetVal = aNode->Kill() ;
318   }
319 //  cdebug_out << "GraphExecutor::DataFlow::Kill" << endl;
320   return RetVal ;
321 }
322
323 bool GraphExecutor::DataFlow::KillDone( const char *aNodeName ) {
324 //  cdebug_in << "GraphExecutor::DataFlow::KillDone( " << aNodeName << " )"<< endl;
325   bool RetVal = false ;
326   GraphExecutor::InNode * aNode = ((GraphExecutor::InNode *) Graph()->GetGraphNode( aNodeName )->GetInNode()) ;
327   if ( aNode ) {
328     RetVal = aNode->KillDone() ;
329   }
330 //  cdebug_out << "GraphExecutor::DataFlow::KillDone" << endl;
331   return RetVal ;
332 }
333
334 bool GraphExecutor::DataFlow::Suspend() {
335   cdebug_in << "GraphExecutor::DataFlow::Suspend()" << endl;
336   bool RetVal = GraphExecutor::OutNode::Suspend() ;
337   cdebug_out << "GraphExecutor::DataFlow::Suspend()" << RetVal << endl;
338   return RetVal ;
339 }
340
341 bool GraphExecutor::DataFlow::Suspend( const char *aNodeName ) {
342 //  cdebug_in << "GraphExecutor::DataFlow::Suspend( " << aNodeName << " )"<< endl;
343   bool RetVal = false ;
344   GraphExecutor::InNode * aNode = ((GraphExecutor::InNode *) Graph()->GetGraphNode( aNodeName )->GetInNode()) ;
345   if ( aNode ) {
346     RetVal = aNode->Suspend() ;
347   }
348 //  cdebug_out << "GraphExecutor::DataFlow::Suspend" << endl;
349   return RetVal ;
350 }
351
352 bool GraphExecutor::DataFlow::SuspendDone() {
353   cdebug_in << "GraphExecutor::DataFlow::SuspendDone()" << endl;
354   bool RetVal = false ;
355   cdebug << "Kill not yet implemented." << endl;
356   cdebug_out << "GraphExecutor::DataFlow::SuspendDone()" << endl;
357   return RetVal ;
358 }
359
360 bool GraphExecutor::DataFlow::SuspendDone( const char *aNodeName ) {
361 //  cdebug_in << "GraphExecutor::DataFlow::SuspendDone( " << aNodeName << " )"<< endl;
362   bool RetVal = false ;
363   GraphExecutor::InNode * aNode = ((GraphExecutor::InNode *) Graph()->GetGraphNode( aNodeName )->GetInNode()) ;
364   if ( aNode ) {
365     RetVal = aNode->SuspendDone() ;
366   }
367 //  cdebug_out << "GraphExecutor::DataFlow::SuspendDone" << endl;
368   return RetVal ;
369 }
370
371 bool GraphExecutor::DataFlow::Resume() {
372   cdebug_in << "GraphExecutor::DataFlow::Resume()" << endl;
373   bool RetVal = GraphExecutor::OutNode::Resume() ;
374   cdebug_out << "GraphExecutor::DataFlow::Resume()" << RetVal << endl;
375   return RetVal ;
376 }
377
378 bool GraphExecutor::DataFlow::Resume( const char *aNodeName ) {
379 //  cdebug_in << "GraphExecutor::DataFlow::Resume( " << aNodeName << " )"<< endl;
380   bool RetVal = false ;
381   GraphExecutor::InNode * aNode = ((GraphExecutor::InNode *) Graph()->GetGraphNode( aNodeName )->GetInNode()) ;
382   if ( aNode ) {
383     RetVal = aNode->Resume() ;
384   }
385 //  cdebug_out << "GraphExecutor::DataFlow::Resume" << endl;
386   return RetVal ;
387 }
388
389 bool GraphExecutor::DataFlow::Stop() {
390   cdebug_in << "GraphExecutor::DataFlow::Stop()" << endl;
391   bool RetVal = GraphExecutor::OutNode::Stop() ;
392   cdebug_out << "GraphExecutor::DataFlow::Stop()" << endl;
393   return RetVal ;
394 }
395
396 bool GraphExecutor::DataFlow::Stop( const char *aNodeName ) {
397 //  cdebug_in << "GraphExecutor::DataFlow::Stop( " << aNodeName << " )"<< endl;
398   bool RetVal = false ;
399   GraphExecutor::InNode * aNode = ((GraphExecutor::InNode *) Graph()->GetGraphNode( aNodeName )->GetInNode()) ;
400   if ( aNode ) {
401     RetVal = aNode->Stop() ;
402   }
403 //  cdebug_out << "GraphExecutor::DataFlow::Stop" << endl;
404   return RetVal ;
405 }
406