OLD | NEW |
(Empty) | |
| 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) |
| 73 if (!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 | %newpoi
nter_flags)); |
| 87 } |
| 88 }%enddef |
OLD | NEW |