一个关于Lua脚本管理器详解
Lua脚本管理器详解是本文要介绍的内容,这不是一个文本编辑器或者ide之类的东东,实际上它只是一个dll,lua是胶水语言,这个管理器的目的是为了让C/C++更好的支持lua。
通常项目里管理脚本的方法都是分开文件存放,lua里没有工程的概念,所以文件是最小单位,这样一来脚本文件数量的增长会带来一个问题,名字污染。lua里定义的变量默认是全局的,只有使用了local定义的才是本地的,这样一来你在脚本a里定义的函数可能和在脚本b里定义的函数同名,而这完全不会带来任何错误或警告,因为在lua里函数就是一个值,你可以随时修改。
导出一个全局函数Include,它能把其它脚本包含进来,就像C里的#include一样,实际上它没有包含任何内容进来,只是建立了一个脚本间的关系网,每一个脚本是一个顶点,Include建立到达关系。每个脚本是隔离开的,即不同的脚本中的变量是可以同名的,但是是不同的变量,这个通过函数环境实现。
关键的东西是,优先关系,lua里虽然没有定义变量的语句,但是却有index和newindex事件,对一组值 取值的时候 t[k] 就触发index事件,对一组值 设定值的时候 t[k] = v 就触发newindex事件。后者就相当于是定义变量啦,即第一次使用。
index优先关系是:local > script > register-table > global,register-table是从C里导出的一些东西的总和,总的原则是越具体的东西越先考虑。首先是找local变量,找不到 就找本环境中的变量,找不到 就找Include关系能到达的其它脚本中的变量,找不到 就找register-table中的变量,找不到 就找全局变量。
newindex优先关系是:local > script(no include) > global,k是local就设置k = v,否则 如果t是table 先rawget(t, k) 找到了就设置值,否则 找global,global中有值就是global 否则就设置script。这里有些混乱,换言之,就是script中和global中不会同时有某个值,global中的值还是会影响到script中的值,也就是说不要定义太多的global值,比如你在脚本中写:
function print() end
它会认为是global的print,而把它重定义掉。
而实际上你在脚本里是无法定义新的global值的,你定义一个global中没有的值,它会转为script环境中的值。除了系统的一些函数,连导出的函数都不是直接放在global中的,所以一般无法定义新的global值。
好了,给了你限制还要给你灵活性,global中有一个Global函数,它能定义global值,接受1到2个参数,第一个是名字,第二个是初值。你如果对已有global值再调用它,会给一个错误信息,说你重定义了某个值。你可以在一个脚本中这样写:
Global("Foo") function Foo() end
这样这个Foo就不是在这个脚本中的函数了,在其它脚本中不用Include也能访问。