zoukankan      html  css  js  c++  java
  • cocos2dx-Lua与Object的通讯机制

    本文转载于:http://blog.csdn.net/liangliang103377/article/details/43269693

               CCLuaObjcBridge - Lua 与 Objective-C 互操作的简单解决方案

    月初的时候,发了一篇关于 Lua 与 Java 互操作的文章,里面提到了我创建的 LuaJavaBridge 工具。现在,最新的 Lua 与 Objective-C 互操作工具也出来了。因为是专门针对 cocos2d-x 的,所以命名为 CCLuaObjcBridge。

    PS: 以前的 LuaJavaBridge 也会改名为 CCLuaJavaBridge,并且参考现在 CCLuaObjcBridge 的实现,做了不少改进,完成后也会发布。

    CCLuaObjcBridge(后文简称 luaoc)的功能就是从 Lua 里直接掉用“任意 Objective-C 类方法”。利用这个特性,封装各种 iOS 上的库简直碉堡了,堪称 cocos2d-x Lua 游戏开发的神器 ^_^

    luaoc 的主要特征

    • 可以从 Lua 调用 Objective-C Class Method
    • 调用 Objective-C 方法时,支持 int/float/boolean/String/Lua function/Lua table 六种参数类型
    • 可以将 Lua function 作为参数传递给 Objective-C,并让 Objective-C 保存 Lua function 的引用
    • 可以从 Objective-C 调用 Lua 的全局函数,或者调用引用指向的 Lua function

    主要功能和 luaj 是一样的,但相比老版本 luaj 做了一些针对 Objective-C 的调整。

    luaoc 用法示例

    下面的代码演示了如何调用 91 SDK:

    Lua 代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    -- 注册回调函数,在玩家离开 91 平台界面时显示一个消息
    -- PS: 91 SDK 的支付接口不会直接返回状态给客户端,支付需要在服务端验证
    local function callback(event)
        if event == "SDKNDCOM_LEAVE_PLATFORM" then
            print("充值正在进行中,稍候您就能收到金币啦")
        end
    end
    
    luaoc.callStaticMethod("SDKNdCom", "registerScriptHandler", {listener = callback})
    
    -- 进入 91 的支付接口
    local args = {
        orderId = "order-00001001001",
        coins = 1000,
    }
    local ok, ret = luaoc.callStaticMethod("SDKNdCom", "payForCoins", args)
    if not ok then
        print(string.format("SDKNdCom.payForCoins() - call API failure, error code: %s", tostring(ret)))
    end
    

    下面代码是 Objective-C 写的中间层,用来沟通 91 SDK 和 Lua 代码。

    Objective-C 代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    
    + (NSDictionary *) payForCoins:(NSDictionary *)dict
    {
        NSString *orderId = [dict objectForKey:@"orderId"];
        if (!orderId || [orderId length] == 0)
        {
            CFUUIDRef theUUID = CFUUIDCreate(NULL);
            CFStringRef string = CFUUIDCreateString(NULL, theUUID);
            CFRelease(theUUID);
            orderId = [(NSString *)string autorelease];
        }
    
        int coins = 0;
        if ([dict objectForKey:@"coins"])
        {
            coins = [[dict objectForKey:@"coins"] intValue];
        }
    
        NSString *description = [dict objectForKey:@"description"];
        if (!description)
        {
            description = @"";
        }
    
        int ret = [[NdComPlatform defaultPlatform] NdUniPayForCoin:orderId
                                                      needPayCoins:coins
                                                    payDescription:description];
    
        return [NSDictionary dictionaryWithObjectsAndKeys:orderId, @"orderId",
                [NSNumber numberWithInt:ret], @"error", nil];
    }
    

    由于无法直接获取 Objective-C 方法的参数个数和类型,所以如果要从 Objective-C 方法里接收 Lua 传递的参数,那么只能以 NSDictionary 的形式。

    上述代码中,Lua 端传递了一个包含 orderId 和 coins 的表格作为参数。这个表格会被 luaoc 自动转换为 NSDictionary 对象,并传入 payForCoins:(NSDictionary*) 方法。

    不过从 Objective-C 返回值给 Lua 时,就可以返回各种类型的值。目前支持的值类型有 int/float/BOOL/NSString/NSDictionary。特别是可以返回 NSDictionary 类型后,Lua 代码从 Objective-C 端获取数据就简单很多了。

    从 Objective-C 调用 Lua

    由于 CCLuaObjcBridge 已经集成到quick-cocos2d-x(一个基于 cocos2d-x 的 Lua 游戏引擎)中,所以从 Objective-C 调用 Lua 也更简单灵活:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    // functionId 是 Lua function 的引用 ID,参考 LuaJavaBridge 文章中的描述
    
    // 1. 将引用 ID 对应的 Lua function 放入 Lua stack
    CCLuaObjcBridge::pushLuaFunctionById(functionId);
    
    // 2. 将需要传递给 Lua function 的参数放入 Lua stack
    CCLuaValueDict item;
    item["title"] = CCLuaValue::stringValue("hello");
    item["coins"] = CCLuaValue::intValue(1000);
    item["success"] = CCLuaValue::booleanValue(TRUE);
    CCLuaObjcBridge::getStack()->pushCCLuaValueDict(item);
    
    // 3. 执行 Lua function
    CCLuaObjcBridge::getStack()->executeFunction(1);
    
    // 4. 释放引用 ID
    CCLuaObjcBridge::releaseLuaFunctionById(callbackId);
    

    CCLuaObjcBridge::getStack() 会返回一个 CCLuaStack 对象的指针。

    CCLuaStack 是 quick-cocos2d-x 引入的新对象,封装了 Lua stack 的一些常用操作。例如要将值放入 Lua stack 就提供了下列方法,支持各种数据类型:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    void pushInt(int intValue);
    void pushFloat(float floatValue);
    void pushBoolean(bool boolValue);
    void pushString(const char* stringValue);
    void pushString(const char* stringValue, int length);
    void pushNil(void);
    void pushCCObject(CCObject* objectValue, const char* typeName);
    void pushCCLuaValue(const CCLuaValue& value);
    void pushCCLuaValueDict(const CCLuaValueDict& dict);
    void pushCCLuaValueArray(const CCLuaValueArray& array);
    

    相比 LuaJavaBridge,CCLuaObjcBridge 更容易使用、传递数据也更方便。以后 LuaJavaBridge 也会更名为 CCLuaJavaBridge,并使用相同的值传递机制。

    OC直接调用lua全局方法:

        cocos2d::CCLuaEngine::defaultEngine()->executeGlobalFunction("luaGlobalfunctionOnPause");

  • 相关阅读:
    在IE和Firfox获取keycode
    using global variable in android extends application
    using Broadcast Receivers to listen outgoing call in android note
    help me!virtual keyboard issue
    using iscroll.js and iscroll jquery plugin in android webview to scroll div and ajax load data.
    javascript:jquery.history.js使用方法
    【CSS核心概念】弹性盒子布局
    【Canvas学习笔记】基础篇(二)
    【JS核心概念】数据类型以及判断方法
    【问题记录】ElementUI上传组件使用beforeupload钩子校验失败时的问题处理
  • 原文地址:https://www.cnblogs.com/guangyun/p/5020201.html
Copyright © 2011-2022 走看看