c++与lua

lua提供了很多c api是的lua与c可以非常方便的交互然而实际运用的交互是需要使用c++ java objc等语言来与lua交互实现功能,

在cocos 将c++类注册到lua 主要关心将类对象实例化函数注册给lua以及实例对象的函数注册到lua, 将类对象注册为usertype,将函数注册在类module下

DEMO CODE

// 以c编译模式引入tolua++
#ifdef __cplusplus
extern "C" {
#endif
#include "tolua++.h"
#ifdef __cplusplus
}
#endif

TOLUA_API int register_test_binding(lua_State* tolua_S);

// 定义好的c++类以及他的public函数注册给lua
class DrawNode3D: public Node
{
public:

    static DrawNode3D* create();

    void drawLine(const Vec3 &from, const Vec3 &to, const Color4F &color);

    void drawCube(Vec3* vertices, const Color4F &color);

    const BlendFunc& getBlendFunc() const;

    void setBlendFunc(const BlendFunc &blendFunc);

    void onDraw(const Mat4 &transform, uint32_t flags);
};



int lua_cocos2dx_DrawNode3D_getBlendFunc(lua_State* L)
{
    int argc = 0;
    cocos2d::DrawNode3D* cobj = nullptr;
    bool ok  = true;

#if COCOS2D_DEBUG >= 1
    tolua_Error tolua_err;
#endif


#if COCOS2D_DEBUG >= 1
// 校验 drawNode 的usertype是否在栈底
    if (!tolua_isusertype(L,1,"cc.DrawNode3D",0,&tolua_err)) goto tolua_lerror;
#endif
    // 将栈底的userType 转化为 c++的drawNode对象指针
    cobj = (cocos2d::DrawNode3D*)tolua_tousertype(L,1,0);

#if COCOS2D_DEBUG >= 1
    if (!cobj)
    {
        tolua_error(L,"invalid 'cobj' in function 'lua_cocos2dx_DrawNode3D_getBlendFunc'", nullptr);
        return 0;
    }
#endif
    // 获取栈的长度也就是参数长度
    argc = lua_gettop(L)-1;
    if (argc == 0)
    {
        if(!ok)
            return 0;
        // 执行c++函数
        const cocos2d::BlendFunc& ret = cobj->getBlendFunc();
        // 压入栈道lua
        blendfunc_to_luaval(L, ret);
        return 1;
    }
    CCLOG("%s has wrong number of arguments: %d, was expecting %d \n", "cc.DrawNode3D:getBlendFunc",argc, 0);
    return 0;

#if COCOS2D_DEBUG >= 1
tolua_lerror:
    tolua_error(L,"#ferror in function 'lua_cocos2dx_DrawNode3D_getBlendFunc'.",&tolua_err);
#endif

    return 0;
}



int lua_cocos2dx_DrawNode3D_create(lua_State* L)
{
    int argc = 0;
    bool ok  = true;

#if COCOS2D_DEBUG >= 1
    tolua_Error tolua_err;
#endif

#if COCOS2D_DEBUG >= 1
    // 检查栈底类型
    if (!tolua_isusertable(L,1,"cc.DrawNode3D",0,&tolua_err)) goto tolua_lerror;
#endif

    argc = lua_gettop(L) - 1;
    //检查参数数量
    if (argc == 0)
    {
        if(!ok)
            return 0;
        //创建c++对象
        cocos2d::DrawNode3D* ret = cocos2d::DrawNode3D::create();
        //将对象压栈给lua
        object_to_luaval(L, "cc.DrawNode3D",(cocos2d::DrawNode3D*)ret);
        return 1;
    }
    CCLOG("%s has wrong number of arguments: %d, was expecting %d\n ", "cc.DrawNode3D:create",argc, 0);
    return 0;
#if COCOS2D_DEBUG >= 1
tolua_lerror:
    tolua_error(L,"#ferror in function 'lua_cocos2dx_DrawNode3D_create'.",&tolua_err);
#endif
    return 0;
}

int lua_cocos2dx_DrawNode3D_setBlendFunc(lua_State* L)
{
    int argc = 0;
    cocos2d::DrawNode3D* cobj = nullptr;
    bool ok = true;

#if COCOS2D_DEBUG >= 1
    tolua_Error tolua_err;
#endif


#if COCOS2D_DEBUG >= 1
    if (!tolua_isusertype(L,1,"cc.DrawNode3D",0,&tolua_err)) goto tolua_lerror;
#endif
    //获取到lua中的c++对象指针
    cobj = (cocos2d::DrawNode3D*)tolua_tousertype(L,1,0);

#if COCOS2D_DEBUG >= 1
    if (!cobj)
    {
        // 如果对象被释放了会向lua报错
        tolua_error(L,"invalid 'cobj' in function 'lua_cocos2dx_DrawNode3D_setBlendFunc'", nullptr);
        return 0;
    }
#endif
    // 检测参数数量
    argc = lua_gettop(L)-1;
    if (argc == 1)
    {
        cocos2d::BlendFunc arg0;

        ok &= luaval_to_blendfunc(L, 2, &arg0, "cc.Sprite3D:setBlendFunc");
        if(!ok)
        {
            tolua_error(L,"invalid arguments in function 'lua_cocos2dx_DrawNode3D_setBlendFunc'", nullptr);
            return 0;
        }
        // 执行对象函数
        cobj->setBlendFunc(arg0);
        return 0;
    }

    CCLOG("%s has wrong number of arguments: %d, was expecting %d \n", "cc.DrawNode3D:setBlendFunc",argc, 1);
    return 0;

#if COCOS2D_DEBUG >= 1
tolua_lerror:
    tolua_error(L,"#ferror in function 'lua_cocos2dx_DrawNode3D_setBlendFunc'.",&tolua_err);
#endif

    return 0;
}



int lua_register_cocos2dx_DrawNode3D(lua_State* L)
{
    // 创建cc.DrawNode3D lua userType
    tolua_usertype(L,"cc.DrawNode3D");
    // 注册为cc在lua的类
    tolua_cclass(L,"DrawNode3D","cc.DrawNode3D","cc.Node",nullptr);
    // 开启drawNode module
    tolua_beginmodule(L,"DrawNode3D");
    //依次想drawNode 添加成员函数
    tolua_function(L,"getBlendFunc",lua_cocos2dx_DrawNode3D_getBlendFunc);
    tolua_function(L,"setBlendFunc",lua_cocos2dx_DrawNode3D_setBlendFunc01);
    tolua_function(L,"drawLine",lua_cocos2dx_DrawNode3D_drawLine);
    tolua_function(L,"clear",lua_cocos2dx_DrawNode3D_clear);
    tolua_function(L,"drawCube",lua_cocos2dx_DrawNode3D_drawCube);
    tolua_function(L,"create", lua_cocos2dx_DrawNode3D_create);
    // 关闭drawNode module
    tolua_endmodule(L);
    std::string typeName = typeid(cocos2d::DrawNode3D).name();
    g_luaType[typeName] = "cc.DrawNode3D";
    g_typeCast["DrawNode3D"] = "cc.DrawNode3D";
    return 1;
}





int register_test_binding(lua_State* L)
{
    //开lua栈 
    tolua_open(L);
    //开启cc module 如果存在则不会创建拿旧的
    tolua_module(L, "cc", 0);
    // 开始module下的成员添加
    tolua_beginmodule(L, "cc");
    // 注册drawNode
    lua_register_cocos2dx_DrawNode3D(L);
    // module成员添加
    tolua_endmodule(L);
    return 0;
}

你可能感兴趣的:(lua,lua,c语言)