Sign in to follow this  

Little design problem with componets + physics

This topic is 3632 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all, I have a little design problem and I would like someone to help here. The main problem is this: I´m using a component based entity system, so, I have a physics component (I´m using Newton Dinamics as my phycis engine). Newton have a callback system to addforces, etc... and I would like to use it for my entities. As you know, callbacks must be simple C functions, or static methods (the same), so this is where the problem comes, I wnated to have a way to encapsulate this callbacks in the phisycs components and let the user inherit from my component and rewrite the callback code to let the entity behave different depending on the physics component the user adds to the entity. As you have guessed, this is causing the problem, because this callback can´t be virtual, but if it is static, all entities will behave physicaly the same, because they all are sharing the static callback method. Is there a way to accomplish this whitout having a function separated from the class?. Thanks in advance, HexDump.

Share this post


Link to post
Share on other sites
The usual technique in these kinds of circumstances is to have a single C style callback function that dispatches the call to your C++ object passed in via the userData member of the callback.

Something along the lines of...

void AddForcesCallback(void* userData)
{
reinterpret_cast<BaseClassOfObject*>(userData)->HandleAddForcesCallback();
}

Then pass the address of your C++ object (of a type derived from BaseClassOfObject) in the userData parameter when you register the callback.

Obviously you need to be very careful with classes and types as the reinterpret cast is a dangerous operator.

Share this post


Link to post
Share on other sites
I'm pretty much reiterating what WillC said but the first idea that comes to my mind would be to use a static function to "reroute" the call to the correct function.
class PhysicsComponent {
void handlePhysics() {
// normal handling here
}
public:
static physicsCallback(void *data) {
reinterpret_cast<PhysicsComponent*>(data)->handlePhysics();
}
};

class FooPhysicsObject : public PhysicsComponent {
void handlePhysics() {
// custom handling here
}
};
That's really the only way I see you can have C style callback interact with an instance of an object.

Share this post


Link to post
Share on other sites
Thanks for the answers, just another one comes to my mind: I see I have to use the reinterpret cast, do you think it is a good option whay I´m trying to do? Would you do it another way? I just ask this, because I hate reinterpret casts :).

Note: I came across the same solution you provide but got stuck when I realized that the method the user should overload, had to be static too.

Thanks in advance,
HexDump.

[Edited by - HexDump on January 6, 2008 2:34:30 PM]

Share this post


Link to post
Share on other sites
i don't know which callback you're trying to handle from Newton, but most of the Newton objects have a "user data" pointer you can associate with the object.

like this:


void NewtonBodySetUserData(const NewtonBody* bodyPtr, void* userDataPtr);
void* NewtonBodyGetUserData(const NewtonBody* bodyPtr);



so your code might do something like this:


// static function
void PhysicsComponent::AddForcesCallback(const NewtonBody* body)
{
PhysicsComponent* component = reinterpret_cast<PhysicsComponent*> NewtonBodyGetUserData(body);

// call virtual function on your PhysicsComponent
component->HandleAddForces();
}




does that help? i don't know exactly which callback or Newton object you're dealing with, but something like the above should be possible.

thanks,
ryan.

Share this post


Link to post
Share on other sites
Quote:
Original post by HexDump
Thanks for the answers, just another one comes to my mind: I see I have to use the reinterpret cast, do you think it is a good option whay I´m trying to do? Would you do it another way? I just ask this, because I hate reinterpret casts :).
HexDump.


In this case, unfortunetly, I don't think it can be avoided since Newton seems to use void* for it's callback userData parameters, so you have no choice but to cast it to the correct type. There are better ways of doing callbacks like this in C++ (for example one the various C++ implementations of delegates), but I imagine Newton does it like that so the SDK can be used with C or C++.

Share this post


Link to post
Share on other sites

This topic is 3632 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this