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 的委托列表中,那么也会在运行时被反射添加。