Salome HOME
mergefrom branch BR_V511_PR tag mergeto_trunk_03feb09
[modules/yacs.git] / src / engine / InputPort.cxx
1 //  Copyright (C) 2006-2008  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.
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 #include "InputPort.hxx"
20 #include "OutPort.hxx"
21 #include "ComposedNode.hxx"
22
23 #include <sstream>
24 #include <iostream>
25 #include <cassert>
26
27 //#define _DEVDEBUG_
28 #include "YacsTrace.hxx"
29
30 using namespace YACS::ENGINE;
31 using namespace std;
32
33 const char InputPort::NAME[]="InputPort";
34
35 InputPort::InputPort(const InputPort& other, Node *newHelder):DataFlowPort(other,newHelder),InPort(other,newHelder),
36                                                               DataPort(other,newHelder),Port(other,newHelder),
37                                                               _initValue(0)
38 {
39   if(other._initValue)
40     _initValue=other._initValue->clone();
41 }
42
43 InputPort::InputPort(const std::string& name, Node *node, TypeCode* type)
44   : DataFlowPort(name,node,type), InPort(name,node,type),DataPort(name,node,type),Port(node), _initValue(0)
45 {
46 }
47
48 string InputPort::getNameOfTypeOfCurrentInstance() const
49 {
50   return NAME;
51 }
52
53 void InputPort::exInit(bool start)
54 {
55   checkBasicConsistency();
56   if(start)
57     exRestoreInit();
58 }
59
60 bool InputPort::isEmpty()
61 {
62   return get()==0;
63 }
64
65 //! Specifies if this port has been \b manually set by the call of InputPort::edInit
66 bool InputPort::edIsManuallyInitialized() const
67 {
68   return _initValue!=0;
69 }
70
71 /*!
72  * Perform a quick and not complete check. Use ComposedNode::CheckConsistency instead.
73  */
74 bool InputPort::edIsInitialized() const
75 {
76   return (edIsManuallyInitialized() or _backLinks.size()!=0 );
77 }
78
79 InputPort::~InputPort()
80 {
81   if(_initValue)
82     _initValue->decrRef();
83 }
84
85 void InputPort::edInit(Any *value)
86 {
87   InputPort *manuallySet=getRuntime()->adapt(this,
88                                              Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME,_type,true);
89   try
90     {
91       manuallySet->put((const void *) value);
92       if(manuallySet!=this)
93         delete manuallySet;
94     }
95   catch(ConversionException&)
96     {
97       if(manuallySet!=this)
98         delete manuallySet;
99       throw;
100     }
101   exSaveInit();
102   modified();
103 }
104
105 //! Initialize the port with an object (value) coming from a world with implementation impl
106 /*!
107  *  You should be careful when using this method : the caller must set the context according to implementation
108  *  For instance, if implementation is Python, the caller must hold the Global Interpreter Lock (also known as GIL).
109  */
110 void InputPort::edInit(const std::string& impl,const void* value)
111 {
112   InputPort *manuallySet=getRuntime()->adapt(this,impl,_type,true);
113   try
114     {
115       manuallySet->put(value);
116       if(manuallySet!=this)
117         delete manuallySet;
118     }
119   catch(ConversionException&)
120     {
121       if(manuallySet!=this)
122         delete manuallySet;
123       throw;
124     }
125   exSaveInit();
126   modified();
127 }
128
129 //! Removes eventually previous manual initialisation.
130 void InputPort::edRemoveManInit()
131 {
132   if(_initValue)
133     _initValue->decrRef();
134   _initValue=0;
135 }
136
137 //! Check basically that this port has one chance to be specified on time. It's a necessary condition \b not \b sufficient at all.
138 void InputPort::checkBasicConsistency() const throw(Exception)
139 {
140   if(!edIsManuallyInitialized() and _backLinks.size()==0 )
141     {
142       ostringstream stream;
143       stream << "InputPort::checkBasicConsistency : Port " << _name << " of node with name " << _node->getName() << " neither initialized nor linked back";
144       throw Exception(stream.str());
145     }
146 }
147
148 std::string InputPort::dump()
149 {
150   string xmldump = "<value><error> NO_SERIALISATION_AVAILABLE </error></value>";
151   return xmldump;
152 }
153
154 void InputPort::setStringRef(std::string strRef)
155 {
156   _stringRef = strRef;
157 }
158
159 ProxyPort::ProxyPort(InputPort* p):InputPort("Convertor", p->getNode(), p->edGetType()),DataPort("Convertor", p->getNode(), p->edGetType()),
160                                    Port( p->getNode())
161 {
162   _port = p;
163 }
164
165 ProxyPort::~ProxyPort()
166 {
167   //For the moment, there is no case in YACS we have a proxy port in a proxy port
168   //So don't test that. _port may be already deleted. The test is not sure.
169   /*
170   if(_port->isIntermediate())
171     delete _port;
172     */
173 }
174
175 void ProxyPort::edRemoveAllLinksLinkedWithMe() throw(Exception)
176 {
177   _port->edRemoveAllLinksLinkedWithMe();
178 }
179
180 /*!
181  * \note : Should never been called because Node clone process does not duplicate data attributes relative to links.
182  *         This part is done afterwards on relink process.
183  */
184 InputPort *ProxyPort::clone(Node *newHelder) const
185 {
186   throw Exception("ProxyPort::clone : internal error - should never happened");
187 }
188
189 void ProxyPort::edNotifyReferencedBy(OutPort *fromPort)
190 {
191   _port->edNotifyReferencedBy(fromPort);
192 }
193
194 void ProxyPort::edNotifyDereferencedBy(OutPort *fromPort)
195 {
196   _port->edNotifyDereferencedBy(fromPort);
197 }
198
199 std::set<OutPort *> ProxyPort::edSetOutPort() const
200 {
201   return _port->edSetOutPort();
202 }
203
204 int ProxyPort::edGetNumberOfLinks() const
205 {
206   return _port->edGetNumberOfLinks();
207 }
208
209 void ProxyPort::exRestoreInit()
210 {
211   _port->exRestoreInit();
212 }
213
214 void ProxyPort::exSaveInit()
215 {
216   _port->exSaveInit();
217 }
218
219 #ifdef NOCOVARIANT
220 InPort *ProxyPort::getPublicRepresentant()
221 #else
222 InputPort *ProxyPort::getPublicRepresentant()
223 #endif
224
225   return _port->getPublicRepresentant();
226 }
227
228 void *ProxyPort::get() const
229 {
230   return _port->get();
231 }
232
233 void ProxyPort::put(const void *data) throw(ConversionException)
234 {
235   _port->put(data);
236 }
237
238 void ProxyPort::getAllRepresentants(std::set<InPort *>& repr) const
239 {
240   DEBTRACE("ProxyPort::getAllRepresentants");
241   _port->getAllRepresentants(repr);
242 }