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