xlua 原理就是通過生成wrap代碼,在運行時調用。
但在實際調試過程中,還是會有很多的反射代碼被生成。
因此添加一個日志輸出,可以看到哪些類型是沒有被生成wrap,而lua中又用到了。
public bool TryDelayWrapLoader(RealStatePtr L, Type type)
{
if (loaded_types.ContainsKey(type)) return true;
loaded_types.Add(type, true);
LuaAPI.luaL_newmetatable(L, type.FullName); //先建一個metatable,因為加載過程可能會需要用到
LuaAPI.lua_pop(L, 1);
Action<RealStatePtr> loader;
int top = LuaAPI.lua_gettop(L);
if (delayWrap.TryGetValue(type, out loader))
{
delayWrap.Remove(type);
loader(L);
}
else
{
#if !GEN_CODE_MINIMIZE && !ENABLE_IL2CPP && (UNITY_EDITOR || XLUA_GENERAL) && !FORCE_REFLECTION && !NET_STANDARD_2_0
if (!DelegateBridge.Gen_Flag && !type.IsEnum() && !typeof(Delegate).IsAssignableFrom(type) && Utils.IsPublic(type))
{
Type wrap = ce.EmitTypeWrap(type);
MethodInfo method = wrap.GetMethod("__Register", BindingFlags.Static | BindingFlags.Public);
method.Invoke(null, new object[] { L });
}
else
{
// 此處添加日志輸出,可以看到在生成wrap代碼后,還有哪些type在被反射生成
Debug.Log("<color=green>jayden:ObjectTranslator.TryDelayWrapLoader:" + type + "</color>");
Utils.ReflectionWrap(L, type, privateAccessibleFlags.Contains(type));
}
#else
Utils.ReflectionWrap(L, type, privateAccessibleFlags.Contains(type));
#endif
// 以下代碼省略
通過日志可以總結出一些規律:
1.class 中又定義了class、enum等類型
這種寫法,在xlua的配置中GenConfig,通過命名空間方法添加的列表中,是無法生成warp類的。
盡量拆分代碼文件,且放在命名空間下,即符合編碼規范,也能減少配置項。
2.自定義的delegate 委托
public delegate void OnMapChanged();
public OnMapChanged EventOnMapChanged;
如果沒有添加到GenConfig 的委托列表中,那么也會在運行時被反射添加。