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 );"); }
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(); }
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(); }
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(); }
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(); }
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(); }
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 );"); }
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(); }
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(); }