tolua 实战

这个博文我主要用来吐槽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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

avi9111

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值