예제 #1
0
        private void CallbackCall(SteamApiDefinition.StructDef c)
        {
            WriteLine("//");
            WriteLine("// Create the functions we need for the vtable");
            WriteLine("//");

            StartBlock("if ( Facepunch.Steamworks.Config.UseThisCall )");
            {
                CallFunctions(c, "ThisCall", "_");
            }
            Else();
            {
                CallFunctions(c, "StdCall", "");
            }
            EndBlock();

            WriteLine("");
            WriteLine("//");
            WriteLine("// Create the callback object");
            WriteLine("//");
            WriteLine($"var cb = new Callback();");
            WriteLine($"cb.vTablePtr = handle.vTablePtr;");
            WriteLine($"cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0;");
            WriteLine($"cb.CallbackId = CallbackId;");

            WriteLine("");
            WriteLine("//");
            WriteLine("// Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native");
            WriteLine("//");
            WriteLine($"handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned );");
        }
예제 #2
0
        private void Callback(SteamApiDefinition.StructDef c)
        {
            WriteLine();
            StartBlock($"internal static void Register( Facepunch.Steamworks.BaseSteamworks steamworks )");
            {
                WriteLine($"var handle = new CallbackHandle( steamworks );");
                WriteLine($"");

                CallbackCall(c);

                WriteLine("");
                WriteLine("//");
                WriteLine("// Register the callback with Steam");
                WriteLine("//");
                WriteLine($"steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId );");

                WriteLine();
                WriteLine("steamworks.RegisterCallbackHandle( handle );");
            }
            EndBlock();

            WriteLine();
            WriteLine("[MonoPInvokeCallback]");
            WriteLine("internal static void OnResultThis( IntPtr self, IntPtr param ){ OnResult( param ); }");
            WriteLine("[MonoPInvokeCallback]");
            WriteLine("internal static void OnResultWithInfoThis( IntPtr self, IntPtr param, bool failure, SteamNative.SteamAPICall_t call ){ OnResultWithInfo( param, failure, call ); }");
            WriteLine("[MonoPInvokeCallback]");
            WriteLine("internal static int OnGetSizeThis( IntPtr self ){ return OnGetSize(); }");
            WriteLine("[MonoPInvokeCallback]");
            WriteLine("internal static int OnGetSize(){ return StructSize(); }");

            WriteLine();
            WriteLine("[MonoPInvokeCallback]");
            StartBlock("internal static void OnResult( IntPtr param )");
            {
                WriteLine($"OnResultWithInfo( param, false, 0 );");
            }
            EndBlock();

            WriteLine();
            WriteLine("[MonoPInvokeCallback]");
            StartBlock("internal static void OnResultWithInfo( IntPtr param, bool failure, SteamNative.SteamAPICall_t call )");
            {
                WriteLine($"if ( failure ) return;");
                WriteLine();
                WriteLine("var value = FromPointer( param );");

                WriteLine();
                WriteLine("if ( Facepunch.Steamworks.Client.Instance != null )");
                WriteLine($"    Facepunch.Steamworks.Client.Instance.OnCallback<{c.Name}>( value );");

                WriteLine();
                WriteLine("if ( Facepunch.Steamworks.Server.Instance != null )");
                WriteLine($"    Facepunch.Steamworks.Server.Instance.OnCallback<{c.Name}>( value );");
            }
            EndBlock();
        }
예제 #3
0
 private void CallResult(SteamApiDefinition.StructDef c)
 {
     WriteLine();
     StartBlock($"internal static CallResult<{c.Name}> CallResult( Facepunch.Steamworks.BaseSteamworks steamworks, SteamAPICall_t call, Action<{c.Name}, bool> CallbackFunction )");
     {
         WriteLine($"return new CallResult<{c.Name}>( steamworks, call, CallbackFunction, FromPointer, StructSize(), CallbackId );");
     }
     EndBlock();
 }
예제 #4
0
        private void CallFunctions(SteamApiDefinition.StructDef c, string ThisCall, string ThisArg)
        {
            var ThisArgC = ThisArg.Length > 0 ? $"{ThisArg}, " : "";
            var This     = ThisArg.Length > 0 ? "This" : "";

            WriteLine("//");
            WriteLine("// Create the VTable by manually allocating the memory and copying across");
            WriteLine("//");
            StartBlock("if ( Platform.IsWindows )");
            {
                WriteLine($"handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTableWin{This} ) ) );");
                StartBlock($"var vTable = new Callback.VTableWin{This}");
                {
                    WriteLine($"ResultA = OnResult{This},");
                    WriteLine($"ResultB = OnResultWithInfo{This},");
                    WriteLine($"GetSize = OnGetSize{This},");
                }
                EndBlock(";");

                WriteLine("handle.FuncA = GCHandle.Alloc( vTable.ResultA );");
                WriteLine("handle.FuncB = GCHandle.Alloc( vTable.ResultB );");
                WriteLine("handle.FuncC = GCHandle.Alloc( vTable.GetSize );");

                WriteLine("Marshal.StructureToPtr( vTable, handle.vTablePtr, false );");
            }
            Else();
            {
                WriteLine($"handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable{This} ) ) );");
                StartBlock($"var vTable = new Callback.VTable{This}");
                {
                    WriteLine($"ResultA = OnResult{This},");
                    WriteLine($"ResultB = OnResultWithInfo{This},");
                    WriteLine($"GetSize = OnGetSize{This},");
                }
                EndBlock(";");

                WriteLine("handle.FuncA = GCHandle.Alloc( vTable.ResultA );");
                WriteLine("handle.FuncB = GCHandle.Alloc( vTable.ResultB );");
                WriteLine("handle.FuncC = GCHandle.Alloc( vTable.GetSize );");

                WriteLine("Marshal.StructureToPtr( vTable, handle.vTablePtr, false );");
            }
            EndBlock();
        }
예제 #5
0
        private void Callback(SteamApiDefinition.StructDef c)
        {
            WriteLine();
            StartBlock($"public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action<{c.Name}, bool> CallbackFunction )");
            {
                WriteLine($"var handle = new CallbackHandle();");
                WriteLine($"handle.steamworks = steamworks;");
                WriteLine($"");

                CallbackCallresultShared(c, false);

                WriteLine("");
                WriteLine("//");
                WriteLine("// Register the callback with Steam");
                WriteLine("//");
                WriteLine($"steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId );");

                WriteLine();
                WriteLine("steamworks.RegisterCallbackHandle( handle );");
            }
            EndBlock();
        }
예제 #6
0
        private void CallResult(SteamApiDefinition.StructDef c)
        {
            WriteLine();
            StartBlock($"public static CallbackHandle CallResult( Facepunch.Steamworks.BaseSteamworks steamworks, SteamAPICall_t call, Action<{c.Name}, bool> CallbackFunction )");
            {
                WriteLine($"var handle = new CallbackHandle();");
                WriteLine($"handle.steamworks = steamworks;");
                WriteLine($"handle.CallResultHandle = call;");
                WriteLine($"handle.CallResult = true;");
                WriteLine($"");

                CallbackCallresultShared(c, true);

                WriteLine("");
                WriteLine("//");
                WriteLine("// Register the callback with Steam");
                WriteLine("//");
                WriteLine($"steamworks.native.api.SteamAPI_RegisterCallResult( handle.PinnedCallback.AddrOfPinnedObject(), call );");

                WriteLine();
                WriteLine("return handle;");
            }
            EndBlock();
        }
예제 #7
0
        private void CallresultFunctions(SteamApiDefinition.StructDef c, bool Result, string ThisCall, string ThisArg)
        {
            var ThisArgC = ThisArg.Length > 0 ? $"{ThisArg}, " : "";

            if (Result)
            {
                WriteLine($"Callback.{ThisCall}.Result         funcA = ( {ThisArgC}p ) => {{  handle.Dispose(); CallbackFunction( FromPointer( p ), false ); }};");
                StartBlock($"Callback.{ThisCall}.ResultWithInfo funcB = ( {ThisArgC}p, bIOFailure, hSteamAPICall ) => ");
                {
                    WriteLine("if ( hSteamAPICall != call ) return;");
                    WriteLine();
                    WriteLine("handle.CallResultHandle = 0;");
                    WriteLine("handle.Dispose();");
                    WriteLine();
                    WriteLine("CallbackFunction( FromPointer( p ), bIOFailure );");
                }
                EndBlock(";");
            }
            else
            {
                WriteLine($"Callback.{ThisCall}.Result         funcA = ( {ThisArgC}p ) => {{ CallbackFunction( FromPointer( p ), false ); }};");
                WriteLine($"Callback.{ThisCall}.ResultWithInfo funcB = ( {ThisArgC}p, bIOFailure, hSteamAPICall ) => {{ CallbackFunction( FromPointer( p ), bIOFailure ); }};");
            }

            WriteLine($"Callback.{ThisCall}.GetSize        funcC = ( {ThisArg} ) => Marshal.SizeOf( typeof( {c.Name} ) );");
            WriteLine();
            WriteLine("//");
            WriteLine("// If this platform is PackSmall, use PackSmall versions of everything instead");
            WriteLine("//");
            StartBlock("if ( Platform.PackSmall )");
            {
                WriteLine($"funcC = ( {ThisArg} ) => Marshal.SizeOf( typeof( PackSmall ) );");
            }
            EndBlock();

            WriteLine("");
            WriteLine("//");
            WriteLine("// Allocate a handle to each function, so they don't get disposed");
            WriteLine("//");
            WriteLine("handle.FuncA = GCHandle.Alloc( funcA );");
            WriteLine("handle.FuncB = GCHandle.Alloc( funcB );");
            WriteLine("handle.FuncC = GCHandle.Alloc( funcC );");
            WriteLine();

            WriteLine("//");
            WriteLine("// Create the VTable by manually allocating the memory and copying across");
            WriteLine("//");
            WriteLine("handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) );");
            StartBlock("var vTable = new Callback.VTable()");
            {
                WriteLine("ResultA = Marshal.GetFunctionPointerForDelegate( funcA ),");
                WriteLine("ResultB = Marshal.GetFunctionPointerForDelegate( funcB ),");
                WriteLine("GetSize = Marshal.GetFunctionPointerForDelegate( funcC ),");
            }
            EndBlock(";");

            WriteLine("//");
            WriteLine("// The order of these functions are swapped on Windows");
            WriteLine("//");
            StartBlock("if ( Platform.IsWindows )");
            {
                WriteLine("vTable.ResultA = Marshal.GetFunctionPointerForDelegate( funcB );");
                WriteLine("vTable.ResultB = Marshal.GetFunctionPointerForDelegate( funcA );");
            }
            EndBlock();

            WriteLine("Marshal.StructureToPtr( vTable, handle.vTablePtr, false );");
        }
예제 #8
0
        private void CallResult(SteamApiDefinition.StructDef c)
        {
            WriteLine();
            StartBlock($"public static CallbackHandle CallResult( Facepunch.Steamworks.BaseSteamworks steamworks, SteamAPICall_t call, Action<{c.Name}, bool> CallbackFunction )");
            {
                WriteLine($"var handle = new CallbackHandle();");
                WriteLine($"handle.steamworks = steamworks;");
                WriteLine($"handle.CallResultHandle = call;");
                WriteLine($"handle.CallResult = true;");
                WriteLine($"");

                WriteLine("//");
                WriteLine("// Create the functions we need for the vtable");
                WriteLine("//");
                WriteLine($"Callback.Result         funcA = ( _, p ) => {{  handle.Dispose(); CallbackFunction( FromPointer( p ), false ); }};");
                StartBlock($"Callback.ResultWithInfo funcB = ( _, p, bIOFailure, hSteamAPICall ) => ");
                {
                    WriteLine("if ( hSteamAPICall != call ) return;");
                    WriteLine();
                    WriteLine("handle.CallResultHandle = 0;");
                    WriteLine("handle.Dispose();");
                    WriteLine();
                    WriteLine("CallbackFunction( FromPointer( p ), bIOFailure );");
                }
                EndBlock(";");
                WriteLine($"Callback.GetSize        funcC = ( _ ) => {{ return Marshal.SizeOf( typeof( {c.Name} ) ); }};");
                WriteLine();
                WriteLine("//");
                WriteLine("// If this platform is PackSmall, use PackSmall versions of everything instead");
                WriteLine("//");
                StartBlock("if ( Platform.PackSmall )");
                {
                    WriteLine($"funcC = ( _ ) => {{ return Marshal.SizeOf( typeof( PackSmall ) ); }};");
                }
                EndBlock();

                WriteLine("");
                WriteLine("//");
                WriteLine("// Allocate a handle to each function, so they don't get disposed");
                WriteLine("//");
                WriteLine("handle.FuncA = GCHandle.Alloc( funcA );");
                WriteLine("handle.FuncB = GCHandle.Alloc( funcB );");
                WriteLine("handle.FuncC = GCHandle.Alloc( funcC );");
                WriteLine();

                WriteLine("//");
                WriteLine("// Create the VTable by manually allocating the memory and copying across");
                WriteLine("//");
                WriteLine("handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) );");
                StartBlock("var vTable = new Callback.VTable()");
                {
                    WriteLine("ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention");
                    WriteLine("ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first");
                    WriteLine("GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works");
                }
                EndBlock(";");

                WriteLine("Marshal.StructureToPtr( vTable, handle.vTablePtr, false );");

                WriteLine("");
                WriteLine("//");
                WriteLine("// Create the callback object");
                WriteLine("//");
                WriteLine($"var cb = new Callback();");
                WriteLine($"cb.vTablePtr = handle.vTablePtr;");
                WriteLine($"cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0;");
                WriteLine($"cb.CallbackId = CallbackId;");

                WriteLine("");
                WriteLine("//");
                WriteLine("// Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native");
                WriteLine("//");
                WriteLine($"handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned );");

                WriteLine("");
                WriteLine("//");
                WriteLine("// Register the callback with Steam");
                WriteLine("//");
                WriteLine($"steamworks.native.api.SteamAPI_RegisterCallResult( handle.PinnedCallback.AddrOfPinnedObject(), call );");

                WriteLine();
                WriteLine("return handle;");
            }
            EndBlock();
        }
예제 #9
0
        private void Callback(SteamApiDefinition.StructDef c)
        {
            WriteLine();
            StartBlock($"public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action<{c.Name}, bool> CallbackFunction )");
            {
                WriteLine($"var handle = new CallbackHandle();");
                WriteLine($"handle.steamworks = steamworks;");
                WriteLine($"");

                WriteLine("//");
                WriteLine("// Create the functions we need for the vtable");
                WriteLine("//");
                WriteLine($"Callback.Result         funcA = ( _, p ) => {{ CallbackFunction( FromPointer( p ), false ); }};");
                WriteLine($"Callback.ResultWithInfo funcB = ( _, p, bIOFailure, hSteamAPICall ) => {{ CallbackFunction( FromPointer( p ), bIOFailure ); }};");
                WriteLine($"Callback.GetSize        funcC = ( _ ) => {{ return Marshal.SizeOf( typeof( {c.Name} ) ); }};");
                WriteLine();
                WriteLine("//");
                WriteLine("// If this platform is PackSmall, use PackSmall versions of everything instead");
                WriteLine("//");
                StartBlock("if ( Platform.PackSmall )");
                {
                    WriteLine($"funcC = ( _ ) => {{ return Marshal.SizeOf( typeof( PackSmall ) ); }};");
                }
                EndBlock();

                WriteLine("");
                WriteLine("//");
                WriteLine("// Allocate a handle to each function, so they don't get disposed");
                WriteLine("//");
                WriteLine("handle.FuncA = GCHandle.Alloc( funcA );");
                WriteLine("handle.FuncB = GCHandle.Alloc( funcB );");
                WriteLine("handle.FuncC = GCHandle.Alloc( funcC );");
                WriteLine();

                WriteLine("//");
                WriteLine("// Create the VTable by manually allocating the memory and copying across");
                WriteLine("//");
                WriteLine("handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) );");
                StartBlock("var vTable = new Callback.VTable()");
                {
                    WriteLine("ResultA = Marshal.GetFunctionPointerForDelegate( funcA ),");
                    WriteLine("ResultB = Marshal.GetFunctionPointerForDelegate( funcB ),");
                    WriteLine("GetSize = Marshal.GetFunctionPointerForDelegate( funcC ),");
                }
                EndBlock(";");

                WriteLine("//");
                WriteLine("// The order of these functions are swapped on Windows");
                WriteLine("//");
                StartBlock("if ( Platform.Os == OperatingSystem.Windows )");
                {
                    WriteLine("vTable.ResultA = Marshal.GetFunctionPointerForDelegate( funcB );");
                    WriteLine("vTable.ResultB = Marshal.GetFunctionPointerForDelegate( funcA );");
                }
                EndBlock();

                WriteLine("Marshal.StructureToPtr( vTable, handle.vTablePtr, false );");

                WriteLine("");
                WriteLine("//");
                WriteLine("// Create the callback object");
                WriteLine("//");
                WriteLine($"var cb = new Callback();");
                WriteLine($"cb.vTablePtr = handle.vTablePtr;");
                WriteLine($"cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0;");
                WriteLine($"cb.CallbackId = CallbackId;");

                WriteLine("");
                WriteLine("//");
                WriteLine("// Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native");
                WriteLine("//");
                WriteLine($"handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned );");

                WriteLine("");
                WriteLine("//");
                WriteLine("// Register the callback with Steam");
                WriteLine("//");
                WriteLine($"steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId );");

                WriteLine();
                WriteLine("steamworks.RegisterCallbackHandle( handle );");
            }
            EndBlock();
        }