Chipmunk error: Grab set is already empty!

Discuss any Chipmunk bugs here.
Post Reply
returnvoid
Posts: 12
Joined: Sun Jan 22, 2012 5:17 pm
Contact:

Chipmunk error: Grab set is already empty!

Post by returnvoid »

Hi, I'm getting this error:

Aborting due to Chipmunk error: Grab set is already empty!
Failed condition: [_grabs count] != 0
Source:/tmp/ChipmunkPro-TMP/Objective-Chipmunk/ChipmunkMultiGrab.m:198

in

- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
for(UITouch *touch in touches){
[multi endLocation:TouchLocation(touch)];
}
}

some help? thanks
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Chipmunk error: Grab set is already empty!

Post by slembcke »

Hrm. That probably should be a warning instead of a hard assertion, and needs a more descriptive assertion.

What is happening is that you are calling endLocation: at least once more than you have called beginLocation:. So the ChipmunkMultiGrab is not tracking any grabs when you tell it to stop tracking one.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
returnvoid
Posts: 12
Joined: Sun Jan 22, 2012 5:17 pm
Contact:

Re: Chipmunk error: Grab set is already empty!

Post by returnvoid »

Thanks slembcke. I was not sure what it was the error so I appreciate your clarification. My implementation is simple and this error happens anytime when you grab so fast over the screen.

This project is build with cocos2d and I do:

Code: Select all

-(id) init{
	if( (self=[super initWithMaskType:FULL_SCREEN]) ) {
        self.isTouchEnabled = YES;
        self.isAccelerometerEnabled = YES;
//I've omitted code
[self initPhysics];
     }
}


-(void) initPhysics{
    space = [[ChipmunkSpace alloc] init];
    space.gravity = ccp(0, gravity);
    
    [space addBounds:CGRectMake(22, 22, 980, 726) thickness:10.0f elasticity:1.0f friction:1.0f layers:CP_ALL_LAYERS group:CP_NO_GROUP collisionType:@"borderType"];
    
    multi = [[ChipmunkMultiGrab alloc] initForSpace:space withSmoothing:cpfpow(0.8, 10.0) withGrabForce:10000];
}

static cpVect
TouchLocation(UITouch *touch){
	return [[CCDirector sharedDirector] convertToGL:[touch locationInView:[touch view]]];
}

- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
	for(UITouch *touch in touches) [multi beginLocation:TouchLocation(touch)];
}

- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
	for(UITouch *touch in touches) [multi updateLocation:TouchLocation(touch)];
}

- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    for(UITouch *touch in touches){
//I tried with this but your explanation says error happens before in ccTouchesBegan, no?
        if(touch.tapCount == 0){
            [multi endLocation:TouchLocation(touch)];
        }
    }
}
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Chipmunk error: Grab set is already empty!

Post by slembcke »

Is it possible that something else is swallowing the touch events?

I'd try adding logging statements in the for loop in the begin and end touch event methods. Increment a counter when you call beginLocation: and decrement it when you call endLocation:. With some logging you can find out of something is preventing you from getting all of your touch events.

If they are balanced and that error is still being thrown, then it's possible that there is a ChipmunkMultiGrab bug.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
returnvoid
Posts: 12
Joined: Sun Jan 22, 2012 5:17 pm
Contact:

Re: Chipmunk error: Grab set is already empty!

Post by returnvoid »

It works! finally I did:

-(id)init{
if(self = [super init]){
//omitted code
touchCounter = 0;
}
return self;
}

- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
for(UITouch *touch in touches) {
touchCounter = 1;
[multi beginLocation:TouchLocation(touch)];
}
}

- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
for(UITouch *touch in touches) [multi updateLocation:TouchLocation(touch)];
}

- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
for(UITouch *touch in touches){
if(touchCounter == 1){
touchCounter = 0;
[multi endLocation:TouchLocation(touch)];
}
}
}

This way I know if ccTouchesBegan was registered because I have another events for navigation, so this solution is perfect, thanks
Post Reply

Who is online

Users browsing this forum: No registered users and 7 guests