With Cocos2D V3 after action has completed on a sprite I need to update data contained in a structure. How can I pass a data structure address to a selector that executes after my sprite action has completed? Any help much appreciated.
Cocos2D V3 does not have CCCallFuncND How pass structure address to selector?
2.1k views Asked by Greg Developer At
2
There are 2 answers
0
On
Although i suggest to move on and use blocks, Here is my ARC friendly version of CCActionCallFuncND. Works with many kinds of data, including primitives, and any objective C class, at most NSArray's and such... Any comment to improve it to be even better is wellcome!
// CCActionCallFuncND.h
#import "CCActionInstant.h"
typedef void (*CC_CALLBACK_ND)(id, SEL, id, void *);
@interface CCActionCallFuncND : CCActionCallFunc<NSCopying>
+(id) actionWithTarget:(id)t selector:(SEL)s data:(void*)d;
-(id) initWithTarget:(id)t selector:(SEL)s data:(void*)d;
@end
// CCActionCallFuncND.m
#import <malloc/malloc.h>
#import "CCActionCallFuncND.h"
#import <objc/runtime.h>
@interface CCActionCallFuncND ()
@property(strong, nonatomic, readwrite)id myObject;
@property(strong, nonatomic, readwrite)NSValue *myValue;
@property(nonatomic, readwrite)CC_CALLBACK_ND callbackND;
@end
@implementation CCActionCallFuncND
+(id)actionWithTarget:(id)t selector:(SEL)s data:(void*)d
{
return [[self alloc] initWithTarget:t selector:s data:d];
}
-(id)initWithTarget:(id)t selector:(SEL)s data:(void*)d
{
if((self=[super initWithTarget:t selector:s]))
{
self.myValue=[NSValue valueWithPointer:d];
self.myObject=nil;
bool bIsOfClass=false;
int classesNumber=objc_getClassList(NULL, 0);
Class *classesList = (Class*)malloc(classesNumber*sizeof(Class));
classesNumber = objc_getClassList(classesList, classesNumber);
for(int i=0; i<classesNumber; i++)
{
if(classesList[i]==*((Class *)d))
{
bIsOfClass=true;
break;
}
}
free(classesList);
if(bIsOfClass)
{
self.myValue=nil;
self.myObject=(__bridge id)d;
}
self.callbackND=(CC_CALLBACK_ND)[t methodForSelector:s];
}
return self;
}
-(id)copyWithZone:(NSZone*)zone
{
CCActionInstant *copy = [[[self class] allocWithZone: zone]
initWithTarget:_targetCallback selector:_selector data:[self.myValue pointerValue]];
return copy;
}
-(void)execute
{
void *dat=self.myValue?(void*)[self.myValue pointerValue]:(__bridge void*)self.myObject;
self.callbackND(_targetCallback, _selector, _target, dat);
}
@end
You would use a
CCActionCallBlockor aCCActionCallFunc. Whichever is appropriate for your use case.Here is an code example of a block being called after a move to action.
And here is an example using a
CCActionCallFuncthat executes a selector after the move action.