What is the appropriate way to call a method with an action, and what should the method itself look like for passing a CGPoint parameter? I've tried to look up examples online without much luck, so I've been pretty much guessing.
What I have tried is this for calling it:
CGPoint spriteCoord = saveStation.sprite.position;
id a1=[CCMoveTo actionWithDuration:.4 position:ccp(saveStation.sprite.position.x,saveStation.sprite.position.y)];
id actionSaveStationReaction = [CCCallFuncND actionWithTarget:self selector:@selector(saveStationReaction : data:) data:&spriteCoord];
[hero.heroSprite runAction:[CCSequence actions:a1, actionSaveStationReaction, nil]];
And the method itself:
-(void) saveStationReaction:(id)sender data:(void *)data {
CGPoint spriteCoord = (void *)data; //error: Invalid initializer
NSLog(@"spriteCoord x = %f", spriteCoord.x);
NSLog(@"spriteCoord y = %f", spriteCoord.y);
}
The proper way to send a CGPoint (or any non-id type like C structs) to a method that takes an id as parameter (any method that uses performSelector) is by wrapping it in an NSValue object:
NSValue* value = [NSValue valueWithBytes:&spriteCoord objCType:@encode(CGPoint)];
In the method that is being called you can retrieve the point from the NSValue object by casting the data pointer to NSValue* and calling getValue:
-(void) saveStationReaction:(id)sender data:(void *)data {
CGPoint spriteCoord;
[((NSValue*)data) getValue:&spriteCoord];
NSLog(@"spriteCoord x = %f", spriteCoord.x);
NSLog(@"spriteCoord y = %f", spriteCoord.y);
}
GamingHorror's suggestion on wrapping the CGPoint in an NSValue is spot-on.
But there's a simpler way than using valueWithByte:objCType:
method: valueWithCGPoint:
, assuming you are coding for iOS and not MacOS.
NSValue *spriteCoordValue = [NSValue valueWithCGPoint:spriteCoord];
[CCCallFuncND actionWithTarget:self selector:@selector(saveStationReaction:data:) data:spriteCoordValue];
// and ..
-(void) saveStationReaction:(id)sender data:(void *)data {
CGPoint spriteCoord = [(NSValue *)data CGPointValue];
NSLog(@"spriteCoord x = %f", spriteCoord.x);
NSLog(@"spriteCoord y = %f", spriteCoord.y);
}
NSValue can also deal with CGSize and CGRect using similar way.
You can't typecast to a CGPoint
with that syntax. Try....
CGPoint *spriteCoord = data;
CGFloat ptX = spriteCoord->x;
CGFloat ptY = spriteCoord->y;
I tried...
CGPoint* spriteCoord = (CGPoint)data;
which didn't work and I guess expectedly so. Try my first suggestion and see if that works for you. It did compile for me but I'm not sure how it will execute and that may depend on your particular situation.
CGPoint is a struct, not an object, so you can't pass it directly to any of the CCCallFunc
's. There are several ways of dealing with this, but the quickest converts the CGPoint to NSString using NSStringFromCGPoint, passing the string, then converting it back to a CGPoint using CGPointFromString.