c++回调lua函数,实现事件
基于上一篇文章
上一篇主要是因为不能调用lua函数 才那样解决,但是本篇能调用lua函数,那么目的实现也就简单多了
归其原因还是tolua 工具生成的hpp cpp文件的函数不对 虽然在c++中函数参数声明为LUA_FUNCTION 但是还是被当做了int处理
所以我们要手动处理函数的调用 也就是修改生成的 函数
... 生成的对应 代码 改为以下 if (NULL == tolua_S) return 0; int argc = 0; NetMgr* self = nullptr; #if COCOS2D_DEBUG >= 1 tolua_Error tolua_err; if (!tolua_isusertype(tolua_S, 1, "cc.Http", 0, &tolua_err)) goto tolua_lerror; #endif self = static_cast<NetMgr*>(tolua_tousertype(tolua_S, 1, 0)); #if COCOS2D_DEBUG >= 1 if (nullptr == self) { tolua_error(tolua_S, "invalid 'self' in function 'tolua_cocos2d_Node_registerScriptHandler'\n", NULL); return 0; } #endif argc = lua_gettop(tolua_S) - 1; if (argc == 1) { #if COCOS2D_DEBUG >= 1 if (!toluafix_isfunction(tolua_S, 2, "LUA_FUNCTION", 0, &tolua_err)) goto tolua_lerror; #endif LUA_FUNCTION handler = toluafix_ref_function(tolua_S, 2, 0); self->setLuaFunc(handler); lua_settop(tolua_S, 1); return 0; } luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d\n", "cc.Node:registerScriptHandler", argc, 1); return 0; #if COCOS2D_DEBUG >= 1 tolua_lerror: tolua_error(tolua_S, "#ferror in function 'tolua_cocos2d_Node_registerScriptHandler'.", &tolua_err); return 0; #endif
头文件改为
class toLuaFunc/*base class for to call lun function*/ { public: void setLuaFunc(LUA_FUNCTION handler); protected: void callLuaFunc(const char*ARG); LUA_FUNCTION handler; }; #define URL_BASE "http://127.0.0.1:8080/cocos/" #define DATA_MAX_LENGTH 100 class NetMgr :public toLuaFunc { public: static NetMgr*getInstance(); /** * @brief new a HttpRequest * @param action such as "login?name=1&&pass=1" * @ */ void getRequest(const char* action); private: NetMgr(){} char _data[DATA_MAX_LENGTH]; };
cpp文件改为
#include "network_srv.h" #include "CCLuaEngine.h" #include "base/CCScriptSupport.h" void toLuaFunc::setLuaFunc(LUA_FUNCTION handler) { this->handler = handler; } void toLuaFunc::callLuaFunc(const char*ARG) { CC_ASSERT(handler > 0, "call lua func 's handle must bigger than 0"); cocos2d::CommonScriptData data(handler, ARG); cocos2d::ScriptEvent scriptEvent(cocos2d::kCommonEvent, &data); cocos2d::LuaEngine::getInstance()->sendEvent(&scriptEvent); } void NetMgr::getRequest(const char* action) { log("c++ getRequest arg is %s",action); string url = URL_BASE; url += action; HttpRequest*request = new HttpRequest; request->setUrl(url.c_str()); request->setRequestType(HttpRequest::Type::GET); request->setResponseCallback([=](HttpClient*client, HttpResponse *respone) { if (respone->getResponseCode() != 200)return; vector<char>* buffer = respone->getResponseData(); CC_ASSERT(DATA_MAX_LENGTH > buffer->size(), " NetMgr buffer size overfloaw"); for (int i = 0; i < buffer->size(); i++) { _data[i] = (*buffer)[i]; } _data[buffer->size()] = '\0'; callLuaFunc(_data); }); HttpClient::getInstance()->setTimeoutForConnect(10); HttpClient::getInstance()->send(request); request->release(); } NetMgr* NetMgr::getInstance() { static NetMgr* _netmgr__ = 0; if (_netmgr__ == 0) { _netmgr__ = new NetMgr; } return _netmgr__; }
lua文件
local function menuCallbackClose() http:getRequest("login?name=1&&pass=1") return end label=cc.LabelTTF:create("login","",35) label:setPosition(self.size.width/2,self.size.height/2); rootNode:addChild(label) local menuToolsItem = rootNode:getChildByName("Button_1") menuToolsItem:addTouchEventListener(menuCallbackClose) local function callback(msg) label:setString(msg); end http=NetMgr:getInstance(); http:setLuaFunc(callback);
其中cpp文件的还可以改为这样
void toLuaFunc::callLuaFunc(const char*ARG) { CC_ASSERT(handler > 0, "call lua func 's handle must bigger than 0"); /* cocos2d::CommonScriptData data(handler, ARG); cocos2d::ScriptEvent scriptEvent(cocos2d::kCommonEvent, &data); cocos2d::LuaEngine::getInstance()->sendEvent(&scriptEvent); */ cocos2d::LuaEngine::getInstance()->getLuaStack()->pushString(ARG); cocos2d::LuaEngine::getInstance()->getLuaStack()->executeFunctionByHandler(handler, 1); cocos2d::LuaEngine::getInstance()->getLuaStack()->clean(); }