]> SALOME platform Git repositories - modules/yacs.git/blob - src/engine_swig/engtypemaps.i
Salome HOME
[PYTHON 3] WIP
[modules/yacs.git] / src / engine_swig / engtypemaps.i
1 // Copyright (C) 2006-2016  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 std_except.i
21 %include std_string.i
22 %include std_map.i
23 %include std_list.i
24 %include std_vector.i
25 %include std_set.i
26
27 // ----------------------------------------------------------------------------
28
29 %{
30 #include "yacsconfig.h"
31
32 #ifdef OMNIORB
33 #include <omniORB4/CORBA.h>
34
35 #include <omniORBpy.h>
36 omniORBpyAPI* api=0;
37
38 #define OMNIPY_CATCH_AND_HANDLE_SYSTEM_EXCEPTIONS \
39 catch (const CORBA::SystemException& ex) { \
40   return api->handleCxxSystemException(ex); \
41 }
42 #else
43 #define OMNIPY_CATCH_AND_HANDLE_SYSTEM_EXCEPTIONS 
44 #endif
45
46 #include "Node.hxx"
47 #include "InlineNode.hxx"
48 #include "ComposedNode.hxx"
49 #include "ServiceNode.hxx"
50 #include "ServiceInlineNode.hxx"
51 #include "ServerNode.hxx"
52 #include "Proc.hxx"
53 #include "Bloc.hxx"
54 #include "ForLoop.hxx"
55 #include "WhileLoop.hxx"
56 #include "ForEachLoop.hxx"
57 #include "Switch.hxx"
58 #include "InputPort.hxx"
59 #include "OutputPort.hxx"
60 #include "InPropertyPort.hxx"
61 #include "InputDataStreamPort.hxx"
62 #include "OutputDataStreamPort.hxx"
63 #include "OptimizerLoop.hxx"
64 #include "HomogeneousPoolContainer.hxx"
65
66 #include <sstream>
67
68 class InterpreterUnlocker
69 {
70 public:
71   InterpreterUnlocker() 
72     {
73       _save = PyEval_SaveThread(); // allow Python threads to run
74     }
75   ~InterpreterUnlocker() 
76     {
77       PyEval_RestoreThread(_save); // restore the thread state
78     }
79 private:
80   PyThreadState *_save;
81 };
82
83 static PyObject* convertNode(YACS::ENGINE::Node* node,int owner=0)
84 {
85   if (!node)
86     return SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__Node,owner);
87   PyObject * ob;
88   //should use $descriptor(YACS::ENGINE::Bloc *) and so on but $descriptor is not defined here
89   // It is better to define a helper function to avoid code bloat
90   // First try to find a swig type info by its mangled name
91   std::string swigtypename="_p_"+node->typeName();
92   swig_type_info *ret = SWIG_MangledTypeQuery(swigtypename.c_str());
93   if (ret) 
94     ob=SWIG_NewPointerObj((void*)node,ret,owner);
95   else
96     {
97       //typeName not known by swig. Try dynamic_cast on known classes
98       //You must respect inheritance order in casting : Bloc before ComposedNode and so on
99       if(dynamic_cast<YACS::ENGINE::Proc *>(node))
100         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__Proc,owner);
101       else if(dynamic_cast<YACS::ENGINE::Bloc *>(node))
102         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__Bloc,owner);
103       else if(dynamic_cast<YACS::ENGINE::ForLoop *>(node))
104         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__ForLoop,owner);
105       else if(dynamic_cast<YACS::ENGINE::WhileLoop *>(node))
106         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__WhileLoop,owner);
107       else if(dynamic_cast<YACS::ENGINE::ForEachLoop *>(node))
108         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__ForEachLoop,owner);
109       else if(dynamic_cast<YACS::ENGINE::Switch *>(node))
110         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__Switch,owner);
111       else if(dynamic_cast<YACS::ENGINE::ComposedNode *>(node))
112         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__ComposedNode,owner);
113       else if(dynamic_cast<YACS::ENGINE::InlineFuncNode *>(node))
114         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__InlineFuncNode,owner);
115       else if(dynamic_cast<YACS::ENGINE::InlineNode *>(node))
116         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__InlineNode,owner);
117       else if(dynamic_cast<YACS::ENGINE::ServiceInlineNode *>(node))
118         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__ServiceInlineNode,owner);
119       else if(dynamic_cast<YACS::ENGINE::ServiceNode *>(node))
120         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__ServiceNode,owner);
121       else if(dynamic_cast<YACS::ENGINE::ServerNode *>(node))
122         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__ServerNode,owner);
123       else if(dynamic_cast<YACS::ENGINE::ElementaryNode *>(node))
124         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__ElementaryNode,owner);
125       else
126         ob=SWIG_NewPointerObj((void*)node,SWIGTYPE_p_YACS__ENGINE__Node,owner);
127     }
128   return ob;
129 }
130
131 static PyObject* convertPort(YACS::ENGINE::Port* port,int owner=0)
132 {
133   if(!port)
134     return SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__Port, owner);
135   PyObject * ob;
136   std::string swigtypename="_p_"+port->typeName();
137   swig_type_info *ret = SWIG_MangledTypeQuery(swigtypename.c_str());
138   if (ret)
139     {
140       YACS::ENGINE::InPropertyPort *inpropertyport = dynamic_cast<YACS::ENGINE::InPropertyPort*>(port);
141       if(inpropertyport)
142         return SWIG_NewPointerObj((void*)inpropertyport,ret,owner);
143
144       YACS::ENGINE::InputPort *inport = dynamic_cast<YACS::ENGINE::InputPort *>(port);
145       if(inport)
146         return SWIG_NewPointerObj((void*)inport,ret,owner);
147
148       YACS::ENGINE::OutputPort *outport = dynamic_cast<YACS::ENGINE::OutputPort *>(port);
149       if(outport)
150         return SWIG_NewPointerObj((void*)outport,ret,owner);
151
152       YACS::ENGINE::InputDataStreamPort *indsport = dynamic_cast<YACS::ENGINE::InputDataStreamPort *>(port);
153       if(indsport)
154         return SWIG_NewPointerObj((void*)indsport,ret,owner);
155
156       YACS::ENGINE::OutputDataStreamPort *outdsport = dynamic_cast<YACS::ENGINE::OutputDataStreamPort *>(port);
157       if(outdsport)
158         return SWIG_NewPointerObj((void*)outdsport,ret,owner);
159
160       return SWIG_NewPointerObj((void*)port,ret,owner);
161     }
162   else
163     {
164       if(YACS::ENGINE::AnyInputPort *cport =dynamic_cast<YACS::ENGINE::AnyInputPort *>(port))
165         ob=SWIG_NewPointerObj((void*)cport,SWIGTYPE_p_YACS__ENGINE__AnyInputPort,owner);
166       else if(YACS::ENGINE::AnyOutputPort *cport =dynamic_cast<YACS::ENGINE::AnyOutputPort *>(port))
167         ob=SWIG_NewPointerObj((void*)cport,SWIGTYPE_p_YACS__ENGINE__AnyOutputPort,owner);
168       else if(dynamic_cast<YACS::ENGINE::InPropertyPort*>(port))
169         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__InPropertyPort,owner);
170       else if(dynamic_cast<YACS::ENGINE::InputPort *>(port))
171         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__InputPort,owner);
172       else if(dynamic_cast<YACS::ENGINE::OutputPort *>(port))
173         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__OutputPort,owner);
174       else if(dynamic_cast<YACS::ENGINE::InputDataStreamPort *>(port))
175         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__InputDataStreamPort, owner);
176       else if(dynamic_cast<YACS::ENGINE::OutputDataStreamPort *>(port))
177         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__OutputDataStreamPort, owner);
178       else if(dynamic_cast<YACS::ENGINE::InPort *>(port))
179         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__InPort, owner);
180       else if(dynamic_cast<YACS::ENGINE::OutPort *>(port))
181         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__OutPort, owner);
182       else if(dynamic_cast<YACS::ENGINE::InGate *>(port))
183         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__InGate, owner);
184       else if(dynamic_cast<YACS::ENGINE::OutGate *>(port))
185         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__OutGate, owner);
186       else
187         ob=SWIG_NewPointerObj((void*)port,SWIGTYPE_p_YACS__ENGINE__Port, owner);
188     }
189   return ob;
190 }
191
192 static PyObject *convertContainer(YACS::ENGINE::Container *cont, int owner=0)
193 {
194   if(!cont)
195     return SWIG_NewPointerObj((void*)cont,SWIGTYPE_p_YACS__ENGINE__Container, owner);
196   if(dynamic_cast<YACS::ENGINE::HomogeneousPoolContainer *>(cont))
197     {
198       return SWIG_NewPointerObj((void*)dynamic_cast<YACS::ENGINE::HomogeneousPoolContainer *>(cont),SWIGTYPE_p_YACS__ENGINE__HomogeneousPoolContainer, owner);
199     }
200   return SWIG_NewPointerObj((void*)cont,SWIGTYPE_p_YACS__ENGINE__Container, owner);
201 }
202
203 //convertFromPyObjVectorOfObj<YACS::ENGINE::SequenceAny *>(pyLi,SWIGTYPE_p_YACS__ENGINE__SequenceAny,"SequenceAny")
204 template<class T>
205 static void convertFromPyObjVectorOfObj(PyObject *pyLi, swig_type_info *ty, const char *typeStr, typename std::vector<T>& ret)
206 {
207   void *argp=0;
208   if(PyList_Check(pyLi))
209     {
210       int size=PyList_Size(pyLi);
211       ret.resize(size);
212       for(int i=0;i<size;i++)
213         {
214           PyObject *obj=PyList_GetItem(pyLi,i);
215           int status=SWIG_ConvertPtr(obj,&argp,ty,0|0);
216           if(!SWIG_IsOK(status))
217             {
218               std::ostringstream oss; oss << "convertFromPyObjVectorOfObj : list is excepted to contain only " << typeStr << " instances !";
219               throw YACS::Exception(oss.str());
220             }
221           T arg=reinterpret_cast< T >(argp);
222           ret[i]=arg;
223         }
224     }
225   else if(PyTuple_Check(pyLi))
226     {
227       int size=PyTuple_Size(pyLi);
228       ret.resize(size);
229       for(int i=0;i<size;i++)
230         {
231           PyObject *obj=PyTuple_GetItem(pyLi,i);
232           int status=SWIG_ConvertPtr(obj,&argp,ty,0|0);
233           if(!SWIG_IsOK(status))
234             {
235               std::ostringstream oss; oss << "convertFromPyObjVectorOfObj : tuple is excepted to contain only " << typeStr << " instances !";
236               throw YACS::Exception(oss.str());
237             }
238           T arg=reinterpret_cast< T >(argp);
239           ret[i]=arg;
240         }
241     }
242   else if(SWIG_IsOK(SWIG_ConvertPtr(pyLi,&argp,ty,0|0)))
243     {
244       ret.resize(1);
245       T arg=reinterpret_cast< T >(argp);
246       ret[0]=arg;
247     }
248   else
249     throw YACS::Exception("convertFromPyObjVectorOfObj : not a list nor a tuple");
250 }
251
252 %}
253
254 #if SWIG_VERSION >= 0x010329
255 %template()        std::list<int>;
256 %template()        std::list<std::string>;
257 #else
258
259 #ifdef SWIGPYTHON
260 %typemap(out) std::list<int>
261 {
262   int i;
263   std::list<int>::iterator iL;
264
265   $result = PyList_New($1.size());
266   for (i=0, iL=$1.begin(); iL!=$1.end(); i++, iL++)
267     PyList_SetItem($result,i,PyLong_FromLong((*iL))); 
268 }
269
270 %typemap(out) std::list<std::string>
271 {
272   int i;
273   std::list<std::string>::iterator iL;
274
275   $result = PyList_New($1.size());
276   for (i=0, iL=$1.begin(); iL!=$1.end(); i++, iL++)
277     PyList_SetItem($result,i,PyString_FromString((*iL).c_str())); 
278 }
279
280 %typemap(in) std::list<std::string>
281 {
282   /* Check if input is a list */
283   if (PyList_Check($input))
284     {
285       int size = PyList_Size($input);
286       int i = 0;
287       std::list<std::string> myList;
288       $1 = myList;
289       for (i = 0; i < size; i++)
290         {
291           PyObject *o = PyList_GetItem($input,i);
292           if (PyString_Check(o))
293             $1.push_back(std::string(PyString_AsString(PyList_GetItem($input,i))));
294           else
295             {
296               PyErr_SetString(PyExc_TypeError,"list must contain strings");
297               return NULL;
298             }
299         }
300     }
301   else
302     {
303       PyErr_SetString(PyExc_TypeError,"not a list");
304       return NULL;
305     }
306 }
307 #endif
308 #endif
309
310 #ifdef SWIGPYTHON
311
312 %typecheck(SWIG_TYPECHECK_POINTER) YACS::ENGINE::Any*
313 {
314   void *ptr;
315   if (SWIG_ConvertPtr($input, (void **) &ptr, $1_descriptor, 0) == 0) 
316     $1 = 1;
317   else if (PyInt_Check($input))
318     $1 = 1;
319   else if(PyFloat_Check($input))
320     $1 = 1;
321   else if (PyString_Check($input))
322     $1 = 1;
323   else 
324     $1 = 0;
325 }
326
327 %typemap(in) YACS::ENGINE::Any* (int is_new_object)
328 {
329   if ((SWIG_ConvertPtr($input,(void **) &$1, $1_descriptor,SWIG_POINTER_EXCEPTION)) == 0)
330     {
331       // It is an Any : it is converted by SWIG_ConvertPtr $input -> $1
332       is_new_object=0;
333     }
334   else if (PyInt_Check($input))
335     {
336       // It is an Int
337       $1=YACS::ENGINE::AtomAny::New((int)PyInt_AsLong($input));
338       is_new_object=1;
339     }
340   else if(PyFloat_Check($input))
341     {
342       // It is a Float
343       $1=YACS::ENGINE::AtomAny::New(PyFloat_AsDouble($input));
344       is_new_object=1;
345     }
346   else if(PyString_Check($input))
347     {
348       // It is a Float
349       $1=YACS::ENGINE::AtomAny::New(PyString_AsString($input));
350       is_new_object=1;
351     }
352   else
353     {
354       // It is an error
355       PyErr_SetString(PyExc_TypeError,"not a yacs any or a convertible type");
356       return NULL;
357     }
358 }
359
360 %typemap(directorout) YACS::ENGINE::Any*
361 {
362   if ((SWIG_ConvertPtr($1,(void **) &$result, $1_descriptor,SWIG_POINTER_EXCEPTION)) == 0)
363     {
364       // It is an Any : it is converted by SWIG_ConvertPtr $input -> $1
365     }
366   else if (PyInt_Check($1))
367     {
368       // It is an Int
369       $result=YACS::ENGINE::AtomAny::New((int)PyInt_AsLong($1));
370     }
371   else if(PyFloat_Check($1))
372     {
373       // It is a Float
374       $result=YACS::ENGINE::AtomAny::New(PyFloat_AsDouble($1));
375     }
376   else if(PyString_Check($1))
377     {
378       // It is a String
379       $result=YACS::ENGINE::AtomAny::New(PyString_AsString($1));
380     }
381   else
382     {
383       // It is an error
384       PyErr_SetString(PyExc_TypeError,"not a yacs any or a convertible type");
385       return NULL;
386     }
387 }
388
389 %typemap(freearg) YACS::ENGINE::Any *inSample
390 {
391   //a reference is taken by the routine called
392   if (!is_new_object$argnum) $1->incrRef();
393 }
394
395 %typemap(freearg) YACS::ENGINE::Any*
396 {
397   //no reference taken by the routine called
398   if (is_new_object$argnum) $1->decrRef();
399 }
400
401 %typemap(out) YACS::ENGINE::Any*
402 {
403   if(dynamic_cast<YACS::ENGINE::SequenceAny *>($1))
404     $result=SWIG_NewPointerObj((void*)$1,SWIGTYPE_p_YACS__ENGINE__SequenceAny,$owner);
405   else if(dynamic_cast<YACS::ENGINE::ArrayAny *>($1))
406     $result=SWIG_NewPointerObj((void*)$1,SWIGTYPE_p_YACS__ENGINE__ArrayAny,$owner);
407   else if(dynamic_cast<YACS::ENGINE::StructAny *>($1))
408     $result=SWIG_NewPointerObj((void*)$1,SWIGTYPE_p_YACS__ENGINE__StructAny,$owner);
409   else
410     $result=SWIG_NewPointerObj((void*)$1,SWIGTYPE_p_YACS__ENGINE__Any,$owner);
411 }
412
413 %typemap(out) YACS::ENGINE::TypeCode*
414 {
415   if(dynamic_cast<YACS::ENGINE::TypeCodeStruct *>($1))
416     $result=SWIG_NewPointerObj((void*)$1,SWIGTYPE_p_YACS__ENGINE__TypeCodeStruct,$owner);
417   else if(dynamic_cast<YACS::ENGINE::TypeCodeSeq *>($1))
418     $result=SWIG_NewPointerObj((void*)$1,SWIGTYPE_p_YACS__ENGINE__TypeCodeSeq,$owner);
419   else if(dynamic_cast<YACS::ENGINE::TypeCodeObjref *>($1))
420     $result=SWIG_NewPointerObj((void*)$1,SWIGTYPE_p_YACS__ENGINE__TypeCodeObjref,$owner);
421   else
422     $result=SWIG_NewPointerObj((void*)$1,SWIGTYPE_p_YACS__ENGINE__TypeCode,$owner);
423 }
424
425 %typemap(in) std::list<YACS::ENGINE::TypeCodeObjref*>
426 {
427   // Check if input is a list 
428   if (PyList_Check($input))
429     {
430       int size = PyList_Size($input);
431       int i = 0;
432       std::list<YACS::ENGINE::TypeCodeObjref*> myList;
433       $1 = myList;
434       for (i = 0; i < size; i++)
435         {
436           PyObject *o = PyList_GetItem($input,i);
437           YACS::ENGINE::TypeCode* temp;
438           if ((SWIG_ConvertPtr(o, (void **) &temp, $descriptor(YACS::ENGINE::TypeCode*),0)) == -1) 
439             {
440               PyErr_SetString(PyExc_TypeError,"not a YACS::ENGINE::TypeCode*");
441               return NULL;
442             }
443           else
444             {
445               if(temp->kind() == YACS::ENGINE::Objref)
446                 $1.push_back((YACS::ENGINE::TypeCodeObjref*)temp);
447               else
448                 {
449                   PyErr_SetString(PyExc_TypeError,"not a YACS::ENGINE::TypeCodeObjref*");
450                   return NULL;
451                 }
452             }
453         }
454     }
455   else
456     {
457       PyErr_SetString(PyExc_TypeError,"not a list");
458       return NULL;
459     }
460 }
461
462 %typemap(out) YACS::ENGINE::Node*
463 {
464   $result=convertNode($1,$owner);
465 }
466
467 %typemap(out) YACS::ENGINE::ServiceNode*
468 {
469   $result=convertNode($1,$owner);
470 }
471
472 %typemap(out) YACS::ENGINE::InlineNode*
473 {
474   $result=convertNode($1,$owner);
475 }
476
477 %typemap(out) YACS::ENGINE::InlineFuncNode*
478 {
479   $result=convertNode($1,$owner);
480 }
481
482 %typemap(out) YACS::ENGINE::ComposedNode*
483 {
484   $result=convertNode($1,$owner);
485 }
486
487 %typemap(out) YACS::ENGINE::OptimizerLoop*
488 {
489   $result=convertNode($1,$owner);
490 }
491
492 %typemap(out) YACS::ENGINE::Proc*
493 {
494   $result=convertNode($1,$owner);
495 }
496
497 %typemap(out) std::set<YACS::ENGINE::Node *>
498 {
499   int i;
500   std::set<YACS::ENGINE::Node *>::iterator iL;
501
502   $result = PyList_New($1.size());
503   PyObject * ob;
504   for (i=0, iL=$1.begin(); iL!=$1.end(); i++, iL++)
505     {
506       ob=convertNode(*iL);
507       PyList_SetItem($result,i,ob); 
508     }
509 }
510
511 %typemap(out) std::list<YACS::ENGINE::Node *>
512 {
513   int i;
514   std::list<YACS::ENGINE::Node *>::iterator iL;
515
516   $result = PyList_New($1.size());
517   PyObject * ob;
518   for (i=0, iL=$1.begin(); iL!=$1.end(); i++, iL++)
519     {
520       ob=convertNode(*iL);
521       PyList_SetItem($result,i,ob); 
522     }
523 }
524
525 %typemap(out) YACS::ENGINE::InputPort*,YACS::ENGINE::OutputPort*,YACS::ENGINE::InPort*,YACS::ENGINE::OutPort*,YACS::ENGINE::InPropertyPort*
526 {
527   $result=convertPort($1,$owner);
528 }
529
530 %typemap(out) std::set<YACS::ENGINE::InGate *>
531 {
532   int i;
533   std::set<YACS::ENGINE::InGate *>::iterator iL;
534   $result = PyList_New($1.size());
535   PyObject * ob;
536   for (i=0, iL=$1.begin(); iL!=$1.end(); i++, iL++)
537     {
538       ob=convertPort(*iL);
539       PyList_SetItem($result,i,ob); 
540     }
541 }
542
543 %typemap(out) std::set<YACS::ENGINE::OutGate *>
544 {
545   int i;
546   std::set<YACS::ENGINE::OutGate *>::iterator iL;
547   $result = PyList_New($1.size());
548   PyObject * ob;
549   for (i=0, iL=$1.begin(); iL!=$1.end(); i++, iL++)
550     {
551       ob=convertPort(*iL);
552       PyList_SetItem($result,i,ob); 
553     }
554 }
555
556 %typemap(out) std::set<YACS::ENGINE::InPort *>
557 {
558   std::set<YACS::ENGINE::InPort *>::iterator iL;
559   $result = PyList_New(0);
560   PyObject * ob;
561   int status;
562   for (iL=$1.begin(); iL!=$1.end(); iL++)
563     {
564       ob=convertPort(*iL);
565       status=PyList_Append($result,ob);
566       Py_DECREF(ob);
567       if (status < 0)
568         {
569           PyErr_SetString(PyExc_TypeError,"cannot build the inport list");
570           return NULL;
571         }
572     }
573 }
574
575 %typemap(out) std::set<YACS::ENGINE::OutPort *>
576 {
577   std::set<YACS::ENGINE::OutPort *>::iterator iL;
578   $result = PyList_New(0);
579   PyObject * ob;
580   int status;
581   for (iL=$1.begin(); iL!=$1.end(); iL++)
582     {
583       ob=convertPort(*iL);
584       status=PyList_Append($result,ob);
585       Py_DECREF(ob);
586       if (status < 0)
587         {
588           PyErr_SetString(PyExc_TypeError,"cannot build the outport list");
589           return NULL;
590         }
591     }
592 }
593
594 %typemap(out) std::list<YACS::ENGINE::OutPort *>
595 {
596   std::list<YACS::ENGINE::OutPort *>::const_iterator it;
597   $result = PyTuple_New($1.size());
598   int i = 0;
599   for (it = $1.begin(); it != $1.end(); ++it, ++i) {
600     PyTuple_SetItem($result,i,convertPort(*it));
601   }
602 }
603 %typemap(out) std::list<YACS::ENGINE::InPort *>
604 {
605   std::list<YACS::ENGINE::InPort *>::const_iterator it;
606   $result = PyTuple_New($1.size());
607   int i = 0;
608   for (it = $1.begin(); it != $1.end(); ++it, ++i) {
609     PyTuple_SetItem($result,i,convertPort(*it));
610   }
611 }
612 %typemap(out) std::list<YACS::ENGINE::OutputPort *>
613 {
614   std::list<YACS::ENGINE::OutputPort *>::const_iterator it;
615   $result = PyTuple_New($1.size());
616   int i = 0;
617   for (it = $1.begin(); it != $1.end(); ++it, ++i) {
618     PyTuple_SetItem($result,i,convertPort(*it));
619   }
620 }
621 %typemap(out) std::list<YACS::ENGINE::InputPort *>
622 {
623   std::list<YACS::ENGINE::InputPort *>::const_iterator it;
624   $result = PyTuple_New($1.size());
625   int i = 0;
626   for (it = $1.begin(); it != $1.end(); ++it, ++i) {
627     PyTuple_SetItem($result,i,convertPort(*it));
628   }
629 }
630 %typemap(out) std::list<YACS::ENGINE::InPropertyPort*>
631 {
632   std::list<YACS::ENGINE::InPropertyPort *>::const_iterator it;
633   $result = PyTuple_New($1.size());
634   int i = 0;
635   for (it = $1.begin(); it != $1.end(); ++it, ++i) {
636     PyTuple_SetItem($result,i,convertPort(*it));
637   }
638 }
639
640 #endif
641
642 /*
643  * Exception section
644  */
645 // a general exception handler
646 %exception {
647    try 
648    {
649       $action
650    } 
651    catch(YACS::Exception& _e) 
652    {
653       PyErr_SetString(PyExc_ValueError,_e.what());
654       return NULL;
655    } 
656    catch(std::invalid_argument& _e) 
657    {
658       PyErr_SetString(PyExc_IOError ,_e.what());
659       return NULL;
660    } catch (std::domain_error& e) {
661       SWIG_exception(SWIG_ValueError, e.what() );
662    } catch (std::overflow_error& e) {
663       SWIG_exception(SWIG_OverflowError, e.what() );
664    } catch (std::out_of_range& e) {
665       PyErr_SetString(PyExc_KeyError,e.what());
666       return NULL;
667    } catch (std::length_error& e) {
668       SWIG_exception(SWIG_IndexError, e.what() );
669    } catch (std::runtime_error& e) {
670       SWIG_exception(SWIG_RuntimeError, e.what() );
671    }
672    OMNIPY_CATCH_AND_HANDLE_SYSTEM_EXCEPTIONS
673    catch (std::exception& e) {
674       SWIG_exception(SWIG_SystemError, e.what() );
675    }
676    catch(...) 
677    {
678      SWIG_exception(SWIG_UnknownError, "Unknown exception");
679    }
680 }
681
682 // a specific exception handler = generic + release lock
683 %define PYEXCEPTION(name)
684 %exception name {
685    try 
686    {
687       InterpreterUnlocker _l;
688       $action
689    } 
690    catch(YACS::Exception& _e) 
691    {
692       PyErr_SetString(PyExc_ValueError,_e.what());
693       return NULL;
694    }
695    catch(std::invalid_argument& _e) 
696    {
697       PyErr_SetString(PyExc_IOError ,_e.what());
698       return NULL;
699    } catch (std::domain_error& e) {
700       SWIG_exception(SWIG_ValueError, e.what() );
701    } catch (std::overflow_error& e) {
702       SWIG_exception(SWIG_OverflowError, e.what() );
703    } catch (std::out_of_range& e) {
704       PyErr_SetString(PyExc_KeyError,e.what());
705       return NULL;
706    } catch (std::length_error& e) {
707       SWIG_exception(SWIG_IndexError, e.what() );
708    } catch (std::runtime_error& e) {
709       SWIG_exception(SWIG_RuntimeError, e.what() );
710    }
711    OMNIPY_CATCH_AND_HANDLE_SYSTEM_EXCEPTIONS
712    catch (std::exception& e) {
713       SWIG_exception(SWIG_SystemError, e.what() );
714    }
715    catch(...) 
716    {
717      SWIG_exception(SWIG_UnknownError, "Unknown exception");
718    }
719 }
720 %enddef
721
722 %define EXCEPTION(name)
723 %exception name {
724    try 
725    {
726       $action
727    } 
728    catch(YACS::Exception& _e) 
729    {
730       PyErr_SetString(PyExc_ValueError,_e.what());
731       return NULL;
732    }
733    catch(std::invalid_argument& _e) 
734    {
735       PyErr_SetString(PyExc_IOError ,_e.what());
736       return NULL;
737    } catch (std::domain_error& e) {
738       SWIG_exception(SWIG_ValueError, e.what() );
739    } catch (std::overflow_error& e) {
740       SWIG_exception(SWIG_OverflowError, e.what() );
741    } catch (std::out_of_range& e) {
742       PyErr_SetString(PyExc_KeyError,e.what());
743       return NULL;
744    } catch (std::length_error& e) {
745       SWIG_exception(SWIG_IndexError, e.what() );
746    } catch (std::runtime_error& e) {
747       SWIG_exception(SWIG_RuntimeError, e.what() );
748    }
749    OMNIPY_CATCH_AND_HANDLE_SYSTEM_EXCEPTIONS
750    catch (std::exception& e) {
751       SWIG_exception(SWIG_SystemError, e.what() );
752    }
753    catch(...) 
754    {
755      SWIG_exception(SWIG_UnknownError, "Unknown exception");
756    }
757 }
758 %enddef
759 /*
760  * End of Exception section
761  */
762
763 /*
764  * Ownership section
765  */
766 //Release ownership : transfer it to C++
767 %apply SWIGTYPE *DISOWN { YACS::ENGINE::CatalogLoader* factory};
768 %apply SWIGTYPE *DISOWN { YACS::ENGINE::Node *DISOWNnode };
769 %apply SWIGTYPE *DISOWN { Node *DISOWNnode };
770 /*
771  * End of ownership section
772  */
773
774 /*
775  * Reference counting section
776  * reference counted objects are created with a count of 1 so we do not incrRef them on wrapping creation
777  * we only decrRef them on wrapping destruction.
778  * Do not forget to declare them new (%newobject) when they are not returned from a constructor
779  * unless they will not be decrRef on wrapping destruction
780  */
781 %feature("ref")   YACS::ENGINE::RefCounter  ""
782 %feature("unref") YACS::ENGINE::RefCounter  "$this->decrRef();"
783
784 // Unfortunately, class ComponentInstance inherits from RefCounter AND PropertyInterface. Thus the ref and
785 // unref features are ambiguous and with swig 2.0.7 at least, we must re-specify those features for class
786 // ComponentInstance unless the instances are destroyed when the Swig object is unref'ed.
787 %feature("ref")   YACS::ENGINE::ComponentInstance  ""
788 %feature("unref") YACS::ENGINE::ComponentInstance  "$this->decrRef();"
789 /*
790  * End of Reference counting section
791  */
792
793 /*
794 %wrapper %{
795   namespace swig {
796     template <> struct traits_from<YACS::ENGINE::InPort *> {
797       static PyObject *from(YACS::ENGINE::InPort* val){
798         return convertPort(val);
799       }
800     };
801     template <> struct traits_from<YACS::ENGINE::OutPort *> {
802       static PyObject *from(YACS::ENGINE::OutPort* val) {
803         return convertPort(val);
804       }
805     };
806     template <> struct traits_from<YACS::ENGINE::InputPort *> {
807       static PyObject *from(YACS::ENGINE::InPort* val){
808         return convertPort(val);
809       }
810     };
811     template <> struct traits_from<YACS::ENGINE::OutputPort *> {
812       static PyObject *from(YACS::ENGINE::OutPort* val) {
813         return convertPort(val);
814       }
815     };
816   }
817 %}
818 */
819
820 %define REFCOUNT_TEMPLATE(tname, T...)
821 /*
822  This macro is a special wrapping for map with value type which derives from RefCounter.
823  To overload standard SWIG wrapping we define a full specialization of std::map
824  with %extend for 4 basic methods : getitem, setitem, delitem and keys.
825  Then we complete the interface by deriving the shadow wrapper from
826  the python mixin class (UserDict.DictMixin).
827  Do not forget to declare the new shadow class to SWIG with tname_swigregister(tname).
828  Objects returned by __getitem__ are declared new (%newobject) so that when destroyed they
829  call decrRef (see feature("unref") for RefCounter).
830 */
831 template<>
832 class std::map<std::string,T*>
833 {
834 public:
835 %extend
836 {
837   void __setitem__(const std::string& name, T* c)
838     {
839       std::map<std::string, T* >::iterator i = self->find(name);
840       if (i != self->end())
841         {
842           if(c==i->second)
843             return;
844           i->second->decrRef();
845         }
846       (*self)[name]=c;
847       c->incrRef();
848     }
849   T* __getitem__(std::string name)
850     {
851       std::map<std::string, T* >::iterator i = self->find(name);
852       if (i != self->end())
853         {
854           i->second->incrRef();
855           return i->second;
856         }
857       else
858         throw std::out_of_range("key not found");
859     }
860   void __delitem__(std::string name)
861     {
862       std::map<std::string, T* >::iterator i = self->find(name);
863       if (i != self->end()){
864         i->second->decrRef();
865         self->erase(i);
866       }
867       else
868         throw std::out_of_range("key not found");
869     }
870   PyObject* keys() {
871       int pysize = self->size();
872       PyObject* keyList = PyList_New(pysize);
873       std::map<std::string, T* >::const_iterator i = self->begin();
874       for (int j = 0; j < pysize; ++i, ++j) {
875         PyList_SET_ITEM(keyList, j, PyString_FromString(i->first.c_str()));
876       }
877       return keyList;
878     }
879 }
880 };
881
882 %newobject std::map<std::string,T* >::__getitem__;
883 %template()   std::pair<std::string, T* >;
884 %template(tname)    std::map<std::string, T* >;
885 %pythoncode{
886 from UserDict import DictMixin
887 class tname(tname,DictMixin):pass
888 tname##_swigregister(tname)
889 }
890 %enddef
891
892