最近为公司的项目做游戏资源的更新功能,既然是游戏资源的更新,自然就包括资源的更新,和lua脚本的更新。更新的功能自然就是,生来md5列表,对比下载。。。@#¥@%#¥……*,各种流程拉。这里主要说一下,lua脚本下载下来之后,如何优先加载下载目录里面的脚本。
cocos2d中,CCLuaStack 是一个与脚本层交互的类,其中的接口并不暴露给lua层。这个类提的addSearchPath接口提供了增加lua搜寻目录的功能,一般的做法是:游戏启动时,直接在C++代码中
bool AppDelegate::applicationDidFinishLaunching()
{
//先脚下载目录中的脚本目录,添加到搜寻列表中
pStack->addSearchPath(project1_download/scripts)
//更把初始包的脚本目录,添加到搜寻列表中
pStack->addSearchPath(origin/scripts)
}
这里,当lua require(xxx)时,lua会先在download/scripts中查找,这样当有新的脚本下载下来之时,就会优先加载了下载目录中的新脚本。而当,download/scripts中打不到时,也就是无新脚本下载下来时,就会加载初始包的初始脚本。这样,可以实现了,下载更新脚本的优先加载。
但是,当公司有多个项目共用一套引挚代码时,代码的编写就会蛋疼了,
项目一的人会写上:pStack->addSearchPath(project1_download/scripts)
项目二的人会写上:pStack->addSearchPath(project2_download/scripts)
不管是用宏定义,还是什么方法,终究是绕不过,要在同一个文件里要做两个脚本加载分支。而用,直接用C++代码强撸,有显低端。
于是,我开始想,就算是CCLuaStack 接口并不暴露给lua层,有没有办法在lua脚本层来实现,增加脚本的搜寻目录呢?
于是,我开始研究,CCLuaStack::addSearchPath的源码:
void CCLuaStack::addSearchPath(const char* path)
{
lua_getglobal(m_state, "package"); /* L: package */
lua_getfield(m_state, -1, "path"); /* get package.path, L: package path */
const char* cur_path = lua_tostring(m_state, -1);
lua_pushfstring(m_state, "%s;%s/?.lua", cur_path, path); /* L: package path newpath */
lua_setfield(m_state, -3, "path"); /* package.path = newpath, L: package path */
lua_pop(m_state, 2); /* L: - */
}
其实,这段源码很简单,不熟悉luaAPI的小伙伴可以遂一谷歌之了。就是把要增加搜寻的path+/?.lua,拼凑在lua的全局表package.path的后端,并与;号分隔。这样就可以给lua require时增加一个脚本搜寻目录了。
对lua加载机制有了解的朋友应该熟翻lua中的pacakge.path,实际在lua语言require时,就是按package.path以“;”号隔开的目录去遂一搜寻。就是这么简单?毛主度说实验是检验真理的唯一标准。于是,我决定听毛主席的话,让实验来证明真理。
我把AppDelegate::applicationDidFinishLaunching中的pStack->addSearchPath(project1_download/scripts)去掉。
而在lua的main文件中加入:
main = function()
local down_path = CCFileUtils:sharedFileUtils():getWritablePath()
local spath = string.format("%s\\download\\script\\?.lua",down_path )
package.path = spath..";"..package.path
.......
end
xpcall(main, __G__TRACKBACK__)
然后,重启游戏,运行!!!果然,不用在C++中调用pStack->addSearchPath,直接给package.path的前端拼接上一个新的搜寻目录后,就可以实现,lua require脚本时,先在docpath/download/script中查找,再在初始包中查找。
那就简单了,就算是多个项目共用一套引挚代码,也只需要每个项目在自己的main.lua脚本入口文件,把要优先搜寻的下载更新目录,往package.path前而拼接就行了。而在C++代码中,跟本不需要在AppDelegate::applicationDidFinishLaunching()中强撸目录了。
到了这里,好像要以打完收工了。其实,还早着呢。这只是在pc端,和ios端可以了。但是,在android端,还不行.
怎么办,在下一篇文章
cocos2d中的脚本加载二:android项目优先加载下载目录中的脚本。中说。
如有转载,还望标明出处:http://www.cnblogs.com/WaterWithAir/p/3568160.html。