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。这个方法是这样实现的:
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函数的例子。
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); } |
事件名为 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) |
相关文章推荐
- quick-cocos2d-x的热更新机制实现<一>前言
- quick-cocos2d-x的热更新机制实现<五>对 framework 的修改
- quick-cocos2d-x的热更新机制实现<六>后记
- quick-cocos2d-x的热更新机制实现<二>特色
- quick-cocos2d-x的热更新机制实现<四>update包(lua)(上)
- quick-cocos2d-x的热更新机制实现<四>update包(lua)(中)
- quick-cocos2d-x的热更新机制实现<四>update包(lua)(下)
- cocos2dx 3.x 自学笔记 <三> cocos2dx 2.x 3.x 内存管理机制
- QUICK-COCOS2D-X的热更新机制实现
- quick-cocos2d-x的热更新机制实现
- Quick-Cocos2d-x的热更新机制实现(终极版2)
- [置顶] 从零开始学C++之对象语义与值语义、资源管理(RAII、资源所有权)、模拟实现auto_ptr<class>、实现Ptr_vector .
- <C++ 实现设计模式> 观察者模式
- Cocos2d-x android使用onKeyDown监听返回键实现二次返回退出<转载>
- Quick-Cocos2d-x的热更新机制实现
- quick-cocos2d-x的热更新机制实现
- c++ 头文件<cstring>(或者string.h)中的常见函数的实现!
- c++ 头文件<cwchar>中常见函数的实现!!!
- Android binder 原理及实现机制<一>
- Android实战简易教程<三>(实现简单绘图组件)