cocos2d Lua注册函数到C++回调

来源:互联网 发布:互联网大数据云计算 编辑:程序博客网 时间:2024/06/08 21:26

以tableView为例:

static int lua_cocos2d_TableView_registerScriptHandler(lua_State* L)
{
   //...
        if (!toluafix_isfunction(L,2,"LUA_FUNCTION",0,&tolua_err) ||
            !tolua_isnumber(L, 3, 0, &tolua_err) )
        {
            goto tolua_lerror;
        }
#endif
        LUA_FUNCTION handler = (  toluafix_ref_function(L,2,0));  注册到lua注册表中  LUA_FUNCTION 就是 int  以后lua函数可以通过handler来拿到
        ScriptHandlerMgr::HandlerType handlerType = (ScriptHandlerMgr::HandlerType) ((int)tolua_tonumber(L,3,0) + (int)ScriptHandlerMgr::HandlerType::SCROLLVIEW_SCROLL);
        
将handler加入到脚本处理管理器中去。handler可以通过self和handlerType来拿到
        ScriptHandlerMgr::getInstance()->addObjectHandler((void*)self, handler, handlerType);
//...
}


class LUA_TableViewDataSource:public Ref,public TableViewDataSource
{
public:
    LUA_TableViewDataSource(){}
    virtual ~LUA_TableViewDataSource(){}
    
//这里的size是通过lua函数执行来获取
    virtual Size tableCellSizeForIndex(TableView *table, ssize_t idx) override
    {
        if (nullptr != table )
        {
//获取handler
            int handler = ScriptHandlerMgr::getInstance()->getObjectHandler((void*)table, ScriptHandlerMgr::HandlerType::TABLECELL_SIZE_FOR_INDEX);
            if (0 != handler)
            {
                LuaTableViewEventData eventData(&idx);
                BasicScriptData data(table,&eventData);//对数据进行封装
                float width = 0.0;
                float height = 0.0;
//处理TABLECELL_SIZE_FOR_INDEX事件,lua需要先向脚本管理器中注册TABLECELL_SIZE_FOR_INDEX事件
                LuaEngine::getInstance()->handleEvent(ScriptHandlerMgr::HandlerType::TABLECELL_SIZE_FOR_INDEX, (void*)&data,2,[&](lua_State* L,int numReturn){
//这个回调是在lua的TABLECELL_SIZE_FOR_INDEX处理函数处理完后 执行
                    CCASSERT(numReturn == 2, "tableCellSizeForIndex return count error");
height = (float)tolua_tonumber(L, -1, 0);
                    lua_pop(L, 1);
                    width  = (float)tolua_tonumber(L, -1, 0);
                    lua_pop(L, 1);
//height 和 width是lua处理函数留在栈顶的
                });
                
                return Size(width, height);
            }
        }
        
        return Size::ZERO;
    }
   
};


//LuaStack处理有回调的函数
int LuaStack::executeFunction(int handler, int numArgs, int numResults, const std::function<void(lua_State*,int)>& func)
{
//..
//全局log函数
        lua_getglobal(_state, "__G__TRACKBACK__");                        /* L: ... func arg1 arg2 ... G */
        if (!lua_isfunction(_state, -1))
        {
            lua_pop(_state, 1);                                           /* L: ... func arg1 arg2 ... */
        }
        else
        {
            lua_insert(_state, functionIndex - 1);                         /* L: ... G func arg1 arg2 ... */
            traceCallback = functionIndex - 1;
        }
        
        int error = 0;
        ++_callFromLua;
        error = lua_pcall(_state, numArgs, numResults, traceCallback);     /* L: ... [G] ret1 ret2 ... retResults*/
//traceCallback是错误处理函数,numResults指定返回的参数个数,然后返回值会push到栈顶
        --_callFromLua;
//..
        // get return value,don't pass LUA_MULTRET to numResults,
        do {
            
            if (numResults <= 0 || nullptr == func)
                break;
            
            func(_state, numResults);  //回调执行
            
        } while (0);
//..
}



0 0
原创粉丝点击