Salome HOME
SMH: 3.0.0 preparation = merged version (POLYWORK + RTVDEBUG01) + adopation for new GUI
[modules/superv.git] / src / GraphBase / DataFlowBase_SwitchNode.cxx
1 //  SUPERV GraphBase : contains fondamental classes for Services, Input Ports, Output Ports Links and Nodes.
2 //
3 //  Copyright (C) 2003  CEA/DEN, EDF R&D
4 //
5 //
6 //
7 //  File   : DataFlowBase_SwitchNode.cxx
8 //  Author : Jean Rahuel, CEA
9 //  Module : SUPERV
10 //  $Header:
11
12 using namespace std;
13 //#include <sstream>
14 //#include <iostream>
15
16 #include "DataFlowBase_SwitchNode.hxx"
17 #include "DataFlowBase_EndOfSwitchNode.hxx"
18 #include "DataFlowBase_Graph.hxx"
19
20 GraphBase::SwitchNode::SwitchNode() :
21   GraphBase::GOTONode::GOTONode() {
22
23   cdebug << "GraphBase::SwitchNode::SwitchNode "  << this 
24          << " _Name " << (void *) Name() << " " << Name() << " _Comment "
25          << (void *) Comment() << " "  << Comment() << " "  << endl ;
26
27 }
28
29 GraphBase::SwitchNode::SwitchNode( CORBA::ORB_ptr ORB ,
30                                    SALOME_NamingService* ptrNamingService ,
31                                    const char * FuncName ,
32                                    const SUPERV::ListOfStrings & aPythonFunction ,
33                                    const char *NodeName ,
34                                    const SUPERV::KindOfNode akind ,
35                                    const SUPERV::SDate NodeFirstCreation ,
36                                    const SUPERV::SDate NodeLastModification  ,
37                                    const char * NodeEditorRelease ,
38                                    const char * NodeAuthor ,
39                                    const char * NodeComment ,
40                                    const bool   GeneratedName ,
41                                    const long   X ,
42                                    const long   Y ,
43                                    int * Graph_prof_debug ,
44                                    ofstream * Graph_fdebug ) :
45   GraphBase::GOTONode::GOTONode( ORB , ptrNamingService , FuncName , aPythonFunction ,
46                                  NodeName , akind , NodeFirstCreation ,
47                                  NodeLastModification  , NodeEditorRelease ,
48                                  NodeAuthor , NodeComment , GeneratedName ,
49                                  X , Y , Graph_prof_debug , Graph_fdebug ) {
50
51   cdebug_in << "GraphBase::SwitchNode::SwitchNode "  << this 
52             << "' _Name " << (void *) Name() << " '" << Name() << " _Comment "
53             << (void *) Comment() << " "  << Comment() << " " 
54             << " KindOfNode " << Kind() << " FuncName " << FuncName
55             << " ServiceName " << ServiceName() << " In("
56             << ServiceInParameter().length()
57             << ") Out(" << ServiceOutParameter().length() << ")" << endl ;
58
59   cdebug_out << "GraphBase::SwitchNode::SwitchNode" << endl;
60 }
61
62 GraphBase::SwitchNode::~SwitchNode() {
63   cdebug << "GraphBase::SwitchNode::~SwitchNode "  << this 
64          << " _Name " << (void *) Name() << " " << Name() << " _Comment "
65          << (void *) Comment() << " "  << Comment() << " "  << endl ;
66 //  if ( _ComponentName != NULLSTRING )
67 //    delete [] _ComponentName ;
68 //  delete [] _Name ;
69 //  delete [] _EditorRelease ;
70 //  if ( _Author != NULLSTRING )
71 //    delete [] _Author ;
72 //  if ( _Computer != FACTORYSERVER )
73 //    delete [] _Computer;
74 //  if ( _Comment != NULLSTRING )
75 //    delete [] _Comment;
76 }
77
78 bool GraphBase::SwitchNode::CheckSwitch() const {
79   GraphBase::EndOfSwitchNode * anEndSwitchNode ;
80   anEndSwitchNode = (GraphBase::EndOfSwitchNode * ) CoupledNode() ;
81   cdebug_in << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
82             << anEndSwitchNode->Name() << endl;
83   int i ;
84
85 //All nodes between Switch and EndSwitch will have _BranchOfSwitchDone to false
86 //When we have to execute such a node in a switchbranch, if _BranchOfSwitchDone is true we have
87 // an error ; else we set _BranchOfSwitchDone to true
88   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
89     GraphBase::OutPort * anOutPort = GetChangeNodeOutPort( i ) ;
90     if ( anOutPort->IsSwitch() || anOutPort->IsGate() ) {
91       int j ;
92       for ( j = 0 ; j < anOutPort->InPortsSize() ; j++ ) {
93         GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( j ) ;
94         GraphBase::ComputingNode * aNode ;
95         aNode = GraphOfNode()->GetChangeGraphNode( anInPort->NodeName() ) ;
96         if ( aNode && aNode != anEndSwitchNode ) {
97           aNode->InitBranchOfSwitchDone( true , anEndSwitchNode ) ;
98         }
99       }
100     }
101   }
102
103   bool DefaultConnected = false ;
104 //OutPorts of the SwitchNode
105   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
106     GraphBase::OutPort * anOutPort = GetChangeNodeOutPort( i ) ;
107     if ( anOutPort->IsSwitch() || anOutPort->IsGate() ) {
108 // We have a branch of the switch
109       cdebug << endl << Name() << "->SwitchNode::CheckSwitch OutPort " << anOutPort->PortName()
110              << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
111              << " SWITCHBRANCH" << endl ;
112
113 //JR 11.02.2005 : if Default is not connected and if Default is true at execution time, the SwitchNode
114 // execution will be aborted
115 //Behavior : in that case, that means that a SwitchBranch should be a DefaultBranch and it is not the case !
116 //1. DEFAULT_OUTPORT
117 //JR 07.04.2005 Debug : an OutPort of the SwitchNode may be linked to the DefaultPort of
118 //                      the EndSwitchNode <==>
119 //                      SwitchNode( Default ) --> EndSwitchNode( Default )
120       bool EndSwitchNode_Default = false ;
121       if ( anOutPort->InPortsSize() ) {
122         GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( 0 ) ;
123         GraphBase::ComputingNode * aNode ;
124         aNode = GraphOfNode()->GetChangeGraphNode( anInPort->NodeName() ) ;
125         if ( aNode == anEndSwitchNode ) {
126           EndSwitchNode_Default = true ;
127         }
128       }
129 //JR 07.04.2005      if ( anOutPort->IsGate() ) {
130       if ( anOutPort->IsGate() || EndSwitchNode_Default ) {
131         if ( anOutPort->InPortsSize() == 0 ) {
132 // DefaultPort of the SwitchNode is not connected
133           cdebug_out << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
134                      << anEndSwitchNode->Name() << " OutPort " << anOutPort->PortName() << " "
135                      << anOutPort->InPortsSize() << " InPortsSize EndSwitch(Default) "
136                      << anEndSwitchNode->GetNodeInGate()->PortStatus() << "WARNING" << endl;
137         }
138         else {
139 // But the DefaultPort of the EndSwitchNode is connected : so there is a branch going to
140 // that DefaultPort
141           cdebug_out << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
142                      << anEndSwitchNode->Name() << " OutPort " << anOutPort->PortName() << " "
143                      << " " << anOutPort->PortStatus() << " " << anOutPort->InPortsSize() << " InPortsSize "
144                      << endl ;
145           DefaultConnected = true ;
146
147           anEndSwitchNode->InitEndSwitchInPortLinked() ;
148
149 // That DefaultBranch have to go directly to the EndSwitchNode
150           GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( 0 ) ;
151           GraphBase::ComputingNode * aNode ;
152           aNode = GraphOfNode()->GetChangeGraphNode( anInPort->NodeName() ) ;
153           if ( aNode != anEndSwitchNode ) {
154             cdebug_out << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
155                        << anEndSwitchNode->Name() << " for OutPort " << anOutPort->PortName()
156                        << " linked to " << aNode->Name() << " WARNING false" << endl;
157             return false ;
158           }
159           cdebug << endl << Name() << " Check of " << anOutPort->PortName() << " switch port branch"
160                  << " to EndSwitchNode" << endl ;
161 // All of InPorts of the EndSwitchNode have to be done :
162           int k ;
163           for ( k = 0 ; k < GetNodeOutPortsSize() ; k++ ) {
164             GraphBase::OutPort * anOutPort = GetChangeNodeOutPort( k ) ;
165             if ( !anOutPort->IsGate() ) {
166               GraphBase::InPort * anInPort ;
167               anInPort = anEndSwitchNode->GetChangeInPort( anOutPort->PortName() ) ;
168               if ( anInPort && !anEndSwitchNode->DecrEndSwitchInPortLinked( anInPort ) ) {
169                 cdebug_out << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
170                            << anEndSwitchNode->Name() << " for port " << anInPort->PortName()
171                            << " WARNING false" << endl;
172                 return false ;
173               }
174               else {
175                 cdebug_out << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
176                            << anEndSwitchNode->Name() << " OutPort " << anOutPort->PortName()
177                            << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
178                            << " not in EndSwitchNode : IGNORED"
179                            << endl;
180               }
181             }
182             else {
183               cdebug_out << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
184                          << anEndSwitchNode->Name() << " OutPort " << anOutPort->PortName()
185                          << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
186                          << " SwitchPort or Gate : IGNORED"
187                          << endl;
188             }
189           }
190 // Check that all InPorts of the EndSwitchNode have a value :
191           if ( !anEndSwitchNode->CheckEndSwitchInPortsLinked() ) {
192             cdebug_out << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
193                        << anEndSwitchNode->Name() << " " << aNode->Name()
194                        << " WARNING false" << endl;
195             return false ;
196           }
197         }
198       }
199
200 //2. SWITCH_OUTPORT
201       else {
202 // We have a SwitchPort which is connected to Gates
203 // We initialize the _NodeDoneInBranchOfSwitch field to false for each node of the
204 // InPortsSize() branch(es)
205         int j ;
206         for ( j = 0 ; j < anOutPort->InPortsSize() ; j++ ) {
207           GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( j ) ;
208           GraphBase::ComputingNode * aNode ;
209           aNode = GraphOfNode()->GetChangeGraphNode( anInPort->NodeName() ) ;
210           if ( aNode && aNode != anEndSwitchNode ) {
211             if ( !aNode->InitBranchOfSwitchDone( false , anEndSwitchNode ) ) {
212               cdebug << Name() << "->ComputingNode::InitBranchOfSwitchDone WARNING false"
213                      << " Node common to two or more branchs of switch" << endl ;
214               return false ;
215             }
216           }
217         }
218
219         anEndSwitchNode->InitEndSwitchInPortLinked() ;
220
221 // At first all of not SwitchPort should have to be done also :
222 // Not Switch Branches (Gate not connected to a switch port of a SwitchNode) :
223 // They are always executed except if we execute the DefaultBranch ...
224         cdebug << "1. " << Name() << "->SwitchNode::CheckSwitch at first NOT_SWITCH_BRANCH_OUTPORT FOR "
225                << anOutPort->PortName()
226                << " " << anOutPort->PortStatus() << " " << anOutPort->Kind() << endl ;
227         for ( j = 0 ; j < GetNodeOutPortsSize() ; j++ ) {
228           GraphBase::OutPort * anOutPort = GetChangeNodeOutPort( j ) ;
229           if ( !anOutPort->IsSwitch() && !anOutPort->IsGate() ) {
230             int k ;
231             for ( k = 0 ; k < anOutPort->InPortsSize() ; k++ ) {
232               GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( k ) ;
233               GraphBase::ComputingNode * aNode ;
234               aNode = GraphOfNode()->GetChangeGraphNode( anInPort->NodeName() ) ;
235               if ( aNode ) {
236                 const GraphBase::InPort * anInGatePort = aNode->GetNodeInGate() ;
237                 cdebug << Name() << "->SwitchNode::CheckSwitch InPort" << k << ". "
238                        << anInPort->PortName() << " of " << aNode->Name() << " :" << endl ;
239 // Direct Connexion to the EndSwitchNode : always executed (except for DefaultBranch)
240                 if ( aNode == anEndSwitchNode ) {
241                   if ( !anEndSwitchNode->DecrEndSwitchInPortLinked( anInPort ) ) {
242                     cdebug_out << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
243                                << anEndSwitchNode->Name() << " for port " << anInPort->PortName()
244                                << " WARNING false" << endl;
245                     return false ;
246                   }
247                   cdebug << Name() << "->SwitchNode::CheckSwitch Check of '"
248                          << anOutPort->PortName() << "' " << anOutPort->Kind()
249                          << " NOT switch port Branch to EndSwitchNode "
250                          << aNode->Name() << " is done" << endl ;
251                 }
252 // Check that InGate is not linked from a SwitchPort or a GatePort of the SwitchNode :
253                 else if ( !anInGatePort->GetOutPort() ) {
254                   cdebug << Name() << "->SwitchNode::CheckSwitch Check of '"
255                          << anOutPort->PortName() << "' " << anOutPort->Kind()
256                          << " NOT switch port Branch to node "
257                          << aNode->Name() << " will be done" << endl ;
258                   if ( !aNode->CheckSwitch( anEndSwitchNode ) ) {
259                     cdebug_out << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
260                                << anEndSwitchNode->Name() << " " << aNode->Name()
261                                << " WARNING false" << endl;
262                     return false ;
263                   }
264                   cdebug << Name() << "->SwitchNode::CheckSwitch Check of '"
265                          << anOutPort->PortName() << "' " << anOutPort->Kind()
266                          << " NOT switch port Branch to node "
267                          << aNode->Name() << " is done" << endl ;
268                 }
269                 else {
270                   cdebug << Name() << "->SwitchNode::CheckSwitch Check of '"
271                          << anOutPort->PortName() << "' " << anOutPort->Kind()
272                          << " NOT switch port Branch to node "
273                          << aNode->Name() << " has InGate connected IGNORED for that branch" << endl ;
274                 }
275               }
276             }
277           }
278         }
279
280         cdebug << "2. "<< Name() << "->SwitchNode::CheckSwitch and now SWITCH_BRANCH_OUTPORT "
281                << anOutPort->PortName()
282                << " " << anOutPort->PortStatus() << " " << anOutPort->Kind() << endl ;
283 // And all links from the switchport anOutPort (connected to Gates) will be checked
284         for ( j = 0 ; j < anOutPort->InPortsSize() ; j++ ) {
285           GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( j ) ;
286           GraphBase::ComputingNode * aNode ;
287           aNode = GraphOfNode()->GetChangeGraphNode( anInPort->NodeName() ) ;
288           if ( aNode == NULL ) {
289             cdebug << Name() << "->SwitchNode::CheckSwitch Check of " << anOutPort->PortName()
290                    << " switch port branch "
291                    << aNode->Name() << " ignored" << endl ;
292           }
293
294
295           else {
296 // That branch does not go directly to the EndSwitchNode
297 // Control the OutPorts Values of the SwitchNode through the branch
298             cdebug << Name() << " Check of " << anOutPort->PortName()
299                    << " switch port Branch to node "
300                    << aNode->Name() << endl ;
301             if ( !aNode->CheckSwitch( anEndSwitchNode ) ) {
302               cdebug_out << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
303                          << anEndSwitchNode->Name() << " " << aNode->Name() << " WARNING false"
304                          << endl;
305               return false ;
306             }
307           }
308         }
309 // Check that all InPorts of the EndSwitchNode have a value :
310         if ( !anEndSwitchNode->CheckEndSwitchInPortsLinked() ) {
311           cdebug_out << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
312                      << anEndSwitchNode->Name() << " CheckEndSwitchInPortsLinked WARNING false"
313                      << endl;
314           return false ;
315         }
316         else {
317           cdebug << Name() << "->SwitchNode::CheckSwitch OutPort " << anOutPort->PortName()
318                  << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
319                  << " SWITCHBRANCH IS OK" << endl << endl ;
320         }
321       }
322     }
323     else {
324       cdebug << Name() << "->SwitchNode::CheckSwitch OutPort " << anOutPort->PortName()
325              << " " << anOutPort->PortStatus() << " " << anOutPort->Kind() << " NOTSWITCHBRANCH"
326              << " IGNORED" << endl ;
327     }
328   }
329   cdebug_out << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
330              << anEndSwitchNode->Name() << " true" << endl;
331   return true ;
332 }
333