static public void clear() { oldl = IntPtr.Zero; oldoc = null; }
public LuaState() { if (mainThread == 0) { mainThread = System.Threading.Thread.CurrentThread.ManagedThreadId; } L = LuaDLL.luaL_newstate(); statemap[L] = this; refQueue = new Queue <UnrefPair>(); ObjectCache.make(L); LuaDLL.lua_atpanic(L, panicCallback); LuaDLL.luaL_openlibs(L); string PCallCSFunction = @" local assert = assert local function check(ok,...) assert(ok, ...) return ... end return function(cs_func) return function(...) return check(cs_func(...)) end end "; LuaDLL.lua_dostring(L, PCallCSFunction); PCallCSFunctionRef = LuaDLL.luaL_ref(L, LuaIndexes.LUA_REGISTRYINDEX); string newindexfun = @" local getmetatable=getmetatable local rawget=rawget local error=error local type=type local function newindex(ud,k,v) local t=getmetatable(ud) repeat local h=rawget(t,k) if h then if h[2] then h[2](ud,v) return else error('property '..k..' is read only') end end t=rawget(t,'__parent') until t==nil error('can not find '..k) end return newindex "; string indexfun = @" local type=type local error=error local rawget=rawget local getmetatable=getmetatable local function index(ud,k) local t=getmetatable(ud) repeat local fun=rawget(t,k) local tp=type(fun) if tp=='function' then return fun elseif tp=='table' then local f=fun[1] if f then return f(ud) else error('property '..k..' is write only') end end t = rawget(t,'__parent') until t==nil error('Can not find '..k) end return index "; newindex_func = (LuaFunction)doString(newindexfun); index_func = (LuaFunction)doString(indexfun); setupPushVar(); pcall(L, init); createGameObject(); }
public static void setBack(IntPtr l, object o) { ObjectCache t = ObjectCache.get(l); t.setBack(l, 1, o); }
public static void pushObject(IntPtr l, object o) { ObjectCache oc = ObjectCache.get(l); oc.push(l, o); }
// lightobj is non-exported object used for re-get from c#, not for lua public static void pushLightObject(IntPtr l, object t) { ObjectCache oc = ObjectCache.get(l); oc.push(l, t, false); }
static public object checkObj(IntPtr l, int p) { ObjectCache oc = ObjectCache.get(l); return(oc.get(l, p)); }
public LuaState() { mainThread = System.Threading.Thread.CurrentThread.ManagedThreadId; L = LuaDLL.luaL_newstate(); statemap[L] = this; if (main == null) { main = this; } refQueue = new Queue <UnrefPair>(); LuaDLL.luaL_openlibs(L); ObjectCache.make(L); LuaDLL.lua_pushlightuserdata(L, L); LuaDLL.lua_setglobal(L, "__main_state"); LuaDLL.lua_pushcfunction(L, print); LuaDLL.lua_setglobal(L, "print"); LuaDLL.lua_pushcfunction(L, pcall); LuaDLL.lua_setglobal(L, "pcall"); LuaDLL.lua_pushcfunction(L, import); LuaDLL.lua_setglobal(L, "import"); string resumefunc = @" local resume = coroutine.resume coroutine.resume=function(co,...) local ret={resume(co,...)} if not ret[1] then UnityEngine.Debug.LogError(debug.traceback(co,ret[2])) end return unpack(ret) end "; // overload resume function for report error if (LuaDLL.lua_dostring(L, resumefunc) != 0) { LuaObject.throwLuaError(L); } LuaDLL.lua_pushcfunction(L, dofile); LuaDLL.lua_setglobal(L, "dofile"); LuaDLL.lua_pushcfunction(L, loadfile); LuaDLL.lua_setglobal(L, "loadfile"); LuaDLL.lua_pushcfunction(L, loader); int loaderFunc = LuaDLL.lua_gettop(L); LuaDLL.lua_getglobal(L, "package"); #if LUA_5_3 LuaDLL.lua_getfield(L, -1, "searchers"); #else LuaDLL.lua_getfield(L, -1, "loaders"); #endif int loaderTable = LuaDLL.lua_gettop(L); // Shift table elements right for (int e = LuaDLL.lua_rawlen(L, loaderTable) + 1; e > 1; e--) { LuaDLL.lua_rawgeti(L, loaderTable, e - 1); LuaDLL.lua_rawseti(L, loaderTable, e); } LuaDLL.lua_pushvalue(L, loaderFunc); LuaDLL.lua_rawseti(L, loaderTable, 1); LuaDLL.lua_settop(L, 0); }
static public void pushInterface(IntPtr l, object i, Type t) { ObjectCache oc = ObjectCache.get(l); oc.pushInterface(l, i, t); }
void OnGUI() { float w = this.maxSize.x; float h = this.maxSize.y; var svrGo = GameObject.FindObjectOfType <LuaSvrGameObject>(); if (svrGo == null) { GUILayout.Label("There is no LuaSvrGameObject in you scene. Run your game first"); return; } _includeLuaSnapshot = GUILayout.Toggle(_includeLuaSnapshot, new GUIContent("include lua snapshot")); if (GUILayout.Button("Capture")) { System.GC.Collect(); LuaDLL.lua_gc(svrGo.state.L, LuaGCOptions.LUA_GCCOLLECT, 0); if (_includeLuaSnapshot) { CsLibrary.LogicModuleProxy.ScriptProxy.EvalLua("takesnapshot()"); } var destroyedObjectNames = ObjectCache.GetAlreadyDestroyedObjectNames(svrGo.state.L); var allObjectNames = ObjectCache.GetAllManagedObjectNames(svrGo.state.L); _destroyedObjectNames.Clear(); foreach (var names in destroyedObjectNames) { var list = new List <string>(); for (int i = 0; i < names.Length; ++i) { if (i == 0) { list.Add(names[i]); } else { var stack = names[i]; var lines = stack.Split(new char[] { '\n' }, System.StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { if (!line.Contains("SLua.")) { list.Add("\t" + line.Trim()); } } } } _destroyedObjectNames.Add(list.ToArray()); } _addedObjectNames.Clear(); foreach (var names in allObjectNames) { if (!_lastAllObjectNames.Contains(names[0])) { var list = new List <string>(); for (int i = 0; i < names.Length; ++i) { if (i == 0) { list.Add(names[i]); } else { var stack = names[i]; var lines = stack.Split(new char[] { '\n' }, System.StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { if (!line.Contains("SLua.")) { list.Add("\t" + line.Trim()); } } } } _addedObjectNames.Add(list.ToArray()); } } _lastAllObjectNames.Clear(); if (null != allObjectNames) { foreach (var names in allObjectNames) { _lastAllObjectNames.Add(names[0]); } } _cachedDelegateCount = LuaState.main.cachedDelegateCount; var delegateStackTraces = LuaState.main.GetCachedDelegateStackTraces(); _delegateStackTraces.Clear(); foreach (var st in delegateStackTraces) { var list = new List <string>(); for (int i = 0; i < st.Length; ++i) { if (i == 0) { list.Add(st[i]); } else { var stack = st[i]; var lines = stack.Split(new char[] { '\n' }, System.StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { if (!line.Contains("SLua.")) { list.Add("\t" + line.Trim()); } } } } _delegateStackTraces.Add(list.ToArray()); } } if (GUILayout.Button("Copy")) { var sb = new StringBuilder(); Export(line => { sb.AppendLine(line); }); GUIUtility.systemCopyBuffer = sb.ToString(); } if (GUILayout.Button("Save")) { string file = EditorUtility.SaveFilePanel("save result", string.Empty, "luasnapshot", "txt"); if (!string.IsNullOrEmpty(file)) { using (var sw = new StreamWriter(file)) { Export(line => { sw.WriteLine(line); }); sw.Close(); } } } GUILayout.Label("LuaDelegate count:" + _cachedDelegateCount); _showDelegateStacks = EditorGUILayout.Foldout(_showDelegateStacks, "Cached Delegate:" + _delegateStackTraces.Count); if (_showDelegateStacks) { _scrollPos0 = GUILayout.BeginScrollView(_scrollPos0, GUILayout.Width(w), GUILayout.Height(240)); int ct = 0; foreach (var stacks in _delegateStackTraces) { for (int i = 0; i < stacks.Length; ++i) { GUILayout.Label(stacks[i]); } ++ct; if (ct > 2000) { break; } } GUILayout.EndScrollView(); } _showDestroyedObject = EditorGUILayout.Foldout(_showDestroyedObject, "Already Destroyed Unity Object:" + _destroyedObjectNames.Count); if (_showDestroyedObject) { _scrollPos1 = GUILayout.BeginScrollView(_scrollPos1, GUILayout.Width(w), GUILayout.Height(240)); int ct = 0; foreach (var names in _destroyedObjectNames) { for (int i = 0; i < names.Length; ++i) { GUILayout.Label(names[i]); } ++ct; if (ct > 2000) { break; } } GUILayout.EndScrollView(); } _showAllObject = EditorGUILayout.Foldout(_showAllObject, "Added Managed C# Object:" + _addedObjectNames.Count); if (_showAllObject) { _scrollPos2 = GUILayout.BeginScrollView(_scrollPos2, GUILayout.Width(w), GUILayout.Height(640)); int ct = 0; foreach (var names in _addedObjectNames) { for (int i = 0; i < names.Length; ++i) { GUILayout.Label(names[i]); } ++ct; if (ct > 2000) { break; } } GUILayout.EndScrollView(); } }
static internal object checkObj(IntPtr l, int p) { ObjectCache oc = ObjectCache.get(l); return(oc.get(l, p)); }
private static void completeInstanceMeta(IntPtr l, Type self) { //lua stack on enter: // instance metatable(-1) // static metatable(-2) // type table(-3) LuaState L = LuaState.get(l); LuaDLL.lua_pushstring(l, "__fullname"); LuaDLL.lua_pushstring(l, self.FullName); LuaDLL.lua_rawset(l, -3);//set instance metatable LuaDLL.lua_pushstring(l, "__typename"); LuaDLL.lua_pushstring(l, self.Name); LuaDLL.lua_rawset(l, -3);//set instance metatable // for instance L.index_func.push(l); LuaDLL.lua_setfield(l, -2, "__index"); L.newindex_func.push(l); LuaDLL.lua_setfield(l, -2, "__newindex"); //因为cs2lua为了更好的匹配重载方法,给存在重载的方法添加了一个签名参数 //lua元方法调用传过来的参数是没有签名参数的,这样会导致方法匹配失败。 //cs2lua翻译的代码会明确调用c#的重载操作符方法。slua对lua元方法的支持 //只保留__gc与__tostring /* * pushValue(l, lua_add); * LuaDLL.lua_setfield(l, -2, "__add"); * pushValue(l, lua_sub); * LuaDLL.lua_setfield(l, -2, "__sub"); * pushValue(l, lua_mul); * LuaDLL.lua_setfield(l, -2, "__mul"); * pushValue(l, lua_div); * LuaDLL.lua_setfield(l, -2, "__div"); * pushValue(l, lua_unm); * LuaDLL.lua_setfield(l, -2, "__unm"); * pushValue(l, lua_eq); * LuaDLL.lua_setfield(l, -2, "__eq"); * pushValue(l, lua_le); * LuaDLL.lua_setfield(l, -2, "__le"); * pushValue(l, lua_lt); * LuaDLL.lua_setfield(l, -2, "__lt"); */ pushValue(l, lua_tostring); LuaDLL.lua_setfield(l, -2, "__tostring"); LuaDLL.lua_pushcfunction(l, lua_gc); LuaDLL.lua_setfield(l, -2, "__gc"); if (self.IsValueType && isImplByLua(self)) { LuaDLL.lua_pushvalue(l, -1); LuaDLL.lua_setglobal(l, self.FullName + ".Instance");//valuetype's instance metatable assign to FullTypeName+".Instance" global variable } LuaDLL.lua_pushvalue(l, -1); LuaDLL.lua_setglobal(l, "__cslib_instance_meta_" + self.FullName.Replace(".", "_")); //instance metatable assign to "__cslib_instance_meta_{full_name_rep_dot_with_}" global variable LuaDLL.lua_setfield(l, LuaIndexes.LUA_REGISTRYINDEX, ObjectCache.getAQName(self)); //pop instance metatable and reg instance metatable }