c++コールバックlua関数、イベントの実装

4826 ワード

前の記事に基づいて
cocos 2 dxはluaの使用のためにc++クラスをエクスポートする
前編は主に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'
", 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
", "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();



}