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