PageRenderTime 19ms CodeModel.GetById 16ms app.highlight 1ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/Lib/typemaps/factory.swg

#
Unknown | 88 lines | 68 code | 20 blank | 0 comment | 0 complexity | ad53503e3c425dc3d6969146317a14c7 MD5 | raw file
 1/*
 2  Implement a more natural wrap for factory methods, for example, if
 3  you have:
 4
 5  ----  geometry.h --------
 6       struct Geometry {                          
 7         enum GeomType{			     
 8           POINT,				     
 9           CIRCLE				     
10         };					     
11         					     
12         virtual ~Geometry() {}    		     
13         virtual int draw() = 0;
14	 
15	 //
16	 // Factory method for all the Geometry objects
17	 //
18         static Geometry *create(GeomType i);     
19       };					     
20       					     
21       struct Point : Geometry  {		     
22         int draw() { return 1; }		     
23         double width() { return 1.0; }    	     
24       };					     
25       					     
26       struct Circle : Geometry  {		     
27         int draw() { return 2; }		     
28         double radius() { return 1.5; }          
29       }; 					     
30       
31       //
32       // Factory method for all the Geometry objects
33       //
34       Geometry *Geometry::create(GeomType type) {
35         switch (type) {			     
36         case POINT: return new Point();	     
37         case CIRCLE: return new Circle(); 	     
38         default: return 0;			     
39         }					     
40       }					    
41  ----  geometry.h --------
42
43
44  You can use the %factory with the Geometry::create method as follows:
45
46    %newobject Geometry::create;
47    %factory(Geometry *Geometry::create, Point, Circle);
48    %include "geometry.h"
49
50  and Geometry::create will return a 'Point' or 'Circle' instance
51  instead of the plain 'Geometry' type. For example, in python:
52
53    circle = Geometry.create(Geometry.CIRCLE)
54    r = circle.radius()
55
56  where circle is a Circle proxy instance.
57
58  NOTES: remember to fully qualify all the type names and don't
59  use %factory inside a namespace declaration, ie, instead of
60  
61     namespace Foo {
62       %factory(Geometry *Geometry::create, Point, Circle);
63     }
64
65  use
66
67     %factory(Foo::Geometry *Foo::Geometry::create, Foo::Point,  Foo::Circle);   
68
69     
70*/
71
72%define %_factory_dispatch(Type) 
73if (!dcast) {
74  Type *dobj = dynamic_cast<Type *>($1);
75  if (dobj) {
76    dcast = 1;
77    %set_output(SWIG_NewPointerObj(%as_voidptr(dobj),$descriptor(Type *), $owner | %newpointer_flags));
78  }   
79}%enddef
80
81%define %factory(Method,Types...)
82%typemap(out) Method {
83  int dcast = 0;
84  %formacro(%_factory_dispatch, Types)
85  if (!dcast) {
86    %set_output(SWIG_NewPointerObj(%as_voidptr($1),$descriptor, $owner | %newpointer_flags));
87  }
88}%enddef