Thanks, this will indeed help me.
Currently, the OdeGeom, OdeJoint, etc. classes remind me very much of NodePath. It’s a not-reference-counted wrapper around a PandaNode - you can have multiple NodePaths pointing to the same node, destroy them without affecting the PandaNode, etc. The one difference is that because ODE isn’t reference counted itself, we can’t just store a reference and it won’t be deleted. I think that’s the biggest problem with the current approach.
If you take a look at the “odecpp.h” and “odecpp_collision.h” in the ODE source, (your version of ODE might or might not have them) you can see they have their own C++ wrapper around the ODE functions and structures. For example, from the dGeom class:
class dGeom {
(...)
protected:
dGeomID _id;
public:
dGeom()
{ _id = 0; }
~dGeom()
{ if (_id) dGeomDestroy (_id); }
dGeomID id() const
{ return _id; }
operator dGeomID() const
{ return _id; }
void destroy() {
if (_id) dGeomDestroy (_id);
_id = 0;
}
(...)
dSpaceID getSpace() const
{ return dGeomGetSpace (_id); }
(...)
}
Also, they have a dSpace class which inherits from dGeom.
It looks like they are just a bit closer to representing the lifetime (although they still provide a way to destroy the geom before the actual class destruction).
However, if you look at the getSpace() function, it still returns a dSpaceID. That’s one of the problems with the other approach of making the objects represent the exact lifetime - you will need to return the exact same OdeSpace object as you gave it. So even if we inherited from those classes, we would still have problems.
The solution for that would be to store a table for that with a pointer to the dBlahID’s and our own objects - we’d need to add some extra memory management smartness. (Also, with this approach, we do need to make the objects reference counted.)
I’ve played a bit with PyODE and noticed they handled these situations fine. I’ve looked in the source code and found this:
# Each geom object has to insert itself into the global dictionary
# _geom_c2py_lut (key:address - value:Python object).
# This lookup table is used in the near callback to translate the C
# pointers into corresponding Python wrapper objects.
Surprisingly, it does look like they use my idea above.
If we chose this idea, we’d need to overhaul the entire layer and we might break people’s code - but I think most people have their code organized in a way that they only have one OdeWhatever pointing to a dWhateverID, so it wouldn’t be much of a problem.
EDIT: Thanks for creating the branch - I will do as you suggested.
I don’t know who should manage it, I’m afraid I lack some CVS experience for that.
I see the ode-develop as a normal tag and not a branch tag, however - how exactly would that work?