Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Objective-C blocks #43

Closed
faxioman opened this issue Aug 13, 2011 · 4 comments
Closed

Support for Objective-C blocks #43

faxioman opened this issue Aug 13, 2011 · 4 comments

Comments

@faxioman
Copy link

Support for Objective-C blocks would be great...
So we could use methods like animateWithDuration:animations:

Bye!

@iamdaiyuan
Copy link

agree,should support for blocks

@mysteriouss
Copy link

I was just wondering how to invoke the 'NSGlobalBlock' if I make it through from Objc to Lua as a parameter. Help!

@probablycorey
Copy link
Owner

I'm not actively maintaining Wax anymore, so I'm not sure if that is possible. But I have a hunch that it is.

@mysteriouss
Copy link

void *wax_copyToObjc(lua_State *L, const char *typeDescription, int stackIndex, int *outsize)
there is a prob. about this function, I think, that stops the NSStackBlock from copying from Lua to Objc.
So I gave up passing blocks into Lua and made a class named 'NSBlockInvacation'.
@interface NSBlockInvocation : NSObject
@Property (nonatomic,copy) void(^block)();
+(NSBlockInvocation *)invocationWithBlock:(void(^)())ablock;
-(void)invoke;
-(void)invoke:(id)anObject;
-(void)invoke:(id)anObject :(id)anotherObject;
@EnD
@implementation NSBlockInvocation
+(NSBlockInvocation *)invocationWithBlock:(void(^)())ablock{
NSBlockInvocation * invo = [[[NSBlockInvocation alloc] init] autorelease];
[invo setBlock:ablock];
return invo;
}
-(void)invoke{
self.block();
}
-(void)invoke:(id)anObject{
self.block(anObject);
}
-(void)invoke:(id)anObject :(id)anotherObject{
self.block(anObject,anotherObject);
}
-(void)dealloc{
[_block release];
[super dealloc];
}
//immobSDK.h
@protocol immobSDK
@optional
+(void)getScore:(NSString *)adunitID :(NSDictionary *)info :(NSBlockInvocation *)handler;
@EnD
@interface immobSDK ()
+(void)getScore:(NSString *)adunitID
accountInfo:(NSDictionary *)info
completionHandler:(void (^)(id result)) handler;
@EnD

//immobSDK.m
@implementation immobSDK
+(void)getScore:(NSString *)adunitID
accountInfo:(NSDictionary *)info
completionHandler:(void (^)(id result)) handler{
if ([self instancesRespondToSelector:@selector(getScore:::)]) {
[self getScore:adunitID:info:[NSBlockInvocation invocationWithBlock:handler]];
}
}
@EnD
--immobSDK.lua
function immobSDK:getScore__(adu,aid,handler)
url = self:QUERYSCORE(adu,aid)
wax.http.request{url, format = "json",callback = function(body,response)
--puts(url)
--puts(body)
if response == nil or body == nil then
handler:invoke(nil)
return
end
if response:statusCode() == 200 then
handler:invoke(body) end
end}
end

_older__no use__see above*_***************************
This is my stupid way for Objc to call the method declared in the Lua code.

typedef void(^completionHandler)(id); //only used for this kind of NSGlobalBlock
int wax_call(id aObserver, SEL aSelector, const char *aName, id aObject,completionHandler handler);

int wax_call(id aObserver, SEL aSelector, const char *aName,id aObject, completionHandler handler){

if ([aObserver respondsToSelector:aSelector]) {
    NSString * name = [NSString stringWithUTF8String:aName];
    [[NSNotificationCenter defaultCenter] addObserver:aObserver selector:aSelector name:name object:nil];
    [[NSNotificationCenter defaultCenter] postNotificationName:name object:aObject];
    [[NSNotificationCenter defaultCenter] removeObserver:aObserver name:name object:nil];
    if (handler) {
        __block id observer = [[NSNotificationCenter defaultCenter] addObserverForName:name object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
            handler([note object]);
            [[NSNotificationCenter defaultCenter] removeObserver:observer name:name object:nil];
        }];
    }
    return 1;
}
return 0;

}

And the Lua code should post the notification to return.
NSNotificationCenter:defaultCenter() :postNotificationName_object(notification:name(),aObjct);

e.g.

[immobSDK getScore:@"123456" :^(id score) {
NSLog(@"%@",score);
}];

@interface immobSDK : NSObject

+(void)getScore:(NSString *)adunitID :(void (^)(id score)) handler;

@EnD

@implementation immobSDK
+(void)initialize{
wax_start("immobSDK.lua",luaopen_wax_http,nil);
}

+(void)getScore:(NSString *)adunitID :(void (^)(id score)) handler{
wax_call(self, @selector(Score:),FUNCTION,adunitID,handler);
}
@EnD

immobSDK.lua

function immobSDK:Score(adunitID)
--puts(adunitID:object())
wax.http.request{"http://www.google.com", callback = function(body,response)
if response:statusCode() == 200 then
NSNotificationCenter:defaultCenter()
:postNotificationName_object(adunitID:name(),200);
end
end}
end

Better ideas? Thank U

I've tried the NSStackBlock,and it cannnot be forced to NSGlobalBlock,otherwise there will be a crash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants