ToLua框架研究

ToLua框架

简介

tolua是腾讯开源的一款用于unity手游的热更新工具,github地址:ToLua
那么就来研究一下这个热更架构。

原理

lua这门脚本语言其实主要就是用来跟其他语言交互的,它的编译器就是c语言写的,几乎可以运行在所有平台上,而且它十分轻量,tolua使用效率更高的luajit编译器,对于比较在意性能的移动平台,是个不错的热更方案选择。
tolua的主要机制就是,创建lua虚拟机,绑定映射c#脚本,所以架构的内容大致归为三大部分:普通的Unity+C#部分、ToLua虚拟机部分和Lua脚本部分。
在我们打开tolua源码项目的时候,会弹出这样一个会话
ToLua框架研究_第1张图片
这就是要自动生成要绑定映射的文件,比如unity里的一些常用脚本类。点击确定自动生成,当然也可以不理会,在项目的lua菜单中自行生成需要的类型注册文件。
ToLua框架研究_第2张图片
其实这个弹框功能就在ToLuaMenu.cs这个编辑器脚本里,我们看看这段代码,它会帮我们做些什么
ToLua框架研究_第3张图片
点击确定,会执行一些方法,比如GenLuaDelegates,会去注册各种c#的委托,CustomSettings可以添加我们需要注册的一些类,比如UnityEngine.RenderSettings,UnityEngine.Time等静态类,还有MeshRenderer,Rigidbody等动态类,还有一些密封类以及c#的一些委托类型,GetCustomTypeDelegates则通过反射获取了这些注册类的字段属性和方法。ToLua框架研究_第4张图片
ToLuaExport会帮我我们自动生成cs类文件用于注册,查阅ToLuaExport的代码会发现它用一套cs文件格式,用stringbuilder自拼接导出了注册类cs文件在下图的目录下,这个目录在CustomSettings.saveDir设置
ToLua框架研究_第5张图片
之后我们看到有个GenLuaBuilder的方法,它会生成一个cs文件,提供一个绑定lua虚拟机的方法,把刚才我们生产的注册文件,将注册的各个类绑定到虚拟机上。

ToLua框架研究_第6张图片

C#与Lua的交互

C#访问Lua的变量,方法

我们看下源码的示例:
ToLua框架研究_第7张图片
ToLua框架研究_第8张图片
如上图,LuaState提供了对表,对变量,对方法的访问方式,很方便~

Lua访问C#的变量,方法

我们看下源码的示例:
ToLua框架研究_第9张图片
LuaState就是我们说的Lua虚拟机, LuaResLoader是lua的资源读取器,它用于载入读取lua脚本。启动LuaState后我们将之前注册过的类绑定到虚拟机上,那么lua脚本里的Unity组件就可以访问了,比如本利中的Gameobject和ParticleSystem,这样就实现了C#读取lua脚本,lua脚本中又可以调用C#或Unity里的类和方法。

LuaState

lua虚拟机的内部到底是如何工作的呢?我翻看了它的源码,以自己的理解分析下~
ToLua框架研究_第10张图片
luastate的构造函数,我们发现,创建一个lua虚拟机,我们会调用LuaStatePtr的LuaNewState方法,返回IntPtr类型,这就是新建虚拟机的句柄,二这个方法来自 LuaDLL的外部dll调用,它在下图的目录里,不同的平台有不同的Dll, LuaDLL提供了许多lua的接口方法
ToLua框架研究_第11张图片
创建的虚拟机还会放在一个stateMap的 dictionary中来管理,在我们执行完lua脚本后可调用LuaState.Dispose来回收虚拟机,这对于性能来说是很重要的步骤。
luastate有几个非常重要的方法
ToLua框架研究_第12张图片
之前说过 lua里要想访问c#的属性,方法就要注册到lua虚拟机里,所以要LuaBinder将这些属性方法注入到Lua虚拟机中, 用Marshal.GetFunctionPointerForDelegate方法拿到方法指针(句柄),调用LuaDll相应的方法,就完成了注入。我们在会看下LuaBinder的Bind方法:
ToLua框架研究_第13张图片
对应Wrap文件的Register方法里,它将完成了属性和方法的注册:
ToLua框架研究_第14张图片
ToLua的大致研究就到这里了,也许有很多理解不到位的地方,希望大家多多指正~

你可能感兴趣的:(lua)