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