Lua 脚本载入简述和运行时脚本刷新

1.脚本载入上,loadfile、dofile、require是比较常用的,具体区别网上有些博文已经写的很好了,如岁月_无恒的http://blog.csdn.net/leecrest/article/details/31742419 和蓝色雪狐的http://blog.163.com/hbu_lijian/blog/static/126129153201422902256778/。这里简单概括:

(1)loadfile编译代码成中间码并且返回编译后的chunk作为一个函数,而不执行代码。一次编译的返回结果可以多次被运行。

(2)dofile读入代码文件并编译执行。每调用dofile一次,都会重新编译执行一次。

(3)require比较接近dofile,但require会先在package.loaded中查找此模块是否存在,会判断文件是否已经加载避免重复加载同一文件。目前项目主要都是用require。

 

2.由于项目中未开发出UI编辑器,所以用Lua开发界面时经常为了校正一个控件位置不断地重新打开游戏查看效果,工作效率很受影响。为了提高开发效率,就写了一些代码让lua脚本在不关闭游戏情况下去实时热更脚本,保证程序猿能在修改lua文件后,立即在游戏里看到效果。大致的机制如下:

(1)监控键盘中特定按键的按下事件,在监听到按键按下后开始进行刷新脚本的操作

(2)由于整个UI界面都是Lua开发,所以不可能去刷新全部UI界面,一般来说保持地图块、人物模型等基础界面不变,去刷新用户打开的窗口就足够了。因此首先先获取当前屏幕中展现的窗口视图类。(一个好的UI框架应该能实时监控到用户当前打开了几个窗口,左、右、中间分别是什么窗口类)

(3)根据当前窗口类,从预先建立好的“窗口类---文件列表目录”映射table中拿到这个窗口类所对应的多个lua文件的相对路径(一个窗口类可能由多个lua文件构成,所以映射的文件路径可能有多个)。

(4)对拿到的脚本文件路径进行重载,如下所示:

 

local function require_ex( file_path )
	package.loaded[file_path] = nil    -- 消除载入记录
	require( file_path )                      -- 重新加载lua文件
end

 

(5)这个时候虽然脚本文件已经重新载入了,但是目前内存中保留的还是旧文件的内容,所以还要清除内存中所有对旧文件内容的引用并创建新文件内容的引用。也就是说要销毁当前展示的窗口,并将所有持有当前打开窗口的引用的变量置空。然后创建新的窗口类对象,赋值给所有之前持有当前打开窗口的引用的变量。并重新展示窗口。

如此一来,程序猿即可在修改完lua文件、按下特定按键后看见自己的窗口重新绘制的效果了。

 

3.运行时脚本刷新除了运用在开发调试过程,在玩家客户端热更代码后应该也会有这个流程。“据说”是在一个lua脚本文件A.lua中进行全局文件的重新加载,然后重新加载A.lua。其中要注意避免让一个lua文件刷新自己,这样是不能成功刷新的。具体的流程因为没接触过这方面工作,所以目前只能等待以后补充

 

原文地址:https://www.cnblogs.com/mzdbskipop/p/3966148.html