public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext _) { TaskCompletionSource <bool> taskCompletion = new TaskCompletionSource <bool>(); try { /* * //Test PushUserData * lua.PushUserData((IntPtr)this.RandomInt); * * if(lua.GetUserType(-1, (int)TYPES.USERDATA) != (IntPtr)this.RandomInt) * { * throw new Exception("GetUserType returned incorrect pointer after PushUserData"); * } * * lua.Pop(1); */ //Test PushUserType this.Type_Id = lua.CreateMetaTable("UserDataTestType"); lua.Pop(1); lua.PushUserType((IntPtr)RandomInt2, this.Type_Id); if (lua.GetUserType(-1, this.Type_Id) != (IntPtr)this.RandomInt2) { throw new Exception("GetUserType returned incorrect pointer after PushUserType"); } //Test SetUserType lua.SetUserType(-1, (IntPtr)this.RandomInt3); if (lua.GetUserType(-1, this.Type_Id) != (IntPtr)this.RandomInt3) { throw new Exception("GetUserType returned incorrect pointer after SetUserType"); } //Additional test for GetType and IsType if (lua.GetType(-1) != this.Type_Id) { throw new Exception("GetType returned incorrect type id on usertype"); } if (!lua.IsType(-1, this.Type_Id)) { throw new Exception("IsType returned false on usertype"); } lua.Pop(1); taskCompletion.TrySetResult(true); } catch (Exception e) { taskCompletion.TrySetException(new Exception[] { e }); } return(taskCompletion.Task); }
public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext assembly_context) { TaskCompletionSource <bool> taskCompletion = new TaskCompletionSource <bool>(); try { int type1 = lua.CreateMetaTable(Guid.NewGuid().ToString()); int type2 = lua.CreateMetaTable(Guid.NewGuid().ToString()); lua.Pop(2); lua.PushUserType((IntPtr)1, type1); if (lua.GetUserType(-1, type2) != IntPtr.Zero) { throw new Exception("GetUserType returned non-zero pointer in the first test."); } if (lua.GetUserType(-1, type1) != (IntPtr)1) { throw new Exception("GetUserType returned invalid pointer in the second test."); } lua.Pop(1); lua.PushUserType((IntPtr)2, type2); if (lua.GetUserType(-1, type1) != IntPtr.Zero) { throw new Exception("GetUserType returned non-zero pointer in the third test."); } if (lua.GetUserType(-1, type2) != (IntPtr)2) { throw new Exception("GetUserType returned invalid pointer in the fourth test."); } lua.Pop(1); lua.PushString(Guid.NewGuid().ToString()); if (lua.GetUserType(-1, type1) != IntPtr.Zero) { throw new Exception("GetUserType returned invalid pointer in the fifth test."); } lua.Pop(1); taskCompletion.TrySetResult(true); } catch (Exception e) { taskCompletion.TrySetException(new Exception[] { e }); } return(taskCompletion.Task); }
public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext assembly_context) { TaskCompletionSource <bool> taskCompletion = new TaskCompletionSource <bool>(); try { int stack_state = lua.Top(); custom_type_id = lua.CreateMetaTable(Guid.NewGuid().ToString()); lua.PushManagedFunction(lua => { long value = (long)lua.GetUserType(1, custom_type_id); lua.Pop(1); lua.PushString((value * 2).ToString()); return(1); }); lua.SetField(-2, "__call"); lua.Pop(1); lua.PushUserType((IntPtr)random_integer, custom_type_id); lua.MCall(0, 1); string ret_string = lua.GetString(-1); lua.Pop(1); lua.PushMetaTable(custom_type_id); lua.PushNil(); lua.SetField(-2, "__call"); lua.Pop(1); if ((stack_state - lua.Top()) != 0) { throw new Exception("Lua stack has some values left"); } if (ret_string != (random_integer * 2).ToString()) { throw new Exception("Return string is incorrect"); } taskCompletion.TrySetResult(true); } catch (Exception e) { taskCompletion.TrySetException(new Exception[] { e }); } return(taskCompletion.Task); }
internal static int ManagedDelegateGC(IntPtr lua_state) { ILua lua = GmodInterop.GetLuaFromState(lua_state); lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB); lua.GetField(-1, ManagedFunctionIdField); int managed_delegate_type_id = (int)lua.GetNumber(-1); lua.Pop(2); IntPtr managed_delegate_handle = lua.GetUserType(1, managed_delegate_type_id); GCHandle.FromIntPtr(managed_delegate_handle).Free(); return(0); }
internal static int ManagedDelegateExecutor(IntPtr lua_state) { ILua lua = GmodInterop.GetLuaFromState(lua_state); try { lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB); lua.GetField(-1, ManagedFunctionIdField); int managed_delegate_type_id = (int)lua.GetNumber(-1); lua.Pop(2); IntPtr managed_delegate_handle = lua.GetUserType(GmodInterop.GetUpvalueIndex(1, false), managed_delegate_type_id); Func <ILua, int> managed_delegate = (Func <ILua, int>)GCHandle.FromIntPtr(managed_delegate_handle).Target; return(Math.Max(0, managed_delegate(lua))); } catch (Exception e) { lua.Pop(lua.Top()); lua.PushString(".NET Exception: " + e.ToString()); return(-1); } }
public void Load(ILua lua, bool is_serverside, ModuleAssemblyLoadContext assembly_context) { // create usertype identifier UserType_Id = lua.CreateMetaTable("Example_UserType"); // set meta-methods // see http://www.tutorialspoint.com/lua/lua_metatables.htm for all meta-methods // also checkout https://www.lua.org/pil/13.html for explanation about meta-methods/tables // __index method // __index is called when you trying to index usertype ex: // MyCSString.Length // MyCSString:ToCharArray() // FindMetaTable("Example_UserType").ToCharArray(MyCSString) lua.PushManagedFunction((lua) => { IntPtr ptr = lua.GetUserType(1, UserType_Id); if (ptr != IntPtr.Zero) { string indexingname = lua.GetString(2); switch (indexingname) { // pushing simple number case "Length": GCHandle gCHandle = GCHandle.FromIntPtr(ptr); string csString = (string)gCHandle.Target; lua.PushNumber(csString.Length); break; // pushing function case "ToCharArray": lua.PushManagedFunction((lua) => { IntPtr ptr = lua.GetUserType(1, UserType_Id); GCHandle gCHandle = GCHandle.FromIntPtr(ptr); string csString = (string)gCHandle.Target; lua.CreateTable(); char[] charArray = csString.ToCharArray(); for (int i = 0; i < charArray.Length; i++) { lua.PushNumber(i); lua.PushString(charArray[i].ToString()); lua.SetTable(-3); } return(1); }); break; case "Clone": lua.PushManagedFunction((lua) => { IntPtr ptr1 = lua.GetUserType(1, UserType_Id); GCHandle gCHandle1 = GCHandle.FromIntPtr(ptr1); string csString1 = (string)gCHandle1.Target; string csString2 = (string)csString1.Clone(); GCHandle gCHandle2 = GCHandle.Alloc(csString2, GCHandleType.Weak); IntPtr ptr2 = GCHandle.ToIntPtr(gCHandle2); lua.PushUserType(ptr2, UserType_Id); return(1); }); break; case "IndexOf": lua.PushManagedFunction((lua) => { IntPtr ptr = lua.GetUserType(1, UserType_Id); GCHandle gCHandle = GCHandle.FromIntPtr(ptr); string csString = (string)gCHandle.Target; string toFind; if (lua.IsType(2, TYPES.STRING)) { toFind = lua.GetString(2); } else if (lua.IsType(2, UserType_Id)) { IntPtr ptr2 = lua.GetUserType(2, UserType_Id); GCHandle gCHandle2 = GCHandle.FromIntPtr(ptr2); toFind = (string)gCHandle2.Target; } else { return(0); } int indexOf = csString.IndexOf(toFind); lua.PushNumber(indexOf); return(1); }); break; case "Contains": lua.PushManagedFunction((lua) => { IntPtr ptr = lua.GetUserType(1, UserType_Id); GCHandle gCHandle = GCHandle.FromIntPtr(ptr); string csString = (string)gCHandle.Target; string toFind; if (lua.IsType(2, TYPES.STRING)) { toFind = lua.GetString(2); } else if (lua.IsType(2, UserType_Id)) { IntPtr ptr2 = lua.GetUserType(2, UserType_Id); GCHandle gCHandle2 = GCHandle.FromIntPtr(ptr2); toFind = (string)gCHandle2.Target; } else { return(0); } bool contains = csString.Contains(toFind); lua.PushBool(contains); return(1); }); break; default: lua.PushNil(); break; } } else { Console.WriteLine("nil passed to __index"); lua.PushNil(); } // function will return 1 result return(1); }); lua.SetField(-2, "__index"); lua.PushManagedFunction((lua) => { // 1 - stands for 1st passed to function argument IntPtr ptr = lua.GetUserType(1, UserType_Id); if (ptr != IntPtr.Zero) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); string csString = (string)gCHandle.Target; lua.PushString(csString); } else { Console.WriteLine("nil passed to __tostring"); lua.PushNil(); } return(1); }); lua.SetField(-2, "__tostring"); // equal (==) method lua.PushManagedFunction((lua) => { IntPtr ptr1 = lua.GetUserType(1, UserType_Id); IntPtr ptr2 = lua.GetUserType(2, UserType_Id); // if we have same pointers, then objects are same if (ptr1 == ptr2) { lua.PushBool(true); } // check if both pointers not zero else if (ptr1 != IntPtr.Zero && ptr2 != IntPtr.Zero) { GCHandle gCHandle1 = GCHandle.FromIntPtr(ptr1); GCHandle gCHandle2 = GCHandle.FromIntPtr(ptr2); string csString1 = (string)gCHandle1.Target; string csString2 = (string)gCHandle2.Target; lua.PushBool(csString1 == csString2); } // some of pointers is Zero, we'll not compare them else { lua.PushBool(false); } return(1); }); lua.SetField(-2, "__eq"); // Dispose() in lua lua.PushManagedFunction((lua) => { // 1 - stands for 1st passed to function argument IntPtr ptr = lua.GetUserType(1, UserType_Id); if (ptr != IntPtr.Zero) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); string csString = (string)gCHandle.Target; Console.WriteLine($"csString ({csString}) is garbage collected"); gCHandle.Free(); } else { Console.WriteLine("nil passed to __gc"); } return(0); }); lua.SetField(-2, "__gc"); lua.Pop(); // now we need to somehow create it lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB); lua.PushManagedFunction((lua) => { string csString = lua.GetString(1); GCHandle gCHandle = GCHandle.Alloc(csString, GCHandleType.Weak); IntPtr ptr = GCHandle.ToIntPtr(gCHandle); lua.PushUserType(ptr, UserType_Id); return(1); }); lua.SetField(-2, "CreateCSString"); lua.Pop(); }
void IModule.Load(ILua lua, bool is_serverside, ModuleAssemblyLoadContext assembly_context) { if (is_serverside) { throw new Exception("Must be loaded from client"); } string platformIdentifier = OperatingSystem.IsWindows() ? "win-x64" : "linux-x64"; assembly_context.SetCustomNativeLibraryResolver((ctx, str) => { if (str.Contains("sourcesdkc")) { if (sourcesdkc == IntPtr.Zero) { Console.WriteLine("loading sourcesdkc"); sourcesdkc = NativeLibrary.Load($"./garrysmod/lua/bin/Modules/GetRenderTargetExample/runtimes/{platformIdentifier}/native/sourcesdkc"); Console.WriteLine($"loaded sourcesdkc: {sourcesdkc != IntPtr.Zero}"); } return(sourcesdkc); } return(IntPtr.Zero); }); if (interfaceh.Sys_LoadInterface("vguimatsurface", ISurface.VGUI_SURFACE_INTERFACE_VERSION, out _, out IntPtr isurfacePtr)) { surface = new(isurfacePtr); } else { throw new Exception("failed loading vguimatsurface"); } if (interfaceh.Sys_LoadInterface("materialsystem", IMaterialSystem.MATERIAL_SYSTEM_INTERFACE_VERSION, out _, out IntPtr materialSystemPtr)) { materialSystem = new(materialSystemPtr); } else { Console.WriteLine("failed loading materialsystem"); } lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB); lua.GetField(-1, "GetRenderTarget"); lua.PushString("ExampleRTwithAlpha"); lua.PushNumber(512); lua.PushNumber(512); lua.MCall(3, 1); rt = lua.GetUserType(-1, (int)TYPES.TEXTURE); lua.Pop(); lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB); lua.GetField(-1, "CreateMaterial"); lua.PushString("ExampleRTwithAlpha_Mat"); lua.PushString("UnlitGeneric"); lua.CreateTable(); { lua.PushString("$basetexture"); lua.PushString("ExampleRTwithAlpha"); lua.SetTable(-3); lua.PushString("$translucent"); lua.PushString("1"); lua.SetTable(-3); } lua.MCall(3, 1); mat = lua.GetUserType(-1, (int)TYPES.MATERIAL); lua.Pop(); lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB); lua.GetField(-1, "hook"); lua.GetField(-1, "Add"); lua.PushString("HUDPaint"); lua.PushString("ExampleRTwithAlpha_Render"); lua.PushManagedFunction(Render); lua.MCall(3, 0); lua.Pop(); }