当前位置: 首页 > 工具软件 > tolua++ > 使用案例 >

tolua 实战

索锐藻
2023-12-01

这个博文我主要用来吐槽cocos2dx的原作者,王欢,还是王什么来着;下面代码不要用;虽然多年之后我还远没达到人家的水平,但其实也就那水平,谁不是过来人;现在人家还是不是继续写程序也不一定;现在的我,以前的我也从来没追求过“极致”,追求的是影响力,但反而影响力也更达不到人家的水平

实际上很多水平一般的程序员写的程序,反而是影响力巨大(这我没在黑Cocos,没在黑Linux)

主要当年写这个博文,在于说,quick的作者比较厉害,可以直接桥接c++;而cocos2dx的原作者就比较一般了(据说一开始直接抄cocos,全部抄过来已经算"厉害",然后后来重构了75%,这个更"厉害")

是的,我又在反讽,虽然隐藏比较深,但我确实想做出反讽的效果

原文:

用的cocos2dx lua的框架

而且是quick lua框架

toLua++的导出函数如何访问Lua Table

有些函数需要向lua返回多个结果,将这些结果存在table中是理所当然的。因为toLua++已经自动生成了函数的wrapper,所以没办法直接将栈顶table返回给Lua。好在toLua预留了lua_Object这个类型,可以代表lua中的任何类型,其实它只是int的typedef罢了,主要是在toLua解析程序时作为标记产生tolua_tovalue调用。在C/C++函数中,需要检查一下栈顶是否为table类型,进行table元素的插入操作,例子函数如下:

void ActorMgr::GetPlayerEntityIDs( lua_Object lua_table )
{
       TEntityListIt tIt ;
       std::list <int> result;

       for(int i = 0; i < ACOTOR_BUCKET_LEN ; ++i)
      {
             for(tIt =mSceneEntities[i].mEntities.begin(); tIt != mSceneEntities[i].mEntities.end( ); ++tIt )
            {
                   TActorPtr tpActor  = tIt->second->mpActor ;
                   if(tpActor ->GetActorType() == LOCAL_PLAYER)
                  {
                         result.push_front(tpActor->GetEntityID());
                  }
                   else if (tpActor-> GetActorType() == REMOTE_PLAYER )
                  {
                         result.push_back(tpActor->GetEntityID());
                  }
            }
      }
       lua_State* L = LuaVM::GetInstPtr()->mLS ;
       assert(lua_istable (L , -1));
       std::list <int>:: iterator iter = result. begin();
       for(int i = 1; iter != result .end(); ++ iter , ++i )
      {
             lua_pushinteger(L , *iter);
             lua_rawseti(L , -2 , i);
      }
       lua_pop(L , 1);
}ActorMgr::GetPlayerEntityIDs( lua_Object lua_table )
{
       TEntityListIt tIt ;
       std::list <int> result;

       for(int i = 0; i < ACOTOR_BUCKET_LEN ; ++i)
      {
             for(tIt =mSceneEntities[i].mEntities.begin(); tIt != mSceneEntities[i].mEntities.end( ); ++tIt )
            {
                   TActorPtr tpActor  = tIt->second->mpActor ;
                   if(tpActor ->GetActorType() == LOCAL_PLAYER)
                  {
                         result.push_front(tpActor->GetEntityID());
                  }
                   else if (tpActor-> GetActorType() == REMOTE_PLAYER )
                  {
                         result.push_back(tpActor->GetEntityID());
                  }
            }
      }
       lua_State* L = LuaVM::GetInstPtr()->mLS ;
       assert(lua_istable (L , -1));
       std::list <int>:: iterator iter = result. begin();
       for(int i = 1; iter != result .end(); ++ iter , ++i )
      {
             lua_pushinteger(L , *iter);
             lua_rawseti(L , -2 , i);
      }
       lua_pop(L , 1);
}

需要注意的是,如果是多个参数,Lua的压栈顺序是object pointer、参数从左到右,所以栈顶元素是函数签名最右边的参数。

lua转c++

bool luaval_to_size(lua_State* L,int lo,Size* outValue, const char* funcName)
{
    if (NULL == L || NULL == outValue)
        return false;
    
    bool ok = true;


    tolua_Error tolua_err;
    if (!tolua_istable(L, lo, 0, &tolua_err) )
    {
#if COCOS2D_DEBUG >=1
        luaval_to_native_err(L,"#ferror:",&tolua_err,funcName);
#endif
        ok = false;
    }
    
    if (ok)
    {
        lua_pushstring(L, "width");  /* L: paramStack key */
        lua_gettable(L,lo);/* L: paramStack paramStack[lo][key] */
        outValue->width = lua_isnil(L,-1) ? 0 : lua_tonumber(L,-1);
        lua_pop(L,1);/* L: paramStack*/
        
        lua_pushstring(L, "height");
        lua_gettable(L,lo);
        outValue->height = lua_isnil(L,-1) ? 0 : lua_tonumber(L,-1);
        lua_pop(L,1);
    }
    
    return ok;
}

关于c++如何绑定lua function

int lua_cocos2dx_EventDispatcher_addCustomEventListener(lua_State* tolua_S)
{
    int argc = 0;
    cocos2d::EventDispatcher* cobj = nullptr;
    bool ok  = true;


#if COCOS2D_DEBUG >= 1
    tolua_Error tolua_err;
#endif




#if COCOS2D_DEBUG >= 1
    if (!tolua_isusertype(tolua_S,1,"cc.EventDispatcher",0,&tolua_err)) goto tolua_lerror;
#endif


    cobj = (cocos2d::EventDispatcher*)tolua_tousertype(tolua_S,1,0);


#if COCOS2D_DEBUG >= 1
    if (!cobj) 
    {
        tolua_error(tolua_S,"invalid 'cobj' in function 'lua_cocos2dx_EventDispatcher_addCustomEventListener'", nullptr);
        return 0;
    }
#endif


    argc = lua_gettop(tolua_S)-1;
    if (argc == 2) 
    {
        std::string arg0;
        std::function<void (cocos2d::EventCustom *)> arg1;


        ok &= luaval_to_std_string(tolua_S, 2,&arg0, "cc.EventDispatcher:addCustomEventListener");


        do {
// Lambda binding for lua is not supported.
assert(false);
} while(0)
;
        if(!ok)
        {
            tolua_error(tolua_S,"invalid arguments in function 'lua_cocos2dx_EventDispatcher_addCustomEventListener'", nullptr);
            return 0;
        }
        cocos2d::EventListenerCustom* ret = cobj->addCustomEventListener(arg0, arg1);
        object_to_luaval<cocos2d::EventListenerCustom>(tolua_S, "cc.EventListenerCustom",(cocos2d::EventListenerCustom*)ret);
        return 1;
    }
    luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "cc.EventDispatcher:addCustomEventListener",argc, 2);
    return 0;


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


    return 0;
}

 类似资料: