[cocos2dx] lua注册回调到c++
思路像所有语言一样,绑定回调主要是执行的任务执行到特定情形的时候,调用对用回调方法。 这里也一样。核心思路是,当c代码执行到特定特定情形的时候,调用lua的方法 主要步骤如下
实现
void ArmatureNode::registerMovementEventHandler(int handler)
{
unregisterMovementEventHandler(); //移除之前注册的监听
_movementHandler = handler; //缓存lua函数的引用 这个后边说
auto dispatcher = getCCEventDispatcher();
auto f = [this](cocos2d::EventCustom *event) //注册c代码形式的回调 这里用function做
{
auto eventData = (dragonBones::EventData*)(event->getUserData());
auto type = (int) eventData->getType();
auto movementId = eventData->animationState->name;
auto lastState = eventData->armature->getAnimation()->getLastAnimationState();
auto stack = cocos2d::LuaEngine::getInstance()->getLuaStack();
stack->pushObject(this,"db.ArmatureNode");
stack->pushInt(type);
stack->pushString(movementId.c_str(),movementId.size());
//通过LuaStack调用lua里的函数 最后一个参数设置参数个数
stack->executeFunctionByHandler(_movementHandler,3);
};
dispatcher->addCustomEventListener(dragonBones::EventData::COMPLETE,f);
}
void ArmatureNode::unregisterMovementEventHandler(void)
{
if (0 != _movementHandler)
{
cocos2d::LuaEngine::getInstance()->removeScriptHandler(_movementHandler); //移除lua函数的绑定
_movementHandler = 0;
}
}
上边的这个函数直接用cocos里的genbinding.py 是无法正确生成lua里可调用的接口的,需要手动编写绑定方法 说这个得用到cocos2dx中提供的一个方法 toluafix_ref_function 会把一个lua栈中的方法转成一个int,以便c++中调用。我会在最后面说这个 int tolua_db_DBCCArmature_registerMovementEventHandler(lua_State* tolua_S)
{
if (NULL == tolua_S)
return 0;
int argc = 0;
dragonBones::ArmatureNode* self = nullptr;
self = static_cast<dragonBones::ArmatureNode*>(tolua_tousertype(tolua_S,255)">1,255)">0)); //第一个参数 就是lua里的self
argc = lua_gettop(tolua_S) - 1;
1 == argc)
{
//第二个参数,就是lua里的function 这里要通过toluafix_ref_function这个函数映射成一个Int值
int handler = (toluafix_ref_function(tolua_S,255)">2,255)">0));
self->registerMovementEventHandler(handler);
0;
}
0;
}
int extends_ArmatureNode(lua_State* tolua_S)
{
lua_pushstring(tolua_S,116)">"db.ArmatureNode");//之前db.ArmatureNode是通过脚本绑定在lua里。这里只做扩展
lua_rawget(tolua_S,LUA_REGISTRYINDEX);
if (lua_istable(tolua_S,-1))
{
lua_pushstring(tolua_S,116)">"registerMovementEventHandler");
lua_pushcfunction(tolua_S,tolua_db_DBCCArmature_registerMovementEventHandler);
lua_rawset(tolua_S,255)">3);
}
lua_pop(tolua_S,255)">1);
-测试 打印回调输出,测试通过 其他
这两个方法是相互对应的 toluafix_ref_function这个方法在注册表上将一个lua的function与一个function_id生成映射 toluafix_get_function_by_refid 方法可以通过前一个方法生成的function_id来讲绑定的lua function放到栈顶 //
TOLUA_API int toluafix_ref_function(lua_State* L,int lo,114)">int def)
{
if (!lua_isfunction(L,lo)) 0;
s_function_ref_id++; //function_id 加1
lua_pushstring(L,TOLUA_REFID_FUNCTION_MAPPING);//在注册表上,存放luafunction 映射table 的key压栈
lua_rawget(L,LUA_REGISTRYINDEX); //获取方法映射表,放在栈顶
lua_pushinteger(L,s_function_ref_id); //function_id压栈
lua_pushvalue(L,lo); //lo有效处索引处是lua方法,lua方法拷贝,压栈
lua_rawset(L,255)">3); //生成映射
lua_pop(L,255)">1);
return s_function_ref_id;
}
TOLUA_API void toluafix_get_function_by_refid(lua_State* L,114)">int refid)
{
lua_pushstring(L,TOLUA_REFID_FUNCTION_MAPPING); //存放luafunction 映射table 的key压栈
lua_rawget(L,LUA_REGISTRYINDEX); //function_id压栈
lua_rawget(L,255)">2); //获取到的luafunction 放到栈顶
lua_remove(L,94)">//
}
疑惑 包括cocos2dx里的所有lua扩展(不是通过脚本直接生成lua接口的)都是通过注册表里扩展的 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |