/* * Pushes a new object into the Lua stack with the provided * metatable */ private void PushNewObject(LuaState luaState, object o, int index, string metatable) { if (metatable == "luaNet_metatable") { // Gets or creates the metatable for the object's type luaState.GetMetaTable(o.GetType().AssemblyQualifiedName); if (luaState.IsNil(-1)) { luaState.SetTop(-2); luaState.NewMetaTable(o.GetType().AssemblyQualifiedName); luaState.PushString("cache"); luaState.NewTable(); luaState.RawSet(-3); luaState.PushLightUserData(_tagPtr); luaState.PushNumber(1); luaState.RawSet(-3); luaState.PushString("__index"); luaState.PushString("luaNet_indexfunction"); luaState.RawGet(LuaRegistry.Index); luaState.RawSet(-3); luaState.PushString("__gc"); luaState.PushCFunction(MetaFunctions.GcFunction); luaState.RawSet(-3); luaState.PushString("__tostring"); luaState.PushCFunction(MetaFunctions.ToStringFunction); luaState.RawSet(-3); luaState.PushString("__concat"); luaState.PushCFunction(MetaFunctions.ConcatFunction); luaState.RawSet(-3); luaState.PushString("__newindex"); luaState.PushCFunction(MetaFunctions.NewIndexFunction); luaState.RawSet(-3); // Bind C# operator with Lua metamethods (__add, __sub, __mul) RegisterOperatorsFunctions(luaState, o.GetType()); RegisterCallMethodForDelegate(luaState, o); } } else { luaState.GetMetaTable(metatable); } // Stores the object index in the Lua list and pushes the // index into the Lua stack luaState.GetMetaTable("luaNet_objects"); luaState.NewUData(index); luaState.PushCopy(-3); luaState.Remove(-4); luaState.SetMetaTable(-2); luaState.PushCopy(-1); luaState.RawSetInteger(-3, index); luaState.Remove(-2); }
private int UnregisterTableInternal(LuaState luaState) { if (!luaState.GetMetaTable(1)) { ThrowError(luaState, "unregister_table: arg is not valid table"); return(0); } luaState.PushString("__index"); luaState.GetTable(-2); object obj = GetRawNetObject(luaState, -1); if (obj == null) { ThrowError(luaState, "unregister_table: arg is not valid table"); } var luaTableField = obj.GetType().GetField("__luaInterface_luaTable"); if (luaTableField == null) { ThrowError(luaState, "unregister_table: arg is not valid table"); } // ReSharper disable once PossibleNullReferenceException luaTableField.SetValue(obj, null); luaState.PushNil(); luaState.SetMetaTable(1); luaState.PushString("base"); luaState.PushNil(); luaState.SetTable(1); return(0); }
public static IntPtr CheckUData(this LuaState state, int ud, string name) { IntPtr p = state.ToUserData(ud); if (p == IntPtr.Zero) { return(IntPtr.Zero); } if (!state.GetMetaTable(ud)) { return(IntPtr.Zero); } state.GetField(LuaRegistry.Index, name); bool isEqual = state.RawEqual(-1, -2); state.Pop(2); if (isEqual) { return(p); } return(IntPtr.Zero); }
public static bool CheckMetaTable(this LuaState state, int index, IntPtr tag) { if (!state.GetMetaTable(index)) { return(false); } state.PushLightUserData(tag); state.RawGet(-2); bool isNotNil = !state.IsNil(-1); state.SetTop(-3); return(isNotNil); }
private int UnregisterTableInternal(LuaState luaState) { try { if (luaState.GetMetaTable(1)) { luaState.PushString("__index"); luaState.GetTable(-2); object obj = GetRawNetObject(luaState, -1); if (obj == null) { ThrowError(luaState, "unregister_table: arg is not valid table"); } var luaTableField = obj.GetType().GetField("__luaInterface_luaTable"); if (luaTableField == null) { ThrowError(luaState, "unregister_table: arg is not valid table"); } luaTableField.SetValue(obj, null); luaState.PushNil(); luaState.SetMetaTable(1); luaState.PushString("base"); luaState.PushNil(); luaState.SetTable(1); } else { ThrowError(luaState, "unregister_table: arg is not valid table"); } } catch (Exception e) { ThrowError(luaState, e.Message); } return(0); }
/* * Pushes a CLR object into the Lua stack as an userdata * with the provided metatable */ internal void PushObject(LuaState luaState, object o, string metatable) { int index = -1; // Pushes nil if (o == null) { luaState.PushNil(); return; } // Object already in the list of Lua objects? Push the stored reference. bool found = (!o.GetType().IsValueType || o.GetType().IsEnum) && _objectsBackMap.TryGetValue(o, out index); if (found) { luaState.GetMetaTable("luaNet_objects"); luaState.RawGetInteger(-1, index); // Note: starting with lua5.1 the garbage collector may remove weak reference items (such as our luaNet_objects values) when the initial GC sweep // occurs, but the actual call of the __gc finalizer for that object may not happen until a little while later. During that window we might call // this routine and find the element missing from luaNet_objects, but collectObject() has not yet been called. In that case, we go ahead and call collect // object here // did we find a non nil object in our table? if not, we need to call collect object var type = luaState.Type(-1); if (type != LuaType.Nil) { luaState.Remove(-2); // drop the metatable - we're going to leave our object on the stack return; } // MetaFunctions.dumpStack(this, luaState); luaState.Remove(-1); // remove the nil object value luaState.Remove(-1); // remove the metatable CollectObject(o, index); // Remove from both our tables and fall out to get a new ID } index = AddObject(o); PushNewObject(luaState, o, index, metatable); }