找回密码
 立即注册
查看: 306|回复: 0

xLua 随笔

[复制链接]
发表于 2022-9-26 08:22 | 显示全部楼层 |阅读模式
一、纯lua相关问题

0. Lua 的 元表 元方法 和 opp的关系

Lua 学习元表,元方法_liaosheng:)-CSDN博客_lua 元方法
这个博客写的很详细了,多注意:元表的含义, 和__index这个元方法的含义;
Lua本没有面向对象,但是利用元表和__index的特效我们也可以实现面向对象。
  1. BaseClass = { trans = nil }
  2. function BaseClass:new() -- 基类构造函数
  3.     local o = {}
  4.     setmetatable(o, { __index = self })
  5.     return o
  6. end
  7. -----------------------------------------------
  8. ItemClass = BaseClass:new()
  9. function ItemClass:Release()
  10.     print("释放")
  11. end
  12. -----------------------------------------------
  13. Fruit = ItemClass:new()
  14. function Fruit:BeEaten()
  15.     print("水果被吃")
  16. end
  17. -----------------------------------------------
  18. function start()
  19.     local f = Fruit:new()
  20.     f:BeEaten()
  21.     f:Release()
  22. end
复制代码
1. Lua 的 虚变量

“_”即为虚变量,用来承接一些多个返回值的方法中不被我们需要的返回值,
功能上可以理解为占位符,但是虚变量是有值的。
2. Lua 的 虚表(听上去和虚变量有关联,其实完全不是一个东西)

先大白话总结:
Lua有自己的GC机制,被引用的对象不会被GC回收,
但是被弱引用引用的对象可以被回收,虚表(也叫弱表)就是具有弱引用条目的表。
所以到底是什么呢:
虚表也是表,设置了元表,同时定义了__mode字段:
        例:
  1. local x = {}
  2. setmetatable( x, {__mode="v"} )
复制代码
__mode字段取值可分为k / v / kv
k表示table的keys是weak的,可被回收;
v表示table的values是weak的,可被回收;
kv表示都weak,key和value中的一个被回收,那么kv键值对就被从表中移除。
二、xLua使用遇到问题

1. require的使用

官方示例中: local util = require 'xlua.util'
直接获取 Resources/xlua/util.lua 脚本,喔,原来 require 直接会从Resources下面找脚本???
那么如果想获取的脚本不在 Resources 目录下怎么办呢?
顺藤摸瓜,于是在官方示例里找到了这些:
  1.                 AddSearcher(StaticLuaCallbacks.LoadBuiltinLib, 2); // just after the preload searcher
  2.                 AddSearcher(StaticLuaCallbacks.LoadFromCustomLoaders, 3);
  3. #if !XLUA_GENERAL
  4.                 AddSearcher(StaticLuaCallbacks.LoadFromResource, 4);
  5.                 AddSearcher(StaticLuaCallbacks.LoadFromStreamingAssetsPath, -1);
  6. #endif
复制代码
从这段代码就知道了:为什么可以从Resources下可以找到 你想要的脚本
  1. internal static int LoadFromResource(RealStatePtr L)
  2.         {
  3.             try
  4.             {
  5.                 string filename = LuaAPI.lua_tostring(L, 1).Replace('.', '/') + ".lua";
  6.                 // Load with Unity3D resources
  7.                 UnityEngine.TextAsset file = (UnityEngine.TextAsset)UnityEngine.Resources.Load(filename);
  8.                 if (file == null)
  9.                 {
  10.                     LuaAPI.lua_pushstring(L, string.Format(
  11.                         "\n\tno such resource '{0}'", filename));
  12.                 }
  13.                 else
  14.                 {
  15.                     if (LuaAPI.xluaL_loadbuffer(L, file.bytes, file.bytes.Length, "@" + filename) != 0)
  16.                     {
  17.                         return LuaAPI.luaL_error(L, String.Format("error loading module {0} from resource, {1}",
  18.                             LuaAPI.lua_tostring(L, 1), LuaAPI.lua_tostring(L, -1)));
  19.                     }
  20.                 }
  21.                 return 1;
  22.             }
  23.             catch (System.Exception e)
  24.             {
  25.                 return LuaAPI.luaL_error(L, "c# exception in LoadFromResource:" + e);
  26.             }
  27.         }
复制代码
回到原本的问题,自定义添加require该怎么办呢?
看上面第一个代码块中四个 AddSearcher ,
第一个LoadBuiltinLib,推测是内置的函数blablabla的,有时间可以试试把它注释掉,康康哪些方法用不了了.... 噗
第三个第四个都眼熟,resources 和 streamingAssets。
还剩第二个LoadFromCustomLoaders,追进去!
  1. internal static int LoadFromCustomLoaders(RealStatePtr L)
  2.         {
  3.             try
  4.             {
  5.                 string filename = LuaAPI.lua_tostring(L, 1);
  6.                 LuaEnv self = ObjectTranslatorPool.Instance.Find(L).luaEnv;
  7.                 foreach (var loader in self.customLoaders)
  8.                 {
  9.                     string real_file_path = filename;
  10.                     byte[] bytes = loader(ref real_file_path);
  11.                     if (bytes != null)
  12.                     {
  13.                         if (LuaAPI.xluaL_loadbuffer(L, bytes, bytes.Length, "@" + real_file_path) != 0)
  14.                         {
  15.                             return LuaAPI.luaL_error(L, String.Format("error loading module {0} from CustomLoader, {1}",
  16.                                 LuaAPI.lua_tostring(L, 1), LuaAPI.lua_tostring(L, -1)));
  17.                         }
  18.                         return 1;
  19.                     }
  20.                 }
  21.                 LuaAPI.lua_pushstring(L, string.Format(
  22.                     "\n\tno such file '{0}' in CustomLoaders!", filename));
  23.                 return 1;
  24.             }
  25.             catch (System.Exception e)
  26.             {
  27.                 return LuaAPI.luaL_error(L, "c# exception in LoadFromCustomLoaders:" + e);
  28.             }
  29.         }
复制代码
嗯,就是它了!customLoaders!
然后blablabla,就找到了这个AddLoader(CustomLoader xxx)这个方法。
传入的是一个 委托:
其定义为:public delegate byte[] CustomLoader(ref string filepath);
喔,在这里处理你传入的path和想要怎么处理,然后返回脚本的 byte[]
okay,搞定!
上官方示例:
  1. LuaEnv luaenv = new LuaEnv();
  2. #if UNITY_EDITOR
  3.             luaenv.AddLoader(new SignatureLoader(PUBLIC_KEY, (ref string filepath) =>
  4.             {
  5.                 filepath = Application.dataPath + "/XLua/Examples/10_SignatureLoader/" + filepath.Replace('.', '/') + ".lua";
  6.                 if (File.Exists(filepath))
  7.                 {
  8.                     return File.ReadAllBytes(filepath);
  9.                 }
  10.                 else
  11.                 {
  12.                     return null;
  13.                 }
  14.             }));
复制代码
----------------------------------------------------------------------------------------------------------------------------
好吧,我直接看了半天官方示例,但是没有提前看最开始的文档,我是xx....
文档上明明白白写着设置loader的方法,哈哈哈
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2025-2-23 00:54 , Processed in 0.090867 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表