【学习笔记】从零开始学ToLua(六)对一些代码的补充说明

还有一些代码的说明在前面的【学习笔记】从零开始学ToLua(四)tolua原理解析

LuaClient

在前面的自定义加载器的案例中我们就是继承于这个类

  • 对于LuaClient我们可以理解成是ToLua内部对自己的一种封装,可以视为tolua环境的一个启动
  • 我们可以从这个类派生

LuaFileUtils

  • beZip = false 在search path 中查找读取lua文件。否则从外部设置过来bundel文件中读取lua文件

LuaResLoader require

  • 派生自LuaFileUtils
  • 优先读取persistentDataPath/系统/Lua 目录下的文件(默认下载目录)
  • 未找到文件怎读取 Resources/Lua 目录下文件(仍没有使用LuaFileUtil读取)

require

  • ulua在初始化LuaState时,会先解析package.path, 并将其存入LuaFileUtilsSearchPaths中。
  • 在LuaState的构造函数中,会调用ToLua.OpenLib(T),该方法定义了一下特殊方法,可以在lua中使用,如typeof等。
  • OpenLib方法会在package.loaders数组中,再添加一个loade((Lua5.3中, 改名为searchers))r,并且将其放到数组的第二个位置。(ToLua.cs line:192)注:Lua require模块时,会依次调用package.loader中的方法,找到则返回
  • loader的作用就是检测传入的文件名(module名),是否在LuaFileUtilsSearchPaths,如果存在就读取文件,若不存在则返回空(LuaFileUitls.cs line:170)

参考资料 lua require 机制 @chiguozi

手机上运行

  • 如果你想在手机上测试例子,首先点击菜单Lua/Copy lua files to Resources, 之后再build.

OpenLibs() 

  • 这个东西非常重要,它标志着你一些C写的PB的内容能不能使用,比如你想去做一个LUAtable去对应protobuf协议,那么你在里面编码解码时,tolua的框架会去调用require "pb",如果你没有写这个库的注册,那么你将不能使用pb的库。
  • 这个库里的注册内容包括如下:

  lua.OpenLibs(LuaDLL.luaopen_pb);
  lua.OpenLibs(LuaDLL.luaopen_sproto_core);
  lua.OpenLibs(LuaDLL.luaopen_protobuf_c);
  lua.OpenLibs(LuaDLL.luaopen_lpeg);
  lua.OpenLibs(LuaDLL.luaopen_bit);
  lua.OpenLibs(LuaDLL.luaopen_socket_core);

setpeer()

  • 我们在前面的继承中使用了它来进行模拟
  • 每个C++对象需要存贮自己的成员变量的值,这个值不能够存贮在元表里(因为元表是类共用的),所以每个对象要用一个私有的表来存贮,这个表在tolua里叫做peer表。
  • 把C#对象在lua中对应的userdata(csobj)和一个lua table(peer)进行setpeer操作后:tolua.setpeer(csobj, peer)
  • 1.把peer表设置为csobj的环境表,peer.base[&vptr] = csobj,  setmetatable(peer.base, vptrtable)
  • 2.在csobj访问一个元素,csobj[key],会进行以下步骤:
  • (1)在peer表直接查找,rawget(peer, key),如果不为nil, 则返回这个值。如果为nil,则进行(2)不查找
  • 如果userdata(u)和peer(p)表都不为空的话,会执行如下步骤:

    1.lua_pushvalue(L, 2);                           把peer表复制压进栈顶                                                        此时虚拟栈:stack: u, p, p

    2.lua_setfenv(L, -3);                      -3是u的位置,相当于把栈顶元素peer设置为u的环境表               此时虚拟栈:stack: u, p 

    3.lua_newtable(L);                       创建一个空的table,压进栈顶                       此时虚拟栈:stack: u, p,vt

    4.lua_pushlightuserdata(L, &vptr);          把一个轻量级的userdata压进栈顶,vptr是一个值为1的static int类型           此时虚拟栈:stack: u, p,vt, lu

    5.lua_pushvalue(L, 1);           把栈底元素u复制压进栈顶                       此时虚拟栈:stack: u, p,vt, lu, u

    6.lua_rawset(L, -3);                                执行vt[lu] = u, 直接赋值,忽略元表                  此时虚拟栈:stack: u, p,vt

    7.lua_getref(L, LUA_RIDX_VPTR);            通过ref获取对应的一个table,压进栈顶                                                  此时虚拟栈:stack: u, p,vt, mt

    8.lua_setmetatable(L, -2);                       setmetatable(p, mt)                                                                      此时虚拟栈:stack: u, p,vt

    9.lua_pushstring(L, "base");                     把"base"字符串压进栈顶                                                                   此时虚拟栈:stack: u, p,vt,"base"

    10.lua_pushvalue(L, -2);         把vt表压进栈顶                            此时虚拟栈:stack: u, p,vt,"base",vt

    11.lua_rawset(L, 2);           p.base = vt                                                                                    此时虚拟栈:stack: u, p,vt

    12.lua_pop(L, 1);             把vt弹出栈顶                             此时虚拟栈:stack: u, p

参考资料:tolua.setpeer  @xsxjin

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值