c++回调lua函数,实现事件

梦想游戏人
目录:
Cocos2dx

基于上一篇文章 

cocos2dx 导出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();



}
Scroll Up