Skip to content
Permalink
Browse files

Fix for a rare but fatal sleeping/contact graph bug.

  • Loading branch information...
slembcke committed Dec 12, 2012
1 parent ef6dfd6 commit dc90c45a485e7b3d8a29987d99239d7abf6673de
Showing with 14 additions and 3 deletions.
  1. +6 −0 include/chipmunk/chipmunk_private.h
  2. +1 −1 src/cpArbiter.c
  3. +7 −2 src/cpSpace.c
@@ -257,6 +257,12 @@ cpArbiterThreadForBody(cpArbiter *arb, cpBody *body)
return (arb->body_a == body ? &arb->thread_a : &arb->thread_b);
}

static inline cpBool
cpArbiterIsFiltered(cpArbiter *arb)
{
return (arb->contacts == NULL);
}

void cpArbiterUnthread(cpArbiter *arb);

void cpArbiterUpdate(cpArbiter *arb, cpContact *contacts, int numContacts, struct cpCollisionHandler *handler, cpShape *a, cpShape *b);
@@ -221,7 +221,7 @@ void
cpArbiterUpdate(cpArbiter *arb, cpContact *contacts, int numContacts, cpCollisionHandler *handler, cpShape *a, cpShape *b)
{
// Arbiters without contact data may exist if a collision function rejected the collision.
if(arb->contacts){
if(!cpArbiterIsFiltered(arb)){
// Iterate over the possible pairs to look for hash value matches.
for(int i=0; i<arb->numContacts; i++){
cpContact *old = &arb->contacts[i];
@@ -340,8 +340,13 @@ cachedArbitersFilter(cpArbiter *arb, struct arbiterFilterContext *context)
// Call separate when removing shapes.
if(shape && arb->state != cpArbiterStateCached) cpArbiterCallSeparate(arb, context->space);

cpArbiterUnthread(arb);
cpArrayDeleteObj(context->space->arbiters, arb);
// If the arbiter is active (non-sensor/filtered) it will have a contacts array.
// TODO is this too much of a hack?...
if(!cpArbiterIsFiltered(arb)){
cpArbiterUnthread(arb);
cpArrayDeleteObj(context->space->arbiters, arb);
}

cpArrayPush(context->space->pooledArbiters, arb);

return cpFalse;

0 comments on commit dc90c45

Please sign in to comment.
You can’t perform that action at this time.