Cocos2d-x Lua registered callback to C++

monitor

_movementHandler = handler; //Cache the reference of the lua function

auto dispatcher = getCCEventDispatcher();

auto f = [this](cocos2d::EventCustom *event) //Register the callback in the form of c code here with 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());

//Call the function in lua through LuaStack The last parameter sets the number of parameters

stack->executeFunctionByHandler(_movementHandler, 3);

};

dispatcher->addCustomEventListener(dragonBones::EventData::COMPLETE, f);

}

void ArmatureNode::unregisterMovementEventHandler(void)

{

if (0 != _movementHandler)

{

cocos2d::LuaEngine::getInstance()->removeScriptHandler(_movementHandler); //Remove the binding of lua function

_movementHandler = 0;

}

}

Provide a way to bind Lua functions to C

The above function directly uses the genbinding.py in cocos to generate the callable interface in Lua. It is necessary to manually write the binding method.

Said this has to use a method provided in Cocos2d-x: toluafix_ref_function will convert a method in the Lua stack into an int for calling in C++. I will say this at the end

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(tolua_tousertype(tolua_S,1,0)); //The first parameter is self in lua

argc = lua_gettop(tolua_S) – 1;

if (1 == argc)

{

//The second parameter is the function in Lua, which needs to be mapped to an Int value through toluafix_ref_function

int handler = (toluafix_ref_function(tolua_S,2,0));

self->registerMovementEventHandler(handler);

return 0;

}

return 0;

}

Bind the binding method to the Lua environment

int extends_ArmatureNode(lua_State* tolua_S)

{

lua_pushstring(tolua_S, "db.ArmatureNode");//Before db.ArmatureNode was bound in lua through script. Only expand here

lua_rawget (tolua_S, LUA_REGISTRYINDEX);

if (lua_istable(tolua_S,-1))

{

lua_pushstring(tolua_S,”registerMovementEventHandler”);

lua_pushcfunction(tolua_S,tolua_db_DBCCArmature_registerMovementEventHandler);

lua_rawset (tolua_S, -3);

}

lua_pop (tolua_S, 1);

return 0;

}

Set callback to C++ in Lua

local arm = db.ArmatureNode:create(“Dragon”)

local animation = arm:getAnimation()

animation:gotoAndPlay(“walk”)

arm:registerMovementEventHandler(

function(…)

print(…)

end

)

test

Print the callback output, the test passes userdata 8 walk

other

toluafix_ref_function 以及 toluafix_get_function_by_refid

These two methods are mutually corresponding toluafix_ref_function. This method generates a mapping between a lua function and a function_id on the registry. The toluafix_get_function_by_refid method can use the function_id generated by the previous method to put the bound lua function on the stack.

//

TOLUA_API int toluafix_ref_function(lua_State* L, int lo, int def)

{

if (!lua_isfunction(L, lo)) return 0;

s_function_ref_id++;                            //function_id 加1

lua_pushstring(L, TOLUA_REFID_FUNCTION_MAPPING);//In the registry, store the key of the luafunction mapping table on the stack

lua_rawget(L, LUA_REGISTRYINDEX); //Get the method mapping table and put it on the top of the stack

lua_pushinteger(L, s_function_ref_id);          //function_id压栈

lua_pushvalue(L, lo); //The index where lo is valid is the lua method, the lua method is copied and pushed onto the stack

lua_rawset(L, -3); //Generate mapping

lua_pop (L, 1);

return s_function_ref_id;

}

TOLUA_API void toluafix_get_function_by_refid(lua_State* L, int refid)

{

lua_pushstring(L, TOLUA_REFID_FUNCTION_MAPPING); //store the key of the luafunction mapping table and push the stack

lua_rawget(L, LUA_REGISTRYINDEX); //Get the method mapping table and put it on the top of the stack

lua_pushinteger(L, refid); //function_id pushes the stack

lua_rawget(L, -2); //Put the obtained luafunction on the top of the stack

lua_remove(L, -2);                                          //

}

executeFunctionByHandler

The executeFunctionByHandler method just gets the function through toluafix_get_function_by_refid and then calls it through the lua_pcall method, the code is not written.

Guess you like

Origin blog.csdn.net/qq_21743659/article/details/108616115