Making Python function just like C++
Bob Hood <bhood2 <at> comcast.net>
2010-05-03 16:09:30 GMT
I'm wrapping an API using SWIG 1.3.40. This API defines a plug-in
architecture that I'm trying to recreate as exactly as possible in
Python. For example, here is an excerpt from a sample plug-in code in C++:
...
virtual void execute_item(const SceneItemRef& item, bool
/*reevaluating*/)
{
MeshRef m(item);
if (!m.valid())
return;
MeshEditContext edit(m.get(), component());
VertexArray pv(4);
pv[0] = m->create_vertex(Vector3d(-1, 0, -1));
pv[1] = m->create_vertex(Vector3d(-1, 0, 1));
pv[2] = m->create_vertex(Vector3d(1, 0, 1));
pv[3] = m->create_vertex(Vector3d(1, 0, -1));
m->create_poly_directly(pv);
}
virtual void execute_scene(const TreeNodeRef& scene)
{
execute_item(create_scene_mesh(active_scene(), "Square"), false);
}
...
So far, in Python, I have the following working (up to a point):
...
def execute_item(self, scene_item, reevaluating=False):
m = MeshRef(scene_item.component())
if not m.valid():
return
edit = MeshEditContext(m.get(), IPyItemCommand.component(self))
pv = VertexArray(4)
pv[0] = m.create_vertex(Vector3d(-1, 0, -1))
pv[1] = m.create_vertex(Vector3d(-1, 0, 1))
pv[2] = m.create_vertex(Vector3d(1, 0, 1))
pv[3] = m.create_vertex(Vector3d(1, 0, -1))
m.create_poly_directly(pv)
def execute_scene(self, scene):
self.execute_item(PyAsgardLib.create_scene_mesh(scene,
"PythonSquare"));
...
What I'm particularly focused on in this post is the creation of the
MeshRef instance. Each of these types ("MeshRef" and "SceneItemRef")
are constructed from a parameterized type called
"ComponentInterfaceReferenceT". This template type provides the
following constructor that allows for the seemingly implicit conversion
between types:
template <class OtherT>
/*implicit*/ ComponentInterfacePtrT(const
ComponentInterfacePtrT<OtherT>& other);
whose implementation looks like:
template <class T>
template <class OtherT>
ComponentInterfaceReferenceT<T>::ComponentInterfaceReferenceT(const
ComponentInterfaceReferenceT<OtherT>& other):
ComponentInterfaceReference(other.component())
{
init(InterfaceTypeID<T>::id());
}
If you will note, in the Python code, I'm having to explicitly pass the
"component" element to the construction by calling the component()
method directly:
m = MeshRef(scene_item.component())
Since SWIG seems to be very type-literal in the generated code, it's
actually doing type-to-type comparisons when I attempt to simply pass
the provided ComponentInterfaceReferenceT-derived type directly:
m = MeshRef(scene_item)
and, of course, it is failing.
While the method of passing the component() directly works, I am
wondering if there is a way to get SWIG to generate code that would
mimic this implicit construction, so I could just pass the
ComponentInterfaceReference-derived type to MeshRef() and have the
Python code look/act just like C++, as in the last line of Python above?
(Oh, and if you plan to recommend using %implicitconv, please provide an
example that would solve this. I've tried it, without success.)
------------------------------------------------------------------------------