You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
2.4 KiB
89 lines
2.4 KiB
4 years ago
|
/*
|
||
|
Implement a more natural wrap for factory methods, for example, if
|
||
|
you have:
|
||
|
|
||
|
---- geometry.h --------
|
||
|
struct Geometry {
|
||
|
enum GeomType{
|
||
|
POINT,
|
||
|
CIRCLE
|
||
|
};
|
||
|
|
||
|
virtual ~Geometry() {}
|
||
|
virtual int draw() = 0;
|
||
|
|
||
|
//
|
||
|
// Factory method for all the Geometry objects
|
||
|
//
|
||
|
static Geometry *create(GeomType i);
|
||
|
};
|
||
|
|
||
|
struct Point : Geometry {
|
||
|
int draw() { return 1; }
|
||
|
double width() { return 1.0; }
|
||
|
};
|
||
|
|
||
|
struct Circle : Geometry {
|
||
|
int draw() { return 2; }
|
||
|
double radius() { return 1.5; }
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// Factory method for all the Geometry objects
|
||
|
//
|
||
|
Geometry *Geometry::create(GeomType type) {
|
||
|
switch (type) {
|
||
|
case POINT: return new Point();
|
||
|
case CIRCLE: return new Circle();
|
||
|
default: return 0;
|
||
|
}
|
||
|
}
|
||
|
---- geometry.h --------
|
||
|
|
||
|
|
||
|
You can use the %factory with the Geometry::create method as follows:
|
||
|
|
||
|
%newobject Geometry::create;
|
||
|
%factory(Geometry *Geometry::create, Point, Circle);
|
||
|
%include "geometry.h"
|
||
|
|
||
|
and Geometry::create will return a 'Point' or 'Circle' instance
|
||
|
instead of the plain 'Geometry' type. For example, in python:
|
||
|
|
||
|
circle = Geometry.create(Geometry.CIRCLE)
|
||
|
r = circle.radius()
|
||
|
|
||
|
where circle is a Circle proxy instance.
|
||
|
|
||
|
NOTES: remember to fully qualify all the type names and don't
|
||
|
use %factory inside a namespace declaration, ie, instead of
|
||
|
|
||
|
namespace Foo {
|
||
|
%factory(Geometry *Geometry::create, Point, Circle);
|
||
|
}
|
||
|
|
||
|
use
|
||
|
|
||
|
%factory(Foo::Geometry *Foo::Geometry::create, Foo::Point, Foo::Circle);
|
||
|
|
||
|
|
||
|
*/
|
||
|
|
||
|
%define %_factory_dispatch(Type)
|
||
|
if (!dcast) {
|
||
|
Type *dobj = dynamic_cast<Type *>($1);
|
||
|
if (dobj) {
|
||
|
dcast = 1;
|
||
|
%set_output(SWIG_NewPointerObj(%as_voidptr(dobj),$descriptor(Type *), $owner | %newpointer_flags));
|
||
|
}
|
||
|
}%enddef
|
||
|
|
||
|
%define %factory(Method,Types...)
|
||
|
%typemap(out) Method {
|
||
|
int dcast = 0;
|
||
|
%formacro(%_factory_dispatch, Types)
|
||
|
if (!dcast) {
|
||
|
%set_output(SWIG_NewPointerObj(%as_voidptr($1),$descriptor, $owner | %newpointer_flags));
|
||
|
}
|
||
|
}%enddef
|