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:
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:
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:
This way, no matter where the OgreNewt::Body destructor was called, everything is safe (I think).
Suggestions? I hope this makes sense.
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.