Ejemplo n.º 1
0
        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);
            }
        }
Ejemplo n.º 6
0
        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();
        }
Ejemplo n.º 7
0
        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();
        }