lua基础学习

lua基础学习

lua数据类型

八大基本数据类型
nil(空),boolean(布尔),number(数字),string(字符串),userdata(自定义类型),function(函数),thread(线程),table(表)

lua与C++交互

lua中调用C函数
C/C++和Lua是如何进行通信的

lua_State状态机

lua_State主要是管理一个lua虚拟机的执行环境, 一个lua虚拟机可以有多个执行环境。Lua虚拟机通过维护这样一个虚拟栈来实现两种之间的通信,lua_State定义如下:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
struct  {  
  CommonHeader;  
  lu_byte status;  
  StkId top;    
  global_State *l_G;  
  CallInfo *ci;  /* call info for current function */  
  const Instruction *oldpc;  /* last pc traced */  
  StkId stack_last;  /* last free slot in the stack */  
  StkId stack;  /* stack base */  
  int stacksize;  
  unsigned short nny;  /* number of non-yieldable calls in stack */  
  unsigned short nCcalls;  /* number of nested C calls */  
  lu_byte hookmask;  
  lu_byte allowhook;  
  int basehookcount;  
  int hookcount;  
  lua_Hook hook;  
  GCObject *openupval;  /* list of open upvalues in this stack */  
  GCObject *gclist;  
  struct lua_longjmp *errorJmp;  /* current error recover point */  
  ptrdiff_t errfunc;  /* current error handling function (stack index) */  
  CallInfo base_ci;  /* CallInfo for first level (C calling Lua) */  
};  

—|—

数据类型转换

C/C++和Lua拥有不同的数据类型,要实现两者之间的数据通信怎么办?Lua虚拟机提供Lua_State这样一种数据结构。任何一种数据从C/C++传入Lua虚拟机中,Lua都会将这类数据转换为一种通用的结构lua_TValue,并且将数据复制一份,将其压入虚拟栈中。lua_TValue定义如下:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
struct lua_TValue {  
  TValuefields;  
};  
  
  
    union { struct { Value v__; int tt__; } i; double d__; } u  
  
union Value {  
  GCObject *gc;    /* collectable objects */  
  void *p;         /* light userdata */  
  int b;           /* booleans */  
  lua_CFunction f; /* light C functions */  
  numfield         /* numbers */  
};  

—|—

Lua有自己的GC,C/C++由自己申请和释放内存,所以两者之间的内存管理是独立的。从C/C++中传递数据到Lua虚拟机会发生数据拷贝,从Lua虚拟机中传递出来是直接从虚拟栈中取值或者地址,所以数据从虚拟栈中pop之后,是否依然是有效引用需要额外注意。

lua垃圾收集机制

热更新

热更新也叫不停机更新,是在游戏服务器运行期间对游戏进行更新。实现不停机修正bug、修改游戏数据等操作。也可以这样讲:一辆车以时速150km跑着,突然爆胎了,然后司机告诉你,我不停车,你去把轮胎换了

热更新原理

第一种:
lua中的require会阻止多次加载相同的模块。所以当需要更新系统的时候,要卸载掉响应的模块。(把package.loaded里对应模块名下设置为nil,以保证下次require重新加载)并把全局表中的对应的模块表置 nil 。同时把数据记录在专用的全局表下,并用 local 去引用它。初始化这些数据的时候,首先应该检查他们是否被初始化过了。这样来保证数据不被更新过程重置。

1  
2  
3  
4  
function reloadUp(module_name)  
    package.loaded[modulename] = nil  
    require(modulename)  
end  

—|—

这种做法简单粗暴,虽然能完成热更新,但是问题很多,旧的引用的模块无法得到更新,这种程度的热更新显然不能满足现在的游戏开发需求。

第二种:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
function reloadUp(module_name)  
    local old_module = _G[module_name]  
  
    package.loaded[module_name] = nil  
    require (module_name)  
  
    local new_module = _G[module_name]  
    for k, v in pairs(new_module) do  
        old_module[k] = v  
    end  
  
    package.loaded[module_name] = old_module  
end  

—|—

糖果

糖果
LUA教程

Lapis框架的常用处理方法

Lapis框架的常用处理方法 Continue reading

MoonScript实现选择排序

Published on February 26, 2017

MoonScript与Redis客户端

Published on January 19, 2017