xLua:一个LuaManager
一个LuaManager.
封装了一个私有LuaEnv,全局只要有一个就可以了。
起了一个mian.lua 的main函数,作为lua模块的入口。所有的lua逻辑都从这里出发。这里是跟toLua的framework学的。。
封装了一个DoFile方法。因为xLua本身没有提供DoFile。想要DoFile得要通过DoString的require。本来我的DoFile也是按照require的方法来的,因为例子里的DoFile就是这样的。不过后来写LuaBehaviour的时候发现一个问题,就是下面注释里写的。给依附MonoBehaviour的lua脚本设置this的时候出问题了,于是就改成了通过loader方法先读取lua脚本,然后再DoString.但是这么做的话,感觉就违背了作者原本为require所设计的customLoader的初衷了。
实现了一个CustomerLoader.需要加密解密的话可以加在这个地方。
实现了一个InitPackagePath。原本不需要加密的话通过修改package.path就能DoFile require了。不过因为上面说的原因,DoFile变成了直接DoString,所以这块也用不上了。
获取全局变量的Get
直接通过LuaFunction调用全局函数的CallFunction.
using UnityEngine;
using System.CollectionLuas;
using System.IO;
using System;
using System.Text;
using XLua;
public class LuaManager : MonoBehaviour
{
//是否加密解密
public bool encryption = false;
public static LuaManager Instance;
private LuaEnv lua;
string envPath {
get {
#if UNITY_EDITOR
return Application.streamingAssetsPath + "/xLua";
#else
return Application.persistentDataPath + "/xLua";
#endif
}
}
public LuaTable Global { get { return lua == null ? null : lua.Global; } }
void Awake()
{
Instance = this;
}
void Start()
{
lua = new LuaEnv();
InitThirdLibs();
if (!encryption)
InitPackagePath();
else
lua.AddLoader(Loader);
//开启main.lua 入口
StartUp();
}
void Update()
{
if (lua != null)
lua.Tick();
}
void OnDestroy()
{
Close();
}
#region 一些接口
public void StartUp()
{
DoFile("main");
Action mainFunc;
Get("main", out mainFunc);
mainFunc();
}
public object[]DoString(string script,string chunk="chunk",LuaTable env=null)
{
return lua.DoString(script, chunk, env);
}
//因为之前遇到的一个 通过require加载代码 出现了 env变成了 "require xxx"所在环境,而不是require加载的代码的环境。
//那么当我设置了一个env.this=this的时候,在本来加载进来的lua代码里就访问不到了。得到require层才能访问到
//所以这里就不用require来加载了。
public object[] DoFile(string filename, LuaTable env = null)
{
byte[] buffer = Loader(ref filename);
string script = Encoding.Default.GetString(buffer);
return lua.DoString(script, filename, env);
}
public object[] CallFunction(string funcName, params object[] args)
{
LuaFunction func = lua.Global.Get(funcName);
var result=func.Call(args);
func.Dispose();
func = null;
return result;
}
public void Get<K, V>(K key, out V val)
{
lua.Global.Get(key, out val);
}
publicLuaTable NewTable(bool setGlobalEnv=false)
{
LuaTable table = lua.NewTable();
LuaTable meta = lua.NewTable();
meta.Set("__index", Global);
table.SetMetaTable(meta);
meta.Dispose();
meta = null;
return table;
}
public void Close()
{
lua.Dispose();
lua = null;
}
#endregion
#region 环境设置
//初始化一些第三方库
void InitThirdLibs()
{
}
void InitPackagePath()
{
lua.DoString("package.path=package.path..';" + envPath + "/?.lua" + "'");
}
byte[] Loader(ref string fileName)
{
//查找lua文件
fileName = fileName.EndsWith(".lua") ? fileName.Substring(0, fileName.Length - 4) : fileName;
fileName = fileName.Replace('.', '/');
fileName = fileName + ".lua";
DirectoryInfo dire = new DirectoryInfo(envPath);
FileInfo fi = SeachFile(dire, fileName);
if (fi == null)
{
Debug.LogError("Lua File: " + fileName + " Not Found!");
return null;
}
fileName = fi.FullName;
FileStream stream = fi.OpenRead();
byte[] buffers = new byte[stream.Length];
stream.Read(buffers, 0, buffers.Length);
stream.Close();
stream.Dispose();
if (encryption)
{
//解密
}
return buffers;
}
FileInfo SeachFile(DirectoryInfo dire, string fileName)
{
FileInfo result = null;
foreach (FileSystemInfo fs in dire.GetFileSystemInfos())
{
FileInfo fi = fs as FileInfo;
if (fi == null)//directory
{
result = SeachFile(fs as DirectoryInfo, fileName);
}
else
{
string path = fi.FullName;
if (path.IndexOf(fileName) >= 0)
{
result = fi;
break;
}
}
}
return result;
}
#endregion
}
- 上一篇: UGUI:一个渐变特写的滚动框特效
- 下一篇: xLua:一个LuaBehaiour