]> SALOME platform Git repositories - modules/yacs.git/blob - src/evalyfx/YACSEvalPort.cxx
Salome HOME
190fa1ef2d636850dc50072ca72ee2707e9a483f
[modules/yacs.git] / src / evalyfx / YACSEvalPort.cxx
1 // Copyright (C) 2012-2015  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 // Author : Anthony Geay (EDF R&D)
20
21 #include "YACSEvalPort.hxx"
22 #include "YACSEvalSeqAny.hxx"
23 #include "OutputPort.hxx"
24 #include "InputPort.hxx"
25 #include "TypeCode.hxx"
26
27 #include "CORBAPorts.hxx"
28 #include "PythonPorts.hxx"
29 #include "AnyInputPort.hxx"
30
31 #include <limits>
32 #include <sstream>
33 #include <typeinfo>
34
35 const char YACSEvalAnyDouble::TYPE_REPR[]="double";
36
37 const char YACSEvalAnyInt::TYPE_REPR[]="int";
38
39 int YACSEvalAnyDouble::toInt() const
40 {
41   throw YACS::Exception("YACSEvalAnyDouble::toInt : invalid type requested !");
42 }
43
44 double YACSEvalAnyDouble::toDouble() const
45 {
46   return _v;
47 }
48
49 YACSEvalAnyDouble *YACSEvalAnyDouble::deepCpy() const
50 {
51   return new YACSEvalAnyDouble(*this);
52 }
53
54 int YACSEvalAnyInt::toInt() const
55 {
56   return _v;
57 }
58
59 double YACSEvalAnyInt::toDouble() const
60 {
61   throw YACS::Exception("YACSEvalAnyInt::toDouble : invalid type requested !");
62 }
63
64 YACSEvalAnyInt *YACSEvalAnyInt::deepCpy() const
65 {
66   return new YACSEvalAnyInt(*this);
67 }
68
69 bool YACSEvalPort::IsInputPortPublishable(const YACS::ENGINE::InputPort *port)
70 {
71   YACS::ENGINE::TypeCode *tc(port->edGetType());
72   if(!tc)
73     throw YACS::Exception("YACSEvalPort::IsInPortPublishable : null type code !");
74   if(tc->kind()==YACS::ENGINE::Double || tc->kind()==YACS::ENGINE::Int)
75     return true;
76   if(tc->kind()==YACS::ENGINE::String)
77     {
78       if(port->edIsManuallyInitialized())
79         return false;
80     }
81   return true;
82 }
83
84 bool YACSEvalPort::IsOutputPortPublishable(const YACS::ENGINE::OutputPort *port)
85 {
86   YACS::ENGINE::TypeCode *tc(port->edGetType());
87   if(!tc)
88     throw YACS::Exception("YACSEvalPort::IsOutputPortPublishable : null type code !");
89   return tc->kind()==YACS::ENGINE::Double || tc->kind()==YACS::ENGINE::Int;
90 }
91
92 std::string YACSEvalPort::GetTypeOfData(const YACS::ENGINE::DataPort *port)
93 {
94   YACS::ENGINE::TypeCode *tc(port->edGetType());
95   if(!tc)
96     throw YACS::Exception("YACSEvalPort::GetTypeOfData : null type code !");
97   if(tc->kind()==YACS::ENGINE::Double)
98     return std::string(YACSEvalAnyDouble::TYPE_REPR);
99   if(tc->kind()==YACS::ENGINE::Int)
100     return std::string(YACSEvalAnyInt::TYPE_REPR);
101   throw YACS::Exception("YACSEvalPort::GetTypeOfData : Unrecognized type of data ! Must be int or double for the moment !");
102 }
103
104 YACSEvalInputPort::YACSEvalInputPort(YACS::ENGINE::InputPort *ptr):_ptr(ptr),_mySeq(0),_isRandom(false),_isLocked(false),_undergroundPort(0)
105 {
106   GetTypeOfData(_ptr);
107 }
108
109 std::string YACSEvalInputPort::getName() const
110 {
111   return _ptr->getName();
112 }
113
114 std::string YACSEvalInputPort::getTypeOfData() const
115 {
116   return GetTypeOfData(_ptr);
117 }
118
119 bool YACSEvalInputPort::isOKForLock() const
120 {
121   if(_isLocked)
122     return true;
123   return hasDefaultValueDefined();
124 }
125
126 bool YACSEvalInputPort::hasDefaultValueDefined() const
127 {
128   return _ptr->edIsManuallyInitialized();
129 }
130
131 /*!
132  * The caller has the ownership of the returned instance.
133  */
134 YACSEvalAny *YACSEvalInputPort::getDefaultValueDefined() const
135 {
136   if(!hasDefaultValueDefined())
137     throw YACS::Exception("YACSEvalInputPort::getDefaultValueDefined : no default value defined !");
138   _ptr->exRestoreInit();
139   YACS::ENGINE::InputPyPort *i0(dynamic_cast<YACS::ENGINE::InputPyPort *>(_ptr));
140   if(i0)
141     {
142       PyObject *data(i0->getPyObj());
143       if(!data)
144         throw YACS::Exception("YACSEvalInputPort::getDefaultValueDefined : internal error !");
145       if(PyFloat_Check(data))
146         return new YACSEvalAnyDouble(PyFloat_AsDouble(data));
147       if(PyInt_Check(data))
148         return new YACSEvalAnyInt((int)PyInt_AsLong(data));
149       throw YACS::Exception("YACSEvalInputPort::getDefaultValueDefined : unmanaged types different from int and double for py !");
150     }
151   YACS::ENGINE::AnyInputPort *i1(dynamic_cast<YACS::ENGINE::AnyInputPort *>(_ptr));
152   if(i1)
153     {
154       YACS::ENGINE::Any *data(i1->getValue());
155       return convertFromInternalAnyToExternal(data);
156     }
157   YACS::ENGINE::InputCorbaPort *i2(dynamic_cast<YACS::ENGINE::InputCorbaPort *>(_ptr));
158   if(i2)
159     {
160       CORBA::Any *data(i2->getAny());
161       if(!data)
162         throw YACS::Exception("YACSEvalInputPort::getDefaultValueDefined : internal error # 3 !");
163       std::string td(getTypeOfData());
164       if(td==YACSEvalAnyDouble::TYPE_REPR)
165         {
166           CORBA::Double v;
167           if((*data)>>=v)
168             return new YACSEvalAnyDouble(v);
169           else
170             throw YACS::Exception("YACSEvalInputPort::getDefaultValueDefined : internal error # 31 !");
171         }
172       if(td==YACSEvalAnyInt::TYPE_REPR)
173         {
174           CORBA::Long v;
175           if((*data)>>=v)
176             return new YACSEvalAnyInt(v);
177           else
178             throw YACS::Exception("YACSEvalInputPort::getDefaultValueDefined : internal error # 32 !");
179         }
180     }
181   std::ostringstream oss;
182   oss << "YACSEvalInputPort::getDefaultValueDefined : Please contact anthony.geay@edf.fr with -> \"" << typeid(*_ptr).name() << "\" !";
183   throw YACS::Exception(oss.str());
184 }
185
186 /*!
187  * This method does not steal the ownership of \a parameter (a deep copy is performed).
188  */
189 void YACSEvalInputPort::setDefaultValue(const YACSEvalAny *parameter)
190 {
191   checkForNonConstMethod();
192   if(parameter)
193     {
194       if(parameter->getTypeOfData()!=getTypeOfData())
195         {
196           std::ostringstream oss; oss << "YACSEvalInputPort::setParameter : Type of data mismatch ! Expecting \"" << getTypeOfData() << "\" having \"" <<  parameter->getTypeOfData() << "\" !";
197           throw YACS::Exception(oss.str());
198         }
199     }
200   //
201   YACS::ENGINE::InputPyPort *i0(dynamic_cast<YACS::ENGINE::InputPyPort *>(_ptr));
202   YACS::ENGINE::AnyInputPort *i1(dynamic_cast<YACS::ENGINE::AnyInputPort *>(_ptr));
203   YACS::ENGINE::InputCorbaPort *i2(dynamic_cast<YACS::ENGINE::InputCorbaPort *>(_ptr));
204   if(parameter)
205     {
206       const YACSEvalAnyDouble *par0(dynamic_cast<const YACSEvalAnyDouble *>(parameter));
207       const YACSEvalAnyInt *par1(dynamic_cast<const YACSEvalAnyInt *>(parameter));
208       if(i0)
209         {
210           if(par0)
211             {
212               PyObject *obj(PyFloat_FromDouble(par0->toDouble()));
213               i0->put(obj);
214               Py_XDECREF(obj);
215             }
216           else if(par1)
217             {
218               PyObject *obj(PyInt_FromLong(par1->toInt()));
219               i0->put(obj);
220               Py_XDECREF(obj);
221             }
222           else
223             throw YACS::Exception("YACSEvalInputPort::setDefaultValueDefined : unmanaged types different from int and double for py !");
224         }
225       else if(i1)
226         {
227           if(par0)
228             {
229               YACS::ENGINE::AtomAny *v(YACS::ENGINE::AtomAny::New(par0->toDouble()));
230               i1->put(v);
231               v->decrRef();
232             }
233           else if(par1)
234             {
235               YACS::ENGINE::AtomAny *v(YACS::ENGINE::AtomAny::New(par1->toInt()));
236               i1->put(v);
237               v->decrRef();
238             }
239           else
240             throw YACS::Exception("YACSEvalInputPort::setDefaultValueDefined : unmanaged types different from int and double for yacsport !");
241         }
242       else if(i2)
243         {
244           CORBA::Any v;
245           if(par0)
246             v<<=par0->toDouble();
247           else if(par1)
248             v<<=(CORBA::Short)par1->toInt();
249           else
250             throw YACS::Exception("YACSEvalInputPort::setDefaultValueDefined : unmanaged types different from int and double for corbaport !");
251           i2->put(&v);
252         }
253       else
254         {
255           std::ostringstream oss;
256           oss << "YACSEvalInputPort::getDefaultValueDefined : Please contact anthony.geay@edf.fr with -> \"" << typeid(*_ptr).name() << "\" !";
257           throw YACS::Exception(oss.str());
258         }
259       _ptr->exSaveInit();
260     }
261   else
262     _ptr->edRemoveManInit();
263 }
264
265 void YACSEvalInputPort::setSequenceOfValuesToEval(const YACSEvalSeqAny *vals)
266 {
267   if(!_isRandom && _isLocked)
268     throw YACS::Exception("YACSEvalInputPort::setSequenceOfValuesToEval : trying to set a sequence on a var not declared as random !");
269   //checkForNonConstMethod not called here because it is a special non const method !
270   if(!vals)
271     throw YACS::Exception("YACSEvalInputPort::setSequenceOfValuesToEval : input is NULL !");
272   if(vals==_mySeq)
273     return ;
274   if(_mySeq)
275     delete _mySeq;
276   _mySeq=vals->copy();
277   _isRandom=true;
278 }
279
280 bool YACSEvalInputPort::hasSequenceOfValuesToEval() const
281 {
282   return (_mySeq!=0);
283 }
284
285 void YACSEvalInputPort::declareRandomnessStatus(bool isRandom)
286 {
287   checkForNonConstMethod();
288   _isRandom=isRandom;
289   if(!_isRandom)
290     _undergroundPort=0;
291 }
292
293 std::size_t YACSEvalInputPort::initializeUndergroundWithSeq() const
294 {
295   if(!_undergroundPort)
296     throw YACS::Exception("YACSEvalInputPort::initializeUndergroundWithSeq : internal error ! this input has not been locked properly ! Need to be locked !");
297   if(!_mySeq)
298     throw YACS::Exception("YACSEvalInputPort::initializeUndergroundWithSeq : this is not set as a sequence !");
299   _mySeq->initialize(_undergroundPort);
300   return _mySeq->size();
301 }
302
303 YACSEvalInputPort::~YACSEvalInputPort()
304 {
305   delete _mySeq;
306 }
307
308 void YACSEvalInputPort::setUndergroundPortToBeSet(YACS::ENGINE::InputPyPort *p) const
309 {
310   if(!_isRandom)
311     throw YACS::Exception("YACSEvalInputPort::setUndergroundPortToBeSet : trying to set a non random var !");
312   _undergroundPort=p;
313 }
314
315 YACSEvalAny *YACSEvalInputPort::convertFromInternalAnyToExternal(YACS::ENGINE::Any *data) const
316 {
317   if(!data)
318     throw YACS::Exception("YACSEvalInputPort::convertFromInternalAnyToExternal : internal error # 2 !");
319   YACS::ENGINE::AtomAny *data2(dynamic_cast<YACS::ENGINE::AtomAny *>(data));
320   if(!data2)
321     throw YACS::Exception("YACSEvalInputPort::convertFromInternalAnyToExternal : internal error # 21 !");
322   std::string td(getTypeOfData());
323   if(td==YACSEvalAnyDouble::TYPE_REPR)
324     return new YACSEvalAnyDouble(data2->getDoubleValue());
325   if(td==YACSEvalAnyInt::TYPE_REPR)
326     return new YACSEvalAnyInt(data2->getIntValue());
327   throw YACS::Exception("YACSEvalInputPort::convertFromInternalAnyToExternal : unmanaged types different from int and double for any !");
328 }
329
330 void YACSEvalInputPort::checkForNonConstMethod() const
331 {
332   if(_isLocked)
333     throw YACS::Exception("YACSEvalInputPort::checkForNonConstMethod : trying to modify a locked input ! To release it call unlockAll on YACSEvalYFX instance owning this !");
334 }
335
336 YACSEvalOutputPort::YACSEvalOutputPort(YACS::ENGINE::OutputPort *ptr):_ptr(ptr)
337 {
338   GetTypeOfData(_ptr);
339 }
340
341 std::string YACSEvalOutputPort::getName() const
342 {
343   return _ptr->getName();
344 }
345
346 std::string YACSEvalOutputPort::getTypeOfData() const
347 {
348   return GetTypeOfData(_ptr);
349 }