In the box2d physics loop of my game (the step), I must call the following block:
if ([objectA conformsToProtocol:@protocol(FMCollisionProtocol)]) {
[objectA performSelector:@selector(collideWith:) withObject:objectB];
}
if ([objectB conformsToProtocol:@protocol(FMCollisionProtocol)]) {
[objectB performSelector:@selector(collideWith:) withObject:objectA];
}
The problem is that collideWith: may alter my physics object and this isn't allowed during the step. Once the step is finished, the physics objects are free to be altered once more. I need some way to remember the target, selector and object paramater of this block for later use. One option would be to use a struct like this:
typedef struct {
id target;
SEL selector;
id object;
} FMCallback;
And store these in an array. Once I've finished my step, I then analyse this array and call performSelector:. Is there a better way around this?
EDIT:
I tried both ways and found blocks to be simpler. I'm using a protocol, so I was unsure how to handle this (it would always return a nil NSMethodSignature):
NSMethodSignature *sig = [FMObject instanceMethodSignatureForSelector:@selector(collideWith:)];
NSInvocation *invoc = [NSInvocation invocationWithMethodSignature:sig];
invoc.target = objectB;
invoc.selector = @selector(collideWith:);
[invoc setArgument:objectA atIndex:2];
[Presenter.physics.callbacks addObject:invoc];
It was also longer than I would have hoped. The blocks worked fine after some reading:
// In the collision
[Presenter.physics.callbacks addObject: Block_copy(^{
[(id)objectB collideWith:objectA];
})];
// After the step
for (id collision in callbacks_) {
((dispatch_block_t)collision)();
Block_release(collision);
}
[callbacks_ removeAllObjects];
Perhaps an NSInvocation?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With