Administrator
发布于 2024-08-12 / 20 阅读
0
0

Lua脚本和数据驱动

参考书籍:【游戏编程精粹6】

概述

1.脚本语言大多是对c++核心语言的延伸,确保数据转换效率。

2.脚本语言是翻译语言,不能汇编成机器代码,需要通过虚拟机执行,慢但灵活可以热更新,为了减少运行事件脚本代码一般科技园编译成字节代码(脚本的中间二元形式,仍运行在虚拟机上)

Lua与C和c+的整合

lua和C++的信息哦交换通过,Lua中运行时管理的一个虚拟栈来实现,每个函数都有它自己的栈,调用一个C++函数就调用一个lua函数,同时会建立一个新的栈来交换数值。为了更高的灵活性,虚拟栈仍能通过索引被访问,正索引从栈底访问,负索引从栈顶访问

从c++代码中使用脚本

脚本是作为C++引擎核心的延申,c++调用脚本函数,通过argumen,开始执行,回收返回值三部分组成

在Lua中,参数会储存在一个栈里,调用函数需要进行一次特殊的API调用,一旦函数执行完成就需要收集执行结果,调用协议的不也需要为每一个调用的函数编写代理函数,在lua中,会收到一个状态结构--Lua_State--这个状态结构允许回收参数并发送结果给脚本同样有别的用处。

对于脚本虚拟机来说,它没有办法靠自己来识别C++函数,我们必须告诉它在哪里能找到这些函数,以及从脚本的范围来说这些函数的名称是什么,Lua会导出全局函数,并单独注册每一个函数,因此不需要任何中间结构,python需要开发者自己建立一个包含所有函数的模块,其中的信息包括每个函数的名字和代理函数的指针,开发者要将次模块注册成为一个单独的API调用。

Lua只能注册c++的静态方法,因为方法的地址只有被声明为静态时候才能获得,静态方法可以作为中间函数来回收对象范围之外的额外参数,然后利用这个对象范围调用真正的方法,这样通过两个间接性来获得一个泛函性

工具:

image-wtzv.png

image-xmsv.png

性能特点

内存管理

脚本语言为高级语言,会进行自动的内存管理,而复杂的任务,如结构定位内存,或释放内存,或者解决内存泄漏以及访问异常,都不存在。在非正确的时间释放内存会对帧率造成影响,过多的内存消耗或者内存分段对游戏的性能也会造成影响

  • 引用计数

引用计数

补充:

Lua尾调用:人话每次递归只返回函数本身,其他值当参数传,不会爆内存,新函数反复使用同一个栈,消除了build的过程

Lua支持“尾调用消除(tail-call elimination)”。
尾调用(tail call):当一个函数调用是另一个函数的最后一个动作时,该调用才算是一条“尾调用”。例如,下面的代码就是一条“尾调用”:

function f(n)   --简单递归
	if n<=0 then
		return 0	
	end
	a=f(n-1)
	return n*a
end
f(1000000000) --每次都要递归到最下面再依次返回,堆会很大会爆内存
---优化为尾递归不会报内存
function f(n,now)
	if n<=0 then
	return now
	end	
	return f(n-1,n*now)
end
f(100000,1)
	
function f (x) return g(x) end

也就是说,当f调用完g之后就再无其他事情可做了。因此在这种情况下,程序就不需要返回那个“尾调用”所在的函数了。所以在“尾调用”之后,程序也不需要保存任何关于该函数的栈(stack)信息了。当g返回时,执行控制权可以直接返回到调用f的那个点上。有一些语言实现(例如Lua解释器)可以得益于这个特点,使得在进行“尾调用”时不好非任何栈空间。将这种实现称为支持“尾调用消除”。
由于“尾调用”不会耗费栈空间,所以一个程序可以拥有无数嵌套的“尾调用”。例如,在第哦用以下函数时,传入任何数字作为参数都不会造成栈溢出

元表Metatable 可以绑定c++中的类并基于table的对象提供支持

元表是在某些值上执行callback

在 Lua 中,每个表都可以有一个元表。元表是一个表,它定义了原始表的行为。当 Lua 尝试对一个表执行某些操作时,它会检查这个表是否有元表,并查询元表以确定如何处理这个操作。通过这种方式,元表允许我们自定义表的某些行为,例如定义如何进行索引、如何进行算术运算等。(对table的定义)

设置和获取元素:通过 setmetatable函数来为一个表 使用getmetatable来获取一个表的元素


评论