Salome HOME
1e60c36f9ec65cd5d86313e4bcc95e382274792f
[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  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.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  File   : DataFlowBase_SwitchNode.cxx
23 //  Author : Jean Rahuel, CEA
24 //  Module : SUPERV
25
26 using namespace std;
27 //#include <sstream>
28 //#include <iostream>
29
30 #include "DataFlowBase_SwitchNode.hxx"
31 #include "DataFlowBase_EndOfSwitchNode.hxx"
32 #include "DataFlowBase_Graph.hxx"
33
34 GraphBase::SwitchNode::SwitchNode() :
35   GraphBase::GOTONode::GOTONode() {
36
37   cdebug << "GraphBase::SwitchNode::SwitchNode "  << this 
38          << " _Name " << (void *) Name() << " " << Name() << " _Comment "
39          << (void *) Comment() << " "  << Comment() << " "  << endl ;
40
41 }
42
43 GraphBase::SwitchNode::SwitchNode( CORBA::ORB_ptr ORB ,
44                                    SALOME_NamingService* ptrNamingService ,
45                                    const char * FuncName ,
46                                    const SUPERV::ListOfStrings & aPythonFunction ,
47                                    const char *NodeName ,
48                                    const SUPERV::KindOfNode akind ,
49                                    const SUPERV::SDate NodeFirstCreation ,
50                                    const SUPERV::SDate NodeLastModification  ,
51                                    const char * NodeEditorRelease ,
52                                    const char * NodeAuthor ,
53                                    const char * NodeComment ,
54                                    const bool   GeneratedName ,
55                                    const long   X ,
56                                    const long   Y ,
57                                    int * Graph_prof_debug ,
58                                    ofstream * Graph_fdebug ) :
59   GraphBase::GOTONode::GOTONode( ORB , ptrNamingService , FuncName , aPythonFunction ,
60                                  NodeName , akind , NodeFirstCreation ,
61                                  NodeLastModification  , NodeEditorRelease ,
62                                  NodeAuthor , NodeComment , GeneratedName ,
63                                  X , Y , Graph_prof_debug , Graph_fdebug ) {
64
65   cdebug_in << "GraphBase::SwitchNode::SwitchNode "  << this 
66             << "' _Name " << (void *) Name() << " '" << Name() << " _Comment "
67             << (void *) Comment() << " "  << Comment() << " " 
68             << " KindOfNode " << Kind() << " FuncName " << FuncName
69             << " ServiceName " << ServiceName() << " In("
70             << ServiceInParameter().length()
71             << ") Out(" << ServiceOutParameter().length() << ")" << endl ;
72
73   cdebug_out << "GraphBase::SwitchNode::SwitchNode" << endl;
74 }
75
76 GraphBase::SwitchNode::~SwitchNode() {
77   cdebug << "GraphBase::SwitchNode::~SwitchNode "  << this 
78          << " _Name " << (void *) Name() << " " << Name() << " _Comment "
79          << (void *) Comment() << " "  << Comment() << " "  << endl ;
80 //  if ( _ComponentName != NULLSTRING )
81 //    delete [] _ComponentName ;
82 //  delete [] _Name ;
83 //  delete [] _EditorRelease ;
84 //  if ( _Author != NULLSTRING )
85 //    delete [] _Author ;
86 //  if ( _Computer != FACTORYSERVER )
87 //    delete [] _Computer;
88 //  if ( _Comment != NULLSTRING )
89 //    delete [] _Comment;
90 }
91
92 bool GraphBase::SwitchNode::CheckSwitch() const {
93   GraphBase::EndOfSwitchNode * anEndSwitchNode ;
94   anEndSwitchNode = (GraphBase::EndOfSwitchNode * ) CoupledNode() ;
95   cdebug_in << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
96             << anEndSwitchNode->Name() << endl;
97   int i ;
98
99   string anErrorMessage = string( "SwitchCheck of " ) + string( Name() ) + " --> " +
100                           string( anEndSwitchNode->Name() ) + string( " :\n" ) ;
101   bool RetVal = true ;
102
103 //All nodes between Switch and EndSwitch will have _BranchOfSwitchDone to false
104 //When we have to execute such a node in a switchbranch, if _BranchOfSwitchDone is true we have
105 // an error ; else we set _BranchOfSwitchDone to true
106   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
107     GraphBase::OutPort * anOutPort = GetChangeNodeOutPort( i ) ;
108     if ( anOutPort->IsSwitch() || anOutPort->IsGate() ) {
109       int j ;
110       for ( j = 0 ; j < anOutPort->InPortsSize() ; j++ ) {
111         GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( j ) ;
112         GraphBase::ComputingNode * aNode ;
113         aNode = GraphOfNode()->GetChangeGraphNode( anInPort->NodeName() ) ;
114         if ( aNode && aNode != anEndSwitchNode ) {
115           aNode->InitBranchOfSwitchDone( true , anEndSwitchNode , anErrorMessage ) ;
116         }
117       }
118     }
119   }
120
121   bool DefaultConnected = false ;
122 //OutPorts of the SwitchNode
123   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
124     GraphBase::OutPort * anOutPort = GetChangeNodeOutPort( i ) ;
125     if ( anOutPort->IsSwitch() || anOutPort->IsGate() ) {
126 // We have a branch of the switch
127       anErrorMessage = anErrorMessage + string( "Branch " ) + string( Name() ) + string( "( " ) +
128                        string( anOutPort->PortName() ) + string( " ) :\n" ) ;
129       cdebug << endl << Name() << "->SwitchNode::CheckSwitch OutPort " << anOutPort->PortName()
130              << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
131              << " SWITCHBRANCH" << endl
132              << "===================================================================================="
133              << endl ;
134
135 //JR 11.02.2005 : if Default is not connected and if Default is true at execution time, the SwitchNode
136 // execution will be aborted
137 //Behavior : in that case, that means that a SwitchBranch should be a DefaultBranch and it is not the case !
138 //1. DEFAULT_OUTPORT
139 //JR 07.04.2005 Debug : an OutPort of the SwitchNode may be linked to the DefaultPort of
140 //                      the EndSwitchNode <==>
141 //                      SwitchNode( Default ) --> EndSwitchNode( Default )
142       bool EndSwitchNode_Default = false ;
143       if ( anOutPort->InPortsSize() ) {
144         GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( 0 ) ;
145         GraphBase::ComputingNode * aNode ;
146         aNode = GraphOfNode()->GetChangeGraphNode( anInPort->NodeName() ) ;
147         if ( aNode == anEndSwitchNode ) {
148           EndSwitchNode_Default = true ;
149         }
150       }
151 //JR 07.04.2005      if ( anOutPort->IsGate() ) {
152       if ( anOutPort->IsGate() || EndSwitchNode_Default ) {
153         if ( anOutPort->InPortsSize() == 0 ) {
154 // DefaultPort of the SwitchNode is not connected
155           cdebug << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
156                  << anEndSwitchNode->Name() << " OutPort " << anOutPort->PortName() << " "
157                  << anOutPort->InPortsSize() << " InPortsSize EndSwitch(Default) "
158                  << anEndSwitchNode->GetNodeInGate()->PortStatus() << "WARNING" << endl;
159         }
160         else {
161 // But the DefaultPort of the EndSwitchNode is connected : so there is a branch going to
162 // that DefaultPort
163           cdebug << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
164                  << anEndSwitchNode->Name() << " OutPort " << anOutPort->PortName() << " "
165                  << " " << anOutPort->PortStatus() << " " << anOutPort->InPortsSize() << " InPortsSize "
166                      << endl ;
167           DefaultConnected = true ;
168
169           anEndSwitchNode->InitEndSwitchInPortLinked() ;
170
171 // That DefaultBranch have to go directly to the EndSwitchNode
172           GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( 0 ) ;
173           GraphBase::ComputingNode * aNode ;
174           aNode = GraphOfNode()->GetChangeGraphNode( anInPort->NodeName() ) ;
175           if ( aNode != anEndSwitchNode ) {
176             anErrorMessage = anErrorMessage + string( Name() ) + "( " +
177                              string( anOutPort->PortName() ) +
178                              string( " ) should not be linked to " ) +
179                              string( aNode->Name() ) + string( "( " ) +
180                              string( anInPort->PortName() ) + string ( " )\n" ) ;
181             cdebug << "1. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
182                    << anEndSwitchNode->Name() << " for OutPort " << anOutPort->PortName()
183                    << " linked to " << aNode->Name() << " ERROR false" << endl;
184             RetVal = false ;
185           }
186           cdebug << endl << Name() << " Check of " << anOutPort->PortName() << " switch port branch"
187                  << " to EndSwitchNode" << endl ;
188 // All of InPorts of the EndSwitchNode have to be done :
189           int k ;
190           for ( k = 0 ; k < GetNodeOutPortsSize() ; k++ ) {
191             GraphBase::OutPort * anOutPort = GetChangeNodeOutPort( k ) ;
192 //JR 06.07.2005 : the InGatePort must also be counted now (enhancement) ...
193 //                But it is done in EndSwitchNode::CheckEndSwitchInPortsLinked
194             if ( !anOutPort->IsGate() ) {
195               GraphBase::InPort * anInPort = NULL ;
196 //JR 22.06.2005 : Enhancement of the behaviour :
197 //                For the DefaultBranch, if we have same PortsNames, Values are automatically
198 //                    transmitted
199 //                But for the DefaultBranch, if we have NOT same PortsNames, we may create links.
200 //                Look at GraphSyrControlAve* ...
201               int kk ;
202 //JR 22.06.2005 : At first look at OutPorts linked to InPorts of the EndSwitchNode with
203 //                different PortsNames :
204               for ( kk = 0 ; kk < anOutPort->InPortsSize() ; kk++ ) {
205                 anInPort = anOutPort->ChangeInPorts( kk ) ;
206                 if ( GraphOfNode()->GetGraphNode( anInPort->NodeName() ) == anEndSwitchNode ) {
207                   if ( !anEndSwitchNode->GetChangeInPort( anOutPort->PortName() ) ) {
208                     if ( anInPort && !anEndSwitchNode->DecrEndSwitchInPortLinked( anInPort ,
209                                                                                   anErrorMessage ) ) {
210                       cdebug << "2. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode : "
211                              << anEndSwitchNode->Name() << " to port " << anInPort->PortName()
212                              << " from port " << Name() << "( " << anOutPort->PortName()
213                              << " ) ERROR false" << endl;
214                       RetVal = false ;
215                     }
216                   }
217                 }
218               }
219 //Get an InPort of the EndSwitchNode with the same name as that OutPort of the SwitchNode
220               anInPort = anEndSwitchNode->GetChangeInPort( anOutPort->PortName() ) ;
221               if ( anInPort && !anEndSwitchNode->DecrEndSwitchInPortLinked( anInPort ,
222                                                                             anErrorMessage ) ) {
223                 cdebug << "3. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
224                        << anEndSwitchNode->Name() << " for port " << anInPort->PortName()
225                        << " ERROR false" << endl;
226                 RetVal = false ;
227               }
228               else {
229                 cdebug << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
230                        << anEndSwitchNode->Name() << " OutPort " << anOutPort->PortName()
231                        << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
232                        << " not in EndSwitchNode : IGNORED"
233                        << endl;
234               }
235 //JR 06.07.2005 : the InGatePort must also be counted now (enhancement) ...
236 //                But it is done in EndSwitchNode::CheckEndSwitchInPortsLinked
237             }
238             else {
239               cdebug << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
240                      << anEndSwitchNode->Name() << " OutPort " << anOutPort->PortName()
241                      << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
242                      << " SwitchPort or Gate : IGNORED"
243                      << endl;
244             }
245           }
246 // Check that all InPorts of the EndSwitchNode have a value :
247           if ( !anEndSwitchNode->CheckEndSwitchInPortsLinked( anErrorMessage ) ) {
248             cdebug << "4. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
249                    << anEndSwitchNode->Name() << " " << aNode->Name()
250                    << " ERROR false" << endl;
251             RetVal = false ;
252           }
253         }
254       }
255
256 //2. SWITCH_OUTPORT
257       else {
258 // We have a SwitchPort which is connected to Gates
259 // We initialize the _NodeDoneInBranchOfSwitch field to false for each node of the
260 // InPortsSize() branch(es)
261         int j ;
262         for ( j = 0 ; j < anOutPort->InPortsSize() ; j++ ) {
263           GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( j ) ;
264           GraphBase::ComputingNode * aNode ;
265           aNode = GraphOfNode()->GetChangeGraphNode( anInPort->NodeName() ) ;
266           if ( aNode && aNode != anEndSwitchNode ) {
267             if ( !aNode->InitBranchOfSwitchDone( false , anEndSwitchNode , anErrorMessage ) ) {
268               anErrorMessage = anErrorMessage + string( Name() ) +
269                                string( " Node(s) are common to two or more branchs of switch.\n" ) ;
270               cdebug << "5. " << Name() << "->ComputingNode::InitBranchOfSwitchDone ERROR false"
271                      << " Node common to two or more branchs of switch" << endl ;
272               RetVal = false ;
273             }
274           }
275         }
276
277         anEndSwitchNode->InitEndSwitchInPortLinked() ;
278
279 // At first all of not SwitchPort should have to be done also :
280 // Not Switch Branches (Gate not connected to a switch port of a SwitchNode) :
281 // They are always executed except if we execute the DefaultBranch ...
282         
283         cdebug << "1. " << Name() << "->SwitchNode::CheckSwitch at first NOTSWITCHBRANCH_OUTPORT FOR "
284                << anOutPort->PortName() << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
285                << " :" << endl ;
286         for ( j = 0 ; j < GetNodeOutPortsSize() ; j++ ) {
287           GraphBase::OutPort * anOutPort = GetChangeNodeOutPort( j ) ;
288           cdebug << Name() << "->SwitchNode::CheckSwitch for OutPort" << j << " "
289                  << anOutPort->PortName() << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
290                  << " InPortsSize " << anOutPort->InPortsSize() << endl ;
291           if ( !anOutPort->IsSwitch() && !anOutPort->IsGate() ) {
292 //JR 23.06.2005 : implicit connection with same PortsNames was missing in SwitchNodeBranches :
293             if ( anOutPort->IsExternConnected() ) {
294               GraphBase::InPort * anInPort ;
295               anInPort = anEndSwitchNode->GetChangeInPort( anOutPort->PortName() ) ;
296               if ( anInPort ) {
297                 anErrorMessage = anErrorMessage + string( "Implicit NotSwitchBranch " ) +
298                                  string( Name() ) + string( "( " ) + string( anOutPort->PortName() ) +
299                                  string( " ) --> " ) + string( anEndSwitchNode->Name() ) +
300                                  string( "( " ) + string( anInPort->PortName() ) + string( " ).\n" ) ;
301                 if ( !anEndSwitchNode->DecrEndSwitchInPortLinked( anInPort ,
302                                                                   anErrorMessage ) ) {
303                   cdebug << "6. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
304                          << anEndSwitchNode->Name() << " for port " << anInPort->PortName()
305                          << " ERROR false" << endl;
306                   RetVal = false ;
307                 }
308                 cdebug << Name() << "->SwitchNode::CheckSwitch Check of '"
309                        << anOutPort->PortName() << "' " << anOutPort->Kind()
310                        << " NOT switch port Branch to EndSwitchNode "
311                        << anEndSwitchNode->Name() << " is done" << endl ;
312               }
313               else {
314                 cdebug << Name() << "->SwitchNode::CheckSwitch Check of '"
315                        << anOutPort->PortName() << "' " << anOutPort->Kind()
316                        << " NOT switch port does not exist in EndSwitchNode. Ignoed " << endl ;
317               }
318             }
319             else {
320               int k ;
321               for ( k = 0 ; k < anOutPort->InPortsSize() ; k++ ) {
322                 GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( k ) ;
323                 GraphBase::ComputingNode * aNode ;
324                 aNode = GraphOfNode()->GetChangeGraphNode( anInPort->NodeName() ) ;
325                 if ( aNode ) {
326                   const GraphBase::InPort * anInGatePort = aNode->GetNodeInGate() ;
327                   cdebug << Name() << "->SwitchNode::CheckSwitch InPort" << k << ". "
328                          << anInPort->PortName() << " of " << aNode->Name() << " :" << endl ;
329 // Direct Connexion to the EndSwitchNode : always executed (except for DefaultBranch)
330                   if ( aNode == anEndSwitchNode ) {
331                     anErrorMessage = anErrorMessage + string( "NotSwitchBranch " ) + string( Name() ) +
332                                      string( "( " ) + string( anOutPort->PortName() ) +
333                                      string( " ) --> " ) + string( aNode->Name() ) +
334                                      string( "( " ) + string( anInPort->PortName() ) +
335                                      string( " ).\n" ) ;
336                     if ( !anEndSwitchNode->DecrEndSwitchInPortLinked( anInPort ,
337                                                                       anErrorMessage ) ) {
338                       cdebug << "7. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
339                              << anEndSwitchNode->Name() << " for port " << anInPort->PortName()
340                              << " ERROR false" << endl;
341                       RetVal = false ;
342                     }
343                     cdebug << Name() << "->SwitchNode::CheckSwitch Check of '"
344                            << anOutPort->PortName() << "' " << anOutPort->Kind()
345                            << " NOT switch port Branch to EndSwitchNode "
346                            << aNode->Name() << " is done" << endl ;
347                   }
348 // Check that InGate is not linked from a SwitchPort or a GatePort of the SwitchNode :
349                   else if ( !anInGatePort->GetOutPort() ) {
350                     cdebug << Name() << "->SwitchNode::CheckSwitch Check of '"
351                            << anOutPort->PortName() << "' " << anOutPort->Kind()
352                            << " NOT switch port Branch to node "
353                            << aNode->Name() << " will be done" << endl ;
354                     anErrorMessage = anErrorMessage + string( "NotSwitchBranch " ) + string( Name() ) +
355                                      string( "( " ) + string( anOutPort->PortName() ) +
356                                      string( " ) --> " ) + string( aNode->Name() ) +
357                                      string( "( " ) + string( anInPort->PortName() ) +
358                                      string( " ).\n" ) ;
359                     if ( !aNode->CheckSwitch( anEndSwitchNode , anErrorMessage ) ) {
360                       cdebug << "8. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
361                              << anEndSwitchNode->Name() << " " << aNode->Name()
362                              << " ERROR false" << endl;
363                       RetVal = false ;
364                     }
365                     cdebug << Name() << "->SwitchNode::CheckSwitch Check of '"
366                            << anOutPort->PortName() << "' " << anOutPort->Kind()
367                            << " NOT switch port Branch to node "
368                            << aNode->Name() << " is done" << endl ;
369                   }
370                   else {
371                     cdebug << Name() << "->SwitchNode::CheckSwitch Check of '"
372                            << anOutPort->PortName() << "' " << anOutPort->Kind()
373                            << " NOT switch port Branch to node "
374                            << aNode->Name() << " has InGate connected IGNORED for that branch"
375                            << endl ;
376                   }
377                 }
378               }
379             }
380           }
381         }
382
383         cdebug << "2. "<< Name() << "->SwitchNode::CheckSwitch and now SWITCH_BRANCH_OUTPORT "
384                << anOutPort->PortName()
385                << " " << anOutPort->PortStatus() << " " << anOutPort->Kind() << endl ;
386 // And all links from the switchport anOutPort (connected to Gates) will be checked
387         for ( j = 0 ; j < anOutPort->InPortsSize() ; j++ ) {
388           GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( j ) ;
389           GraphBase::ComputingNode * aNode ;
390           aNode = GraphOfNode()->GetChangeGraphNode( anInPort->NodeName() ) ;
391           if ( aNode == NULL ) {
392             cdebug << Name() << "->SwitchNode::CheckSwitch Check of " << anOutPort->PortName()
393                    << " switch port branch "
394                    << aNode->Name() << " ignored" << endl ;
395           }
396
397
398           else {
399 // That branch does not go directly to the EndSwitchNode
400 // Control the OutPorts Values of the SwitchNode through the branch
401             cdebug << Name() << " Check of " << anOutPort->PortName()
402                    << " switch port Branch to node "
403                    << aNode->Name() << endl ;
404             if ( !aNode->CheckSwitch( anEndSwitchNode , anErrorMessage ) ) {
405               cdebug << "9. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
406                      << anEndSwitchNode->Name() << " " << aNode->Name() << " ERROR false"
407                      << endl;
408               RetVal = false ;
409             }
410           }
411         }
412 // Check that all InPorts of the EndSwitchNode have a value :
413         if ( !anEndSwitchNode->CheckEndSwitchInPortsLinked( anErrorMessage ) ) {
414           cdebug << "10. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
415                  << anEndSwitchNode->Name() << " CheckEndSwitchInPortsLinked ERROR false"
416                  << endl;
417           RetVal = false ;
418         }
419         else {
420           cdebug << Name() << "->SwitchNode::CheckSwitch OutPort " << anOutPort->PortName()
421                  << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
422                  << " SWITCHBRANCH IS OK" << endl << endl ;
423         }
424       }
425     }
426     else {
427       cdebug << Name() << "->SwitchNode::CheckSwitch OutPort " << anOutPort->PortName()
428              << " " << anOutPort->PortStatus() << " " << anOutPort->Kind() << " NOTSWITCHBRANCH"
429              << " IGNORED" << endl ;
430     }
431   }
432
433   if ( !RetVal ) {
434     GraphOfNode()->SetMessages( anErrorMessage ) ;
435   }
436
437   cdebug_out << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
438              << anEndSwitchNode->Name() << " RetVal " << RetVal << endl;
439   return RetVal ;
440 }
441