HI,
I'm getting a crash when I remove a collision handler while still in contact with a object. Here's what happens.
I have this call:
cpSpaceAddCollisionHandler(pSpace, pShape1->collision_type,
pShape2->collision_type,
OnCollision, NULL, NULL, OnSeparate, NULL);
After a while, when an object collides, for certain situations, I want to remove the callback for those 2 collision types, so I call:
cpSpaceRemoveCollisionHandler(pSpace, pShape1->collision_type,
pShape2->collision_type);
Well, i get a crash when they separate, in
contactSetFilter(), at this line:
arb->handler->separate(arb, space, arb->handler->data);
as separate is now an invalid value: 0xabababab
Any suggestions? Is this an invalid situation and it shouldn't be allowed?
BTW, I'm using v5.3.4, so you'll probably suggest I upgrade, but I'd rather not at this point.
Thanks!
Calling cpSpaceRemoveCollisionHandler while still in contact
-
- Posts: 10
- Joined: Fri May 06, 2011 9:12 pm
- Contact:
- slembcke
- Site Admin
- Posts: 4166
- Joined: Tue Aug 14, 2007 7:13 pm
- Contact:
Re: Calling cpSpaceRemoveCollisionHandler while still in con
Ah. I was going to say, I've added specific logic to handle that, but I'm not sure at which version I did it without looking through a ton of change logs.
At the moment I don't have time to get you a fully working solution, but this is how the code works in the latest code. Basically instead of calling the separate callback directly by dereferencing the dangling pointer, it calls cpArbiterCallSeparate() instead. cpArbiterCallSeparate() looks up the handler again, and then calls it. So it safely handles the case where a handler is removed while a collision is active. I don't remember offhand how much work it would take to adapt it to Chipmunk 5.x (I haven't personally worked on that in almost a year now). You might need to change some of the types
At the moment I don't have time to get you a fully working solution, but this is how the code works in the latest code. Basically instead of calling the separate callback directly by dereferencing the dangling pointer, it calls cpArbiterCallSeparate() instead. cpArbiterCallSeparate() looks up the handler again, and then calls it. So it safely handles the case where a handler is removed while a collision is active. I don't remember offhand how much work it would take to adapt it to Chipmunk 5.x (I haven't personally worked on that in almost a year now). You might need to change some of the types
Code: Select all
static inline cpCollisionHandler *
cpSpaceLookupHandler(cpSpace *space, cpCollisionType a, cpCollisionType b)
{
cpCollisionType types[] = {a, b};
return (cpCollisionHandler *)cpHashSetFind(space->collisionHandlers, CP_HASH_PAIR(a, b), types);
}
static inline void
cpArbiterCallSeparate(cpArbiter *arb, cpSpace *space)
{
// The handler needs to be looked up again as the handler cached on the arbiter may have been deleted since the last step.
cpCollisionHandler *handler = cpSpaceLookupHandler(space, arb->a->collision_type, arb->b->collision_type);
handler->separate(arb, space, handler->data);
}
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
-
- Posts: 10
- Joined: Fri May 06, 2011 9:12 pm
- Contact:
Re: Calling cpSpaceRemoveCollisionHandler while still in con
OK, I can probably throw a fix in there for that.
I actually may just bite the bullet and upgrade, as I need to also upgrade SFML, and I might do it all in one go.
Regardless, thanks for the help!
I actually may just bite the bullet and upgrade, as I need to also upgrade SFML, and I might do it all in one go.
Regardless, thanks for the help!
Who is online
Users browsing this forum: No registered users and 2 guests