陈云佳 2020-08-15
DoString(init_xlua, "Init"); public object[] DoString(byte[] chunk, string chunkName = "chunk", LuaTable env = null) { #if THREAD_SAFE || HOTFIX_ENABLE lock (luaEnvLock) { #endif var _L = L; int oldTop = LuaAPI.lua_gettop(_L); int errFunc = LuaAPI.load_error_func(_L, errorFuncRef); if (LuaAPI.xluaL_loadbuffer(_L, chunk, chunk.Length, chunkName) == 0) { if (env != null) { env.push(_L); LuaAPI.lua_setfenv(_L, -2); } if (LuaAPI.lua_pcall(_L, 0, -1, errFunc) == 0) { LuaAPI.lua_remove(_L, errFunc); return translator.popValues(_L, oldTop); } } return null; #if THREAD_SAFE || HOTFIX_ENABLE } #endif }
LUALIB_API int xluaL_loadbuffer (lua_State *L, const char *buff, int size, const char *name) { return luaL_loadbuffer(L, buff, size, name); }
if (0 != LuaAPI.xlua_getglobal(rawL, "_G")) { throw new Exception("get _G fail!"); } translator.Get(rawL, -1, out _G);
private object getLuaTable(RealStatePtr L, int idx, object target) { if (LuaAPI.lua_type(L, idx) == LuaTypes.LUA_TUSERDATA) { object obj = translator.SafeGetCSObj(L, idx); return (obj != null && obj is LuaTable) ? obj : null; } if (!LuaAPI.lua_istable(L, idx)) { return null; } LuaAPI.lua_pushvalue(L, idx); return new LuaTable(LuaAPI.luaL_ref(L), translator.luaEnv); }
private object getLuaFunction(RealStatePtr L, int idx, object target) { if (LuaAPI.lua_type(L, idx) == LuaTypes.LUA_TUSERDATA) { object obj = translator.SafeGetCSObj(L, idx); return (obj != null && obj is LuaFunction) ? obj : null; } if (!LuaAPI.lua_isfunction(L, idx)) { return null; } LuaAPI.lua_pushvalue(L, idx); return new LuaFunction(LuaAPI.luaL_ref(L), translator.luaEnv); }
int errFunc = LuaAPI.load_error_func(L, luaEnv.errorFuncRef); LuaAPI.lua_getref(L, luaReference);//lua_function压栈。 if (args != null) { nArgs = args.Length; for (int i = 0; i < args.Length; i++) { translator.PushAny(L, args[i]);//参数压栈 } } int error = LuaAPI.lua_pcall(L, nArgs, -1, errFunc);//调用
public object CreateDelegateBridge(RealStatePtr L, Type delegateType, int idx) { LuaAPI.lua_pushvalue(L, idx); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); if (!LuaAPI.lua_isnil(L, -1))//之前加载过,走缓存 { int referenced = LuaAPI.xlua_tointeger(L, -1); LuaAPI.lua_pop(L, 1); if (delegate_bridges[referenced].IsAlive) { if (delegateType == null) { return delegate_bridges[referenced].Target; } DelegateBridgeBase exist_bridge = delegate_bridges[referenced].Target as DelegateBridgeBase; Delegate exist_delegate; if (exist_bridge.TryGetDelegate(delegateType, out exist_delegate)) { return exist_delegate; } ... } } else //第一次加载 { LuaAPI.lua_pushvalue(L, idx); int reference = LuaAPI.luaL_ref(L); LuaAPI.lua_pushvalue(L, idx); LuaAPI.lua_pushnumber(L, reference); LuaAPI.lua_rawset(L, LuaIndexes.LUA_REGISTRYINDEX); //栈:lua_func //register[lua_func] = ref_id DelegateBridgeBase bridge; bridge = new DelegateBridge(reference, luaEnv);//省略一部分,最终走的是这边,每个lua_function都会是生成一个bridge,并把对应的ref_id赋值给bridge. reference try { var ret = getDelegate(bridge, delegateType); bridge.AddDelegate(delegateType, ret); delegate_bridges[reference] = new WeakReference(bridge); return ret; } } }
Delegate getDelegate(DelegateBridgeBase bridge, Type delegateType) { Delegate ret = bridge.GetDelegateByType(delegateType); if (ret != null) { return ret; } ...//忽略特殊情况 }
if (type == typeof(System.Action<int>)) { return new System.Action<int>(__Gen_Delegate_Imp2);//创建新的Action并返回。 } public void __Gen_Delegate_Imp2(int p0) { #if THREAD_SAFE || HOTFIX_ENABLE lock (luaEnv.luaEnvLock) { #endif RealStatePtr L = luaEnv.rawL; int errFunc = LuaAPI.pcall_prepare(L, errorFuncRef, luaReference);//方法压栈 LuaAPI.xlua_pushinteger(L, p0); //参数压栈 PCall(L, 1, 0, errFunc); LuaAPI.lua_settop(L, errFunc - 1); //lua方法调用 #if THREAD_SAFE || HOTFIX_ENABLE } #endif }
Action<int> sceneLoad; sceneLoad = luaEnv.Global.GetInPath<Action<int>>("GameMain.OnLevelWasLoaded");//实际赋值的是__Gen_Delegate_Imp2方法。 sceneLoad(level);//调用__Gen_Delegate_Imp2方法