2023-04-03 11:04:31 +08:00

285 lines
8.2 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections.Generic;
using UnityEngine;
using XLua;
using System;
using System.IO;
namespace BF
{
public class LuaManager : ManagerBase
{
#region override
static LuaManager instance;
public static LuaManager Create()
{
BFLog.LogAssert(instance == null, "This method only allows BFMain to call once");
instance = new LuaManager();
return instance;
}
LuaManager() { }
public override void Init()
{
OnInit();
}
public override void Update()
{
OnUpdate();
}
public override void Destroy()
{
OnDestroy();
}
#endregion
internal LuaEnv luaEnv;
const float GCInterval = 1; // 1 second
float lastGCTime = 0;
Dictionary<string, byte[]> luaScriptDict = new Dictionary<string, byte[]>();
Action luaUpdate;
Action luaOnDestroy;
Action<string, string> luaOnLogMessageReceived;
Action<bool> luaOnApplicationFocus;
Action<bool> luaOnApplicationPause;
Action luaOnApplicationQuit;
Action gameInitSuccCallback;
AssetBundleConfigCollection Abcc { get { return BFMain.Instance.ResMgr.AbConfigCollection; } }
public bool DevExist = false;
void OnInit()
{
if (luaEnv == null)
{
#if UNITY_EDITOR
DevExist = Directory.Exists(Application.dataPath + "/Developer/lua");
#endif
Application.logMessageReceived += OnLogMessageReceived;
luaEnv = new LuaEnv();
luaEnv.AddBuildin("rapidjson", XLua.LuaDLL.Lua.LoadRapidJson);
luaEnv.AddBuildin("lpeg", XLua.LuaDLL.Lua.LoadLpeg);
luaEnv.AddBuildin("pb", XLua.LuaDLL.Lua.LoadLuaProfobuf);
}
}
void OnLogMessageReceived(string message, string stackTrace, LogType type)
{
if (type == LogType.Error || type == LogType.Exception)
{
luaOnLogMessageReceived?.Invoke(message, stackTrace);
}
}
/// <summary>
/// 初始化首包lua
/// </summary>
public void InitFirstLua(LuaEnv.CustomLoader loader)
{
BFLog.Log("加载首包lua first.lua");
luaEnv.ClearLoader();
luaEnv.AddLoader(loader);
luaEnv.DoString("require 'app/first/first'");
}
/// <summary>
/// 初始化main.lua 进入游戏
/// </summary>
public void InitGame(Action gameInitSuccCallback)
{
this.gameInitSuccCallback = gameInitSuccCallback;
luaEnv.ClearLoader();
luaEnv.AddLoader((ref string scriptPath) =>
{
var text = LoadGameLuaScriptText(scriptPath);
return text;
});
luaEnv.DoString("require 'main'");
#if HOTFIX_ENABLE
luaEnv.DoString("require 'app/hotfix/hotfixmain'");
#endif
}
byte[] LoadGameLuaScriptText(string scriptPath)
{
byte[] result = null;
if (!luaScriptDict.TryGetValue(scriptPath, out result))
{
#if !USE_AB && UNITY_EDITOR
result = LoadLuaDeveloperMode(scriptPath);
#else
result = LoadLuaStandardMode(scriptPath);
#endif
if (result != null)
{
luaScriptDict.Add(scriptPath, result);
}
}
return result;
}
public byte[] LoadLuaDeveloperMode(string scriptPath)
{
byte[] result = null;
if (DevExist)
{
// 开发路径加载
var devLuaPath = Application.dataPath + "/Developer/lua/" + scriptPath + ".lua";
if (File.Exists(devLuaPath))
{
result = File.ReadAllBytes(devLuaPath);
}
else
{
Debug.LogError("lua file is missing : " + devLuaPath);
}
}
else
{
// 开发路径不存在尝试bytes路径加载
var luaBytesPath = Application.dataPath + "/lua/" + scriptPath + ".lua.bytes";
if (File.Exists(luaBytesPath))
{
result = File.ReadAllBytes(luaBytesPath);
XLua.LuaDLL.Lua.decryptLua(ref result[0], result.Length);
}
else
{
Debug.LogError("lua file is missing : " + luaBytesPath);
}
}
return result;
}
byte[] LoadLuaStandardMode(string scriptPath)
{
byte[] result = LoadLuaAB(scriptPath);
if (result == null)
{
Debug.LogError("Lua assetBundle is missing : " + scriptPath + ".lua");
}
return result;
}
byte[] LoadLuaAB(string scriptPath)
{
var luaPath = "assets/lua/" + scriptPath + ".lua.bytes";
var abConfig = Abcc.GetConfigByAssetPath(luaPath);
string fullpath;
if (abConfig.location == 1)
{
fullpath = Path.Combine(Application.persistentDataPath, "update", abConfig.assetBundlePath);
}
else
{
fullpath = Path.Combine(Application.streamingAssetsPath, abConfig.assetBundlePath);
}
var ab = AssetBundle.LoadFromFile(fullpath);
var textAsset = ab.LoadAsset<TextAsset>(luaPath);
var bytes = textAsset.bytes.Clone() as byte[];
XLua.LuaDLL.Lua.decryptLua(ref bytes[0], bytes.Length);
ab.Unload(true);
return bytes;
}
public void GetGlobalLuaFunc()
{
luaEnv.Global.Get("luaUpdate", out luaUpdate);
luaEnv.Global.Get("luaOnDestroy", out luaOnDestroy);
luaEnv.Global.Get("luaOnLogMessageReceived", out luaOnLogMessageReceived);
luaEnv.Global.Get("luaOnApplicationFocus", out luaOnApplicationFocus);
luaEnv.Global.Get("luaOnApplicationPause", out luaOnApplicationPause);
luaEnv.Global.Get("luaOnApplicationQuit", out luaOnApplicationQuit);
}
public void OnGameInitSucc()
{
BFLog.Log("OnGameInitSucc");
gameInitSuccCallback?.Invoke();
gameInitSuccCallback = null;
BFMain.Instance.GameLaunchMgr.LaunchRequester.ClearLaunchSuccCallback();
}
public void ClearCache()
{
luaScriptDict.Clear();
}
public void LuaEnvTick()
{
luaEnv.Tick();
lastGCTime = Time.time;
}
public void LuaEnvFullGC(int count)
{
int defaultCheckCouunt = luaEnv.GetMaxCheckPerTick();
luaEnv.SetMaxCheckPerTick(count);
LuaEnvTick();
luaEnv.SetMaxCheckPerTick(defaultCheckCouunt);
}
void OnUpdate()
{
luaUpdate?.Invoke();
if (Time.time - lastGCTime > GCInterval)
{
luaEnv.Tick();
lastGCTime = Time.time;
}
}
public void OnApplicationFocus(bool hasFocus)
{
luaOnApplicationFocus?.Invoke(hasFocus);
}
public void OnApplicationPause(bool pauseStatus)
{
luaOnApplicationPause?.Invoke(pauseStatus);
}
public void OnApplicationQuit()
{
luaOnApplicationQuit?.Invoke();
}
void OnDestroy()
{
luaOnDestroy?.Invoke();
luaOnDestroy = null;
luaUpdate = null;
luaOnApplicationFocus = null;
luaOnApplicationPause = null;
luaOnApplicationQuit = null;
}
public void Clear()
{
luaUpdate = null;
luaOnDestroy = null;
luaOnLogMessageReceived = null;
luaOnApplicationFocus = null;
luaOnApplicationPause = null;
luaOnApplicationQuit = null;
gameInitSuccCallback = null;
}
}
}