用途
与其他模块交互的时候,找一个按钮对应执行的函数要找很久。如果可以直接获取事件所在代码行数就好了
错误思路
思路1:在lua侧获取按钮的userdata,并为其设置metatable
错误原因:按钮的userdata是C#对象,是xlua为其设置的元表,lua无法修改。
思路2:在C#侧,获取按钮实例,获取其点击事件并获得这个点击事件的debug信息。
错误原因:C#侧的点击事件已经被包装成了System.Action这个C#类型,无法获得lua的函数debug信息。
正确思路
其实从上面的错误思路2,就可以想到正确的写法了。找到包装System.Action的地方就好了,那怎么查呢?
lua的函数为btn.clickevent = function() end,我们需要考虑这一行函数调用后,C#上面的btn是如何接受到这个lua函数的。
可以看wrap文件:
Utils.RegisterFunc(L, Utils.SETTER_IDX, "clickevent", _s_set_clickevent);
static int _s_set_clickevent(RealStatePtr L)
{
try {
ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
Button gen_to_be_invoked = (Button)translator.FastGetCSObj(L, 1);
gen_to_be_invoked.clickevent = translator.GetDelegate<System.Action<...>>(L, 2);
} catch(System.Exception gen_e) {
return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
}
return 0;
}
不难看出,是在translator.GetDelegate>(L, 2);这段函数中,将luafunction转为的System.Action. 这样思路就很清晰了,我们只需要在这一段中插入代码,获取这个即将被转为Action的luaFunction,获取它的debug信息就可以了。所以我们只需要:
#if UNITY_EDITOR
/// <summary>
/// 存储 Lua 函数位置信息,用于调试
/// </summary>
public static class LuaFunctionLocationTracker
{
/// <summary>
/// 最后一次创建的 Delegate 对应的 Lua 函数位置
/// 在 CreateDelegateBridge 返回前设置,供外部立即读取
/// </summary>
public static string LastCreatedDelegateLocation;
}
#endif
public object CreateDelegateBridge(RealStatePtr L, Type delegateType, int idx)
{
#if UNITY_EDITOR
// 在栈上的 Lua 函数还未被包装前,获取其位置信息
string luaFuncLocation = GetLuaFunctionLocation(L, idx);
LuaFunctionLocationTracker.LastCreatedDelegateLocation = luaFuncLocation;
#endif
修改ObjectTranslator,使得在任何lua函数包装前,都将这个lua函数的debug信息获取出来,存储到静态变量中。然后我们把button的luaFunction设置修改为属性。这样的话,在这个button的setter中,我们获取objectTranslator中的静态变量,就是上一次,也就是刚刚在CreateDelegateBridge中设置的位置信息了。
public System.Action clickevent
{
get => _clickevent;
set
{
_clickevent = value;
// 从 XLua ObjectTranslator 获取刚刚创建的 Lua 函数位置
if (value != null && GetLastDelegateLocationFunc != null)
{
luaClickLocation = GetLastDelegateLocationFunc();
}
else
{
luaClickLocation = null;
}
}
}
最后,我们只需要在C#中调用这个点击事件的地方,插入一行print luaClickLocation的代码就好了!