前言
Lua作为一门优秀的脚本语言,经常被嵌入到其他高级语言的运行环境中;在游戏中因为要做到热更新,用Lua来编写业务逻辑已经是一个非常成熟的方案了。在游戏运行过程中,如果要实时更新指定的lua脚本,只需重新载入该脚本并刷新内存中的缓存模块,就可以让游戏的业务逻辑按最新的版本来执行了。
当调用require时,Lua要分几个步骤在多个地方查找是否存在同名的模块,按优先级进行寻找;在package.searchers这张表中定义了这些步骤及其执行顺序。因此只需将这几个地方的缓存清空后,Lua就会从磁盘中重新去加载最新的文件内容,这样就达到了刷新的目的了。
实现方法
function M:reload(filename)
local old_module
if package.loaded[filename] then
-- 把旧的模块缓存一下
old_module = package.loaded[filename]
-- 然后将package.loaded[filename]置空
package.loaded[filename] = nil
-- 再把package.preload[filename]也置空
package.preload[filename] = nil
end
-- xpcall下执行require
local succ,err = pcall(require, filename)
if not succ then
--热更失败,将旧值赋回去
print("reload fail, err info:",err)
package.loaded[filename] = old_module
return false
end
return true
end
总结
这样就可以将发生变更的脚本更新到内存中,实现了在运行时边走边换轮子。