1 // SUPERV GraphBase : contains fondamental classes for Services, Input Ports, Output Ports Links and Nodes.
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : DataFlowBase_SwitchNode.cxx
23 // Author : Jean Rahuel, CEA
30 #include "DataFlowBase_SwitchNode.hxx"
31 #include "DataFlowBase_EndOfSwitchNode.hxx"
32 #include "DataFlowBase_Graph.hxx"
34 GraphBase::SwitchNode::SwitchNode() :
35 GraphBase::GOTONode::GOTONode() {
37 cdebug << "GraphBase::SwitchNode::SwitchNode " << this
38 << " _Name " << (void *) Name() << " " << Name() << " _Comment "
39 << (void *) Comment() << " " << Comment() << " " << endl ;
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 ,
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 ) {
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 ;
73 cdebug_out << "GraphBase::SwitchNode::SwitchNode" << endl;
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 ;
83 // delete [] _EditorRelease ;
84 // if ( _Author != NULLSTRING )
85 // delete [] _Author ;
86 // if ( _Computer != FACTORYSERVER )
87 // delete [] _Computer;
88 // if ( _Comment != NULLSTRING )
89 // delete [] _Comment;
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;
99 string anErrorMessage = string( "SwitchCheck of " ) + string( Name() ) + " --> " +
100 string( anEndSwitchNode->Name() ) + string( " :\n" ) ;
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() ) {
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 ) ;
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 << "===================================================================================="
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 !
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 ;
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;
161 // But the DefaultPort of the EndSwitchNode is connected : so there is a branch going to
163 cdebug << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
164 << anEndSwitchNode->Name() << " OutPort " << anOutPort->PortName() << " "
165 << " " << anOutPort->PortStatus() << " " << anOutPort->InPortsSize() << " InPortsSize "
167 DefaultConnected = true ;
169 anEndSwitchNode->InitEndSwitchInPortLinked() ;
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;
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 :
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
199 // But for the DefaultBranch, if we have NOT same PortsNames, we may create links.
200 // Look at GraphSyrControlAve* ...
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 ,
210 cdebug << "2. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode : "
211 << anEndSwitchNode->Name() << " to port " << anInPort->PortName()
212 << " from port " << Name() << "( " << anOutPort->PortName()
213 << " ) ERROR false" << endl;
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 ,
223 cdebug << "3. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
224 << anEndSwitchNode->Name() << " for port " << anInPort->PortName()
225 << " ERROR false" << endl;
229 cdebug << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
230 << anEndSwitchNode->Name() << " OutPort " << anOutPort->PortName()
231 << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
232 << " not in EndSwitchNode : IGNORED"
235 //JR 06.07.2005 : the InGatePort must also be counted now (enhancement) ...
236 // But it is done in EndSwitchNode::CheckEndSwitchInPortsLinked
239 cdebug << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
240 << anEndSwitchNode->Name() << " OutPort " << anOutPort->PortName()
241 << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
242 << " SwitchPort or Gate : IGNORED"
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;
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)
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 ;
277 anEndSwitchNode->InitEndSwitchInPortLinked() ;
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 ...
283 cdebug << "1. " << Name() << "->SwitchNode::CheckSwitch at first NOTSWITCHBRANCH_OUTPORT FOR "
284 << anOutPort->PortName() << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
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() ) ;
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 ,
303 cdebug << "6. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
304 << anEndSwitchNode->Name() << " for port " << anInPort->PortName()
305 << " ERROR false" << endl;
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 ;
314 cdebug << Name() << "->SwitchNode::CheckSwitch Check of '"
315 << anOutPort->PortName() << "' " << anOutPort->Kind()
316 << " NOT switch port does not exist in EndSwitchNode. Ignoed " << endl ;
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() ) ;
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() ) +
336 if ( !anEndSwitchNode->DecrEndSwitchInPortLinked( anInPort ,
338 cdebug << "7. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
339 << anEndSwitchNode->Name() << " for port " << anInPort->PortName()
340 << " ERROR false" << endl;
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 ;
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() ) +
359 if ( !aNode->CheckSwitch( anEndSwitchNode , anErrorMessage ) ) {
360 cdebug << "8. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
361 << anEndSwitchNode->Name() << " " << aNode->Name()
362 << " ERROR false" << endl;
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 ;
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"
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 ;
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"
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"
420 cdebug << Name() << "->SwitchNode::CheckSwitch OutPort " << anOutPort->PortName()
421 << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
422 << " SWITCHBRANCH IS OK" << endl << endl ;
427 cdebug << Name() << "->SwitchNode::CheckSwitch OutPort " << anOutPort->PortName()
428 << " " << anOutPort->PortStatus() << " " << anOutPort->Kind() << " NOTSWITCHBRANCH"
429 << " IGNORED" << endl ;
434 GraphOfNode()->SetMessages( anErrorMessage ) ;
437 cdebug_out << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
438 << anEndSwitchNode->Name() << " RetVal " << RetVal << endl;