这个系列我们主要学习Cocos2d-x Lua,总结Lua开发过程中所涉及的知识点,以及在开发过程中如何使用Cocos Code IDE。这一篇讲解HTTP工具类封装
实现
该工具类对Cocos2d-x中的HttpClient进行了封装,使可以在Lua中实现http异步请求。
LuaHttpClient.h
#ifndef __LUAHTTPCLIENT_H__ #define __LUAHTTPCLIENT_H__ #include "cocos2d.h" USING_NS_CC; #include "cocos-ext.h" USING_NS_CC_EXT; // 参数封装类 class LuaParams{ public: static LuaParams* create(){ LuaParams* params = new LuaParams(); // 参数在回调后释放 params->setTypeName("nil"); return params; }; static LuaParams* create(const char* url, int func, const char* data, CCObject* obj , const char* typeName = "nil"){ LuaParams* params = new LuaParams(); params->setData(data); params->setUrl(url); params->setFunc(func); params->setCCObjct(obj); params->setTypeName(typeName); return params; }; void setFunc(int func_){ func = func_; }; int getFunc(){ return func; }; void setCCObjct(CCObject* obj_){ obj = obj_; }; CCObject* getCCObjct(){ return obj; }; void setTypeName(const char* typeName_){ typeName = typeName_; }; const char* getTypeName(){ return typeName; }; void setUrl(const char* url_){ url = url_; }; const char* getUrl(){ return url; }; void setData(const char* data_){ data = data_; }; const char* getData(){ return data; }; private: /** POST请求数据 **/ const char* data; /** 请求地址 **/ const char* url; /** Lua回调方法 **/ int func; /** 用户数据 **/ CCObject* obj; /** 用户数据类型名称 **/ const char* typeName; }; // Lua异步http请求工具类 class LuaHttpClient:public CCObject{ public: // 单例 static LuaHttpClient* getInstance(); // 异步Get请求 void asynGet(LuaParams* params); // 异步Post请求 void asynPost(LuaParams* params); // 回调函数 void callback(CCHttpClient *sender, CCHttpResponse *response); }; #endif
LuaHttpClient.cpp
#include "LuaHttpClient.h" #include "../cocos2dx_support/CCLuaEngine.h" static LuaHttpClient* s_instance = NULL; LuaHttpClient* LuaHttpClient::getInstance(){ if (s_instance == NULL) { s_instance = new LuaHttpClient(); s_instance->autorelease(); } return s_instance; } void LuaHttpClient::asynGet(LuaParams* params){ CCHttpRequest* request = new CCHttpRequest(); request->setUrl(params->getUrl()); request->setRequestType(CCHttpRequest::kHttpGet); request->setResponseCallback(this, httpresponse_selector(LuaHttpClient::callback)); request->setUserData((void*)params); CCHttpClient::getInstance()->send(request); if (params->getTypeName() != "nil") { params->getCCObjct()->retain(); //引用计数+1 } } void LuaHttpClient::asynPost(LuaParams* params){ CCHttpRequest* request = new CCHttpRequest(); request->setUrl(params->getUrl()); request->setRequestType(CCHttpRequest::kHttpPost); request->setResponseCallback(this, httpresponse_selector(LuaHttpClient::callback)); request->setUserData((void*)params); // write the post data request->setRequestData(params->getData(), strlen(params->getData())); CCHttpClient::getInstance()->send(request); request->release(); if (params->getTypeName() != "nil") { params->getCCObjct()->retain(); //引用计数+1 } } void LuaHttpClient::callback(CCHttpClient *sender, CCHttpResponse *response){ if (!response) { return; } int statusCode = response->getResponseCode(); char statusString[64] = {}; sprintf(statusString, "HTTP Status Code: %d, tag = %s", statusCode, response->getHttpRequest()->getTag()); CCLog("response code: %d", statusCode); // 回调Lua函数 LuaParams* params = (LuaParams*)response->getHttpRequest()->getUserData(); if (!response->isSucceed()) { CCLog("response failed"); CCLog("error buffer: %s", response->getErrorBuffer()); // 释放内存 if (params->getTypeName() != "nil") { params->getCCObjct()->release(); //引用计数-1 } delete params; return; } // dump data std::vector<char> *buffer = response->getResponseData(); std::string data (buffer->begin(),buffer->end()); CCLOG("request success"); CCLuaStack* pStack = CCLuaEngine::defaultEngine()->getLuaStack(); pStack->pushString(data.c_str()); //把服务器回应的数据添加到函数参数1 //if (params->getCCObjct() && params->getTypeName()) //这个判断不知道为什么有一定随机性 if (params->getTypeName() != "nil") { // 如果传递了CCObject,把它作为第二个参数 pStack->pushCCObject(params->getCCObjct(),params->getTypeName()); pStack->executeFunctionByHandler(params->getFunc(),2); pStack->clean(); params->getCCObjct()->release(); //引用计数-1 }else{ //第一个参数是函数的整数句柄,第二个参数是函数参数个数 pStack->executeFunctionByHandler(params->getFunc(),1); pStack->clean(); } delete params; }
绑定到Lua
工程下载:http://upyun.cocimg.com/cocos/Cocos2d-x_LuaHttpClient-master.zip
该工程使用Cocos2d-x-2.2.6和vs2012,把工程放到引擎projects目录下即可:
1. 把“绑定自定义类到lua”目录下的ext文件夹放到cocos2d-x-2.2.6\scripting\lua目录下
2. 其它文件放到cocos2d-x-2.2.6\tools\tolua++目录下,点击build_ext.bat生成绑定文件
3. 把LuaExt.h和LuaExt.cpp放到cocos2d-x-2.2.6\scripting\lua\cocos2dx_support下
4. 修改CCLuaStack.cpp,在init方法下调用tolua_Ext_open方法注册自定义C++类
#include "LuaExt.h" //包含头文件 m_state = lua_open(); luaL_openlibs(m_state); tolua_Cocos2d_open(m_state); tolua_Ext_open(m_state); //注册自定义类 toluafix_open(m_state);
5.在项目中引入文件
点击查看:绑定C++自定义类到Lua
调用示例
在Lua中调用的示例代码
-- 在主线程中创建一个CCLayer local layer2 = CCLayerColor:create(ccc4(200,0,0,200)) -- 回调函数(参数1:服务返回的数据,参数2:用户数据(CCObject)) local callback = function(responseData, userdata) cclog("lua response data : %s",responseData) -- 替换场景 local scene = CCScene:create() scene:addChild(userdata) -- 添加主线程中创建的CCLayer到场景 CCDirector:sharedDirector():replaceScene(scene) end -- 1.异步http get请求并,传递一个CCObject local params = LuaParams:create("http://www.baidu.com",callback,"",layer2,"CCLayer") -- 2.异步http get请求 -- local params = LuaParams:create() -- params:setUrl("http://www.baidu.com") -- params:setFunc(callback) pClient:getInstance():asynGet(params) --发起请求