Salome HOME
Merge branch 'omu/workloadmanager'
[modules/yacs.git] / src / engine / OutputPort.cxx
1 // Copyright (C) 2006-2020  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "OutputPort.hxx"
21 #include "ComposedNode.hxx"
22 #include "InputPort.hxx"
23 #include "InPropertyPort.hxx"
24 #include "Runtime.hxx"
25 #include "Node.hxx"
26
27 #include <sstream>
28 #include <iostream>
29
30 //#define _DEVDEBUG_
31 #include "YacsTrace.hxx"
32
33 using namespace YACS::ENGINE;
34 using namespace std;
35
36 const char OutputPort::NAME[]="OutputPort";
37
38 OutputPort::OutputPort(const OutputPort& other, Node *newHelder):DataFlowPort(other,newHelder),OutPort(other,newHelder),
39                                                                  DataPort(other,newHelder),Port(other,newHelder)
40 {
41 }
42
43 OutputPort::OutputPort(const std::string& name, Node *node, TypeCode* type):DataFlowPort(name,node,type),OutPort(name,node,type),
44                                                                        DataPort(name,node,type),Port(node)
45 {
46 }
47
48 string OutputPort::getNameOfTypeOfCurrentInstance() const
49 {
50   return NAME;
51 }
52
53 void OutputPort::edRemoveAllLinksLinkedWithMe()
54 {
55   set<InputPort *>::iterator iter;
56   set<InputPort *> vec(_setOfInputPort);
57   for( set<InputPort *>::iterator iter2=vec.begin();iter2!=vec.end();iter2++)
58     edRemoveInputPort(*iter2,true);
59   _setOfInputPort.clear();
60 }
61
62 void OutputPort::exInit()
63 {
64 }
65
66 void OutputPort::put(const void *data)
67 {
68   for(set<InputPort *>::iterator iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++)
69     (*iter)->put(data);
70 }
71
72 /**
73  * check if output type is an input type and if a data converter exists before link
74  */
75 bool OutputPort::edAddInputPort(InputPort *phyPort)
76 {
77   DEBTRACE("OutputPort::edAddInputPort");
78   if(!isAlreadyInSet(phyPort))
79     {
80       InputPort *pwrap = getRuntime()->adapt(phyPort,
81                                              _node->getImplementation(),
82                                              this->edGetType());
83       _setOfInputPort.insert(pwrap);
84       modified();
85       phyPort->modified();
86       return true;
87     }
88   else
89     return false;
90 }
91
92 bool OutputPort::edAddInPropertyPort(InPropertyPort *phyPort)
93 {
94   DEBTRACE("OutputPort::edAddInPropertyPort");
95   if(!isAlreadyInSet(phyPort))
96     {
97       InputPort *pwrap = getRuntime()->adapt(phyPort,
98                                              _node->getImplementation(),
99                                              this->edGetType());
100       _setOfInputPort.insert(pwrap);
101       modified();
102       phyPort->modified();
103       return true;
104     }
105   else
106     return false;
107 }
108
109 /**
110  * Remove a link by performing not only the deletion in _setOfInputPort but also dereference to the target inputPort.
111  * If 'forward' == true the forward deletion 
112  * If 'forward' == false no forward deletion performed, oneway deletion without update 'inputPort' side.
113  */
114 int OutputPort::edRemoveInputPort(InputPort *inputPort, bool forward)
115 {
116   if(forward)
117     {
118       set<InPort *> s;
119       inputPort->getAllRepresentants(s);
120       DEBTRACE("+++");
121       for(set<InPort *>::iterator iter=s.begin();iter!=s.end();iter++)
122         {
123           DEBTRACE("---");
124           _node->getRootNode()->edRemoveLink(this,*iter);
125         }
126       return -1;
127     }
128   else
129     {
130 #ifdef NOCOVARIANT
131       InPort *publicRepr=inputPort->getPublicRepresentant();
132 #else
133       InputPort *publicRepr=inputPort->getPublicRepresentant();
134 #endif
135       set<InputPort *>::iterator iter;
136       for(iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
137         if((*iter)->getPublicRepresentant()==publicRepr)
138           break;
139       if(iter!=_setOfInputPort.end())
140         {
141           (*iter)->modified();
142           if((*iter)->isIntermediate())
143             delete (*iter);
144           _setOfInputPort.erase(iter);
145           modified();
146           return edGetNumberOfOutLinks();
147         }
148       else
149         throw Exception("OutputPort::edRemoveInputPort : link does not exist, unable to remove it");
150     }
151 }
152
153 OutputPort::~OutputPort()
154 {
155   set<InputPort *>::iterator iter;
156   for(iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
157     {
158       delete (*iter);
159     }
160 }
161
162 bool OutputPort::isAlreadyLinkedWith(InPort *with) const
163 {
164   InPort *publicRepr=with->getPublicRepresentant();
165   set<InPort *> s;
166   set<InputPort *>::const_iterator iter;
167   for(iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
168     {
169     if((*iter)->getPublicRepresentant() == publicRepr)
170       return true;
171     }
172   for(iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
173     (*iter)->getAllRepresentants(s);
174   for(set<InPort *>::iterator iter2=s.begin();iter2!=s.end();iter2++)
175     {
176     if((*iter2)->getPublicRepresentant() == publicRepr)
177       return true;
178     }
179   return false;
180 }
181
182 bool OutputPort::isAlreadyInSet(InputPort *inputPort) const
183 {
184 #ifdef NOCOVARIANT
185   InPort *publicRepr=inputPort->getPublicRepresentant();
186 #else
187   InputPort *publicRepr=inputPort->getPublicRepresentant();
188 #endif
189   for(set<InputPort *>::const_iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
190     if((*iter)->getPublicRepresentant()==publicRepr)
191       return true;
192   return false;
193 }
194
195 bool
196 OutputPort::isConnected() const
197 {
198   return !_setOfInputPort.empty();
199 }
200
201
202 /**
203  * check compatibility of port class ( an inputPort ) before trying to create the link.
204  */
205 bool OutputPort::addInPort(InPort *inPort)
206 {
207   DEBTRACE("OutputPort::addInPort");
208   if(inPort->getNameOfTypeOfCurrentInstance()!=InputPort::NAME &&
209      inPort->getNameOfTypeOfCurrentInstance()!=InPropertyPort::NAME)
210     {
211       string what="not compatible type of port requested during building of link FROM ";
212       what+=NAME; what+=" TO "; what+=inPort->getNameOfTypeOfCurrentInstance();
213       throw Exception(what);
214     }
215   if (inPort->getNameOfTypeOfCurrentInstance() == InputPort::NAME)
216   {
217     return edAddInputPort(static_cast<InputPort*>(inPort));
218   }
219   else
220   {
221     return edAddInPropertyPort(static_cast<InPropertyPort*>(inPort));
222   }
223 }
224
225 /**
226  * check compatibility of port class ( an inputPort ) before trying to remove link WITHOUT forward.
227  */
228 int OutputPort::removeInPort(InPort *inPort, bool forward)
229 {
230   if(inPort->getNameOfTypeOfCurrentInstance()!=InputPort::NAME && !forward)
231     {
232       string what="not compatible type of port requested during destruction of for link FROM ";
233       what+=NAME; what+=" TO "; what+=inPort->getNameOfTypeOfCurrentInstance();
234       throw Exception(what);
235     }
236   return edRemoveInputPort(static_cast<InputPort*>(inPort),forward);
237 }
238
239 std::set<InPort *> OutputPort::edSetInPort() const
240 {
241   set<InPort *> s;
242   for(set<InputPort *>::const_iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
243     (*iter)->getAllRepresentants(s);
244   return s;
245 }
246
247 std::string OutputPort::dump()
248 {
249   string xmldump = "<value><error> NO_SERIALISATION_AVAILABLE </error></value>";
250   return xmldump;
251 }
252
253
254 //! Returns physical links linked to this. Contrary to edSetInPort that returns semantic links.
255 const std::set<InputPort *>& OutputPort::getSetOfPhyLinks() const
256 {
257   return _setOfInputPort;
258 }
259
260 //! Check validity of output port. Nothing on base class
261 void OutputPort::checkBasicConsistency() const
262 {
263 }