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