您的位置:首页 > 移动开发 > Cocos引擎

quick-cocos2d-x的热更新机制实现<三>Updater(C++)

2015-05-18 14:37 741 查看
原文地址:http://www.cocoachina.com/bbs/read.php?tid=213061

3 Updater(C++)

AssetsManager 中提供了下载资源,访问更新列表,解压zip包,删除临时文件,设置搜索路径等等一系列的功能。但它的使用方式相当死板,我只能传递一个获取版本号的地址,一个zip包的地址,一个临时文件夹路径,然后就干等着。期间啥也干不了。

当然,我可以通过 quick 为其增加的 registerScriptHandler 方法让lua得知下载进度和网络状态等等。但下载进度的数字居然以事件名的方式通过字符串传过来的!这个就太匪夷所思了点。

于是,我对这个 AssetsManager 进行了修改。因为修改的东西实在太多,改完后就不好意思再叫这个名字了(其实主要是现在的名字比较短 XD)。我们只需要记住这个 Updater 是使用 AssetsManager
修改的即可。

在上面SunLightJuly和Henry同学的方法中,使用的是 CCHTTPRequest 来获取网络资源的。CCHTTPRequest 封装了cURL 操作。而在 Updater 中,是直接封装的 cURL
操作。

在我的设计中,逻辑应该尽量放在lua中,C++部分只提供功能供lua调用。因为lua可以进行热更新,而C++部分则只能整包更新。

Updater 主要实现的内容如下:

3.1 删除了不需要的方法

get和set相关的一堆方法都被删除了。new对象的时候也不必传递参数了。

3.2 增加 getUpdateInfo 方法

这个方法通过HTTP协议获取升级列表数据,获取到的数据直接返回,C++并不做处理。

3.3 修改 update 方法

这个方法通过HTTP协议下载升级包,需要提供四个参数:

zip文件的url;
zip文件的保存位置;
zip 文件的解压临时目录;
解压之前是否需要清空临时目录。

3.4 修改事件类型

我把把传递给lua的事件分成了四种类型:

3.4.1 UPDATER_MESSAGE_UPDATE_SUCCEED

事件名为 success,代表更新成功,zip文件下载并解压完毕;

3.4.2 UPDATER_MESSAGE_STATE

事件名为 state,更新过程中的状态(下载开始、结束,解压开始、结束)也传递给了lua。这个方法是这样实现的:

复制代码

void Updater::Helper::handlerState(Message *msg)

{

StateMessage* stateMsg = (StateMessage*)msg->obj;

if(stateMsg->manager->_delegate)

{

stateMsg->manager->_delegate->onState(stateMsg->code);

}

if (stateMsg->manager->_scriptHandler)

{

std::string stateMessage;

switch ((StateCode)stateMsg->code)

{

case kDownStart:

stateMessage = "downloadStart";

break;

case kDownDone:

stateMessage = "downloadDone";

break;

case kUncompressStart:

stateMessage = "uncompressStart";

break;

case kUncompressDone:

stateMessage = "uncompressDone";

break;

default:

stateMessage = "stateUnknown";

}

CCScriptEngineManager::sharedManager()

->getScriptEngine()

->executeEvent(

stateMsg->manager->_scriptHandler,

"state",

CCString::create(stateMessage.c_str()),

"CCString");

}

delete ((StateMessage*)msg->obj);

}

3.4.3 UPDATER_MESSAGE_PROGRESS

事件名为 progress,传递的对象为一个 CCInteger ,代表进度。详细的实现可以看 源码

3.4.4 UPDATER_MESSAGE_ERROR

事件名为 error,传递的对象是一个 CCString,值有这样几个:

errorCreateFile
errorNetwork
errorNoNewVersion
errorUncompress
errorUnknown

方法的实现和上面的 UPDATER_MESSAGE_STATE 类似,这里就不贴了。详细的实现可以看 源码

Updater(C++) 部分只做了这些苦力工作,而具体的分析逻辑(分析getUserInfo返回的数据决定是否升级、如何升级和升级什么),下载命令的发出(调用update方法),解压成功之后的操作(比如合并新文件到就文件中,更新文件索引列表等等),全部需要lua来做。下面是一个处理Updater(C++)事件的lua函数的例子。

复制代码

function us._updateHandler(event, value)

updater.state = event

if event == "success" then

updater.stateValue = value:getCString()

-- 成功之后更新资源列表,合并新资源

updater.updateFinalResInfo()

-- 调用成功后的处理函数

if us._succHandler then

us._succHandler()

end

elseif event == "error" then

updater.stateValue = value:getCString()

elseif event == "progress" then

updater.stateValue = tostring(value:getValue())

elseif event == "state" then

updater.stateValue = value:getCString()

end

-- us._label 是一个CCLabelTTF,用来显示进度和状态

us._label:setString(updater.stateValue)

assert(event ~= "error",

string.format("Update error: %s !", updater.stateValue))

end

updater:registerScriptHandler(us._updateHandler)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: