Destructor improvement to OgreNewt::Body

litghost

18-08-2007 19:33:36

I am working with OgreNewt, and have found some small bugs when I (mis-)used OgreNewt::Body.

First off, the OgreNewt::Body destructor is not virtual. Maybe you never intended for people to inherit OgreNewt::Body, but I did anyways. Regardless, maybe you want to change the OgreNewt::Body destructor to virtual.

Second, is the current destructor looks like:


Body::~Body()
{
if (m_body)
{
if (NewtonBodyGetUserData(m_body))
{
NewtonBodySetDestructorCallback( m_body, NULL );
NewtonDestroyBody( m_world->getNewtonWorld(), m_body );
}
}
}


However, this introduces an immediate bug if the destructor was called in the middle of a World update. If I may quote the Newton docs:


NewtonDestroyBody

If this function is called from inside a simulation step the destruction of the body will be delayed until end of the time step.


The problem is, if the OgreNewt::Body is attached to anything, there is the possiblility of callbacks firing. Since the data the callbacks expects is now destroyed, the program will crash. My solution is to unregister all callbacks at destruction. New OgreNewt::Body destructor:


Body::~Body()
{
if (m_body)
{
if (NewtonBodyGetUserData(m_body))
{
NewtonBodySetDestructorCallback( m_body, NULL );
NewtonBodySetUserData( m_body, NULL );
NewtonBodySetTransformCallback( m_body, NULL );
NewtonBodySetForceAndTorqueCallback( m_body, NULL );
NewtonBodySetAutoactiveCallback( m_body, NULL );

NewtonDestroyBody( m_world->getNewtonWorld(), m_body );
}
}
}


This way, no matter where the OgreNewt::Body destructor was called, everything is safe (I think).

Suggestions? I hope this makes sense.

walaber

20-08-2007 00:26:06

i don't see why this should cause any harm... I'll update my local code, and it will be reflected in the next update I do...

I'm currently waiting for Newton 1.6 to be released, and then I will give OgreNewt an update to work with Newton, and probably clean up the demos a bit. this change will go in that update.