Callbacks uses static methods (IL2CPP Compatible)

This commit is contained in:
Garry Newman 2018-02-14 17:40:16 +00:00
parent 04c7eb59dc
commit 68b409d163
18 changed files with 13364 additions and 10680 deletions

View File

@ -41,6 +41,8 @@ protected BaseSteamworks( uint appId )
public virtual void Dispose()
{
Callbacks.Clear();
foreach ( var h in CallbackHandles )
{
h.Dispose();
@ -157,5 +159,37 @@ public void UpdateWhile( Func<bool> func )
#endif
}
}
Dictionary<Type, List<Action<object>>> Callbacks = new Dictionary<Type, List<Action<object>>>();
internal List<Action<object>> CallbackList( Type T )
{
List<Action<object>> list = null;
if ( !Callbacks.TryGetValue( T, out list ) )
{
list = new List<Action<object>>();
Callbacks[T] = list;
}
return list;
}
internal void OnCallback<T>( T data )
{
var list = CallbackList( typeof( T ) );
foreach ( var i in list )
{
i( data );
}
}
internal void RegisterCallback<T>( Action<T> func )
{
var list = CallbackList( typeof( T ) );
list.Add( ( o ) => func( (T) o ) );
}
}
}

View File

@ -89,6 +89,12 @@ public Client( uint appId ) : base( appId )
//
SetupCommonInterfaces();
//
// Register Callbacks
//
SteamNative.Callbacks.RegisterCallbacks( this );
//
// Client only interfaces
//
@ -121,8 +127,6 @@ public Client( uint appId ) : base( appId )
CurrentLanguage = native.apps.GetCurrentGameLanguage();
AvailableLanguages = native.apps.GetAvailableGameLanguages().Split( new[] {';'}, StringSplitOptions.RemoveEmptyEntries ); // TODO: Assumed colon separated
//
// Run update, first call does some initialization
//

View File

@ -22,8 +22,8 @@ internal Achievements( Client c )
client = c;
All = new Achievement[0];
SteamNative.UserStatsReceived_t.RegisterCallback( c, UserStatsReceived );
SteamNative.UserStatsStored_t.RegisterCallback( c, UserStatsStored );
c.RegisterCallback<UserStatsReceived_t>( UserStatsReceived );
c.RegisterCallback<UserStatsStored_t>( UserStatsStored );
Refresh();
}
@ -100,9 +100,8 @@ public bool Reset( string identifier )
return client.native.userstats.ClearAchievement( identifier );
}
private void UserStatsReceived( UserStatsReceived_t stats, bool isError )
private void UserStatsReceived( UserStatsReceived_t stats )
{
if ( isError ) return;
if ( stats.GameID != client.AppId ) return;
Refresh();
@ -110,9 +109,8 @@ private void UserStatsReceived( UserStatsReceived_t stats, bool isError )
OnUpdated?.Invoke();
}
private void UserStatsStored( UserStatsStored_t stats, bool isError )
private void UserStatsStored( UserStatsStored_t stats )
{
if ( isError ) return;
if ( stats.GameID != client.AppId ) return;
Refresh();

View File

@ -163,7 +163,7 @@ internal Friends( Client c )
{
client = c;
SteamNative.PersonaStateChange_t.RegisterCallback( client, OnPersonaStateChange );
client.RegisterCallback<SteamNative.PersonaStateChange_t>( OnPersonaStateChange );
}
/// <summary>
@ -357,9 +357,9 @@ public SteamFriend Get( ulong steamid )
return f;
}
private void OnPersonaStateChange( PersonaStateChange_t data, bool error )
private void OnPersonaStateChange( PersonaStateChange_t data )
{
// HUH
}
}

View File

@ -36,12 +36,13 @@ public enum Type : int
public Lobby( Client c )
{
client = c;
SteamNative.LobbyDataUpdate_t.RegisterCallback( client, OnLobbyDataUpdatedAPI );
SteamNative.LobbyChatMsg_t.RegisterCallback( client, OnLobbyChatMessageRecievedAPI );
SteamNative.LobbyChatUpdate_t.RegisterCallback( client, OnLobbyStateUpdatedAPI );
SteamNative.GameLobbyJoinRequested_t.RegisterCallback( client, OnLobbyJoinRequestedAPI );
SteamNative.LobbyInvite_t.RegisterCallback( client, OnUserInvitedToLobbyAPI );
SteamNative.PersonaStateChange_t.RegisterCallback( client, OnLobbyMemberPersonaChangeAPI );
client.RegisterCallback<SteamNative.LobbyDataUpdate_t>( OnLobbyDataUpdatedAPI );
client.RegisterCallback<SteamNative.LobbyChatMsg_t>( OnLobbyChatMessageRecievedAPI );
client.RegisterCallback<SteamNative.LobbyChatUpdate_t>( OnLobbyStateUpdatedAPI );
client.RegisterCallback<SteamNative.GameLobbyJoinRequested_t>( OnLobbyJoinRequestedAPI );
client.RegisterCallback<SteamNative.LobbyInvite_t>( OnUserInvitedToLobbyAPI );
client.RegisterCallback<SteamNative.PersonaStateChange_t>( OnLobbyMemberPersonaChangeAPI );
}
/// <summary>
@ -242,9 +243,10 @@ public string GetMemberData( ulong steamID, string key )
return client.native.matchmaking.GetLobbyMemberData( CurrentLobby, steamID, key );
}
internal void OnLobbyDataUpdatedAPI( LobbyDataUpdate_t callback, bool error )
internal void OnLobbyDataUpdatedAPI( LobbyDataUpdate_t callback )
{
if ( error || (callback.SteamIDLobby != CurrentLobby) ) { return; }
if ( callback.SteamIDLobby != CurrentLobby ) return;
if ( callback.SteamIDLobby == CurrentLobby ) //actual lobby data was updated by owner
{
UpdateLobbyData();
@ -320,10 +322,10 @@ public Type LobbyType
private static byte[] chatMessageData = new byte[1024 * 4];
private unsafe void OnLobbyChatMessageRecievedAPI( LobbyChatMsg_t callback, bool error )
private unsafe void OnLobbyChatMessageRecievedAPI( LobbyChatMsg_t callback )
{
//from Client.Networking
if ( error || callback.SteamIDLobby != CurrentLobby )
if ( callback.SteamIDLobby != CurrentLobby )
return;
SteamNative.CSteamID steamid = 1;
@ -380,9 +382,9 @@ public enum MemberStateChange
Banned = ChatMemberStateChange.Banned,
}
internal void OnLobbyStateUpdatedAPI( LobbyChatUpdate_t callback, bool error )
internal void OnLobbyStateUpdatedAPI( LobbyChatUpdate_t callback )
{
if ( error || callback.SteamIDLobby != CurrentLobby )
if ( callback.SteamIDLobby != CurrentLobby )
return;
MemberStateChange change = (MemberStateChange)callback.GfChatMemberStateChange;
@ -555,9 +557,9 @@ public bool InviteUserToLobby( ulong friendID )
return client.native.matchmaking.InviteUserToLobby( CurrentLobby, friendID );
}
internal void OnUserInvitedToLobbyAPI( LobbyInvite_t callback, bool error )
internal void OnUserInvitedToLobbyAPI( LobbyInvite_t callback )
{
if ( error || (callback.GameID != client.AppId) ) { return; }
if ( callback.GameID != client.AppId ) return;
if ( OnUserInvitedToLobby != null ) { OnUserInvitedToLobby( callback.SteamIDLobby, callback.SteamIDUser ); }
}
@ -570,18 +572,17 @@ internal void OnUserInvitedToLobbyAPI( LobbyInvite_t callback, bool error )
/// <summary>
/// Joins a lobby if a request was made to join the lobby through the friends list or an invite
/// </summary>
internal void OnLobbyJoinRequestedAPI( GameLobbyJoinRequested_t callback, bool error )
internal void OnLobbyJoinRequestedAPI( GameLobbyJoinRequested_t callback )
{
if ( error ) { return; }
Join( callback.SteamIDLobby );
}
/// <summary>
/// Makes sure we send an update callback if a Lobby user updates their information
/// </summary>
internal void OnLobbyMemberPersonaChangeAPI( PersonaStateChange_t callback, bool error )
internal void OnLobbyMemberPersonaChangeAPI( PersonaStateChange_t callback )
{
if ( error || !UserIsInCurrentLobby( callback.SteamID ) ) { return; }
if ( !UserIsInCurrentLobby( callback.SteamID ) ) return;
if ( OnLobbyMemberDataUpdated != null ) { OnLobbyMemberDataUpdated( callback.SteamID ); }
}

View File

@ -101,7 +101,7 @@ void OnLobbyList(LobbyMatchList_t callback, bool error)
{
//else we need to get the info for the missing lobby
client.native.matchmaking.RequestLobbyData(lobby);
SteamNative.LobbyDataUpdate_t.RegisterCallback(client, OnLobbyDataUpdated);
client.RegisterCallback<SteamNative.LobbyDataUpdate_t>( OnLobbyDataUpdated );
}
}
@ -121,7 +121,7 @@ void checkFinished()
Finished = false;
}
void OnLobbyDataUpdated(LobbyDataUpdate_t callback, bool error)
void OnLobbyDataUpdated(LobbyDataUpdate_t callback)
{
if (callback.Success == 1) //1 if success, 0 if failure
{

View File

@ -23,10 +23,10 @@ internal MicroTransactions( Client c )
{
client = c;
SteamNative.MicroTxnAuthorizationResponse_t.RegisterCallback( client, onMicroTxnAuthorizationResponse );
client.RegisterCallback<SteamNative.MicroTxnAuthorizationResponse_t>( onMicroTxnAuthorizationResponse );
}
private void onMicroTxnAuthorizationResponse( MicroTxnAuthorizationResponse_t arg1, bool arg2 )
private void onMicroTxnAuthorizationResponse( MicroTxnAuthorizationResponse_t arg1 )
{
if ( OnAuthorizationResponse != null )
{

View File

@ -18,11 +18,6 @@ public static void ForUnity( string platform )
//
if ( platform == "WindowsEditor" || platform == "WindowsPlayer" )
{
//
// 32bit windows unity uses a stdcall
//
if ( IntPtr.Size == 4 ) UseThisCall = false;
ForcePlatform( OperatingSystem.Windows, IntPtr.Size == 4 ? Architecture.x86 : Architecture.x64 );
}
@ -36,6 +31,8 @@ public static void ForUnity( string platform )
ForcePlatform( OperatingSystem.Linux, IntPtr.Size == 4 ? Architecture.x86 : Architecture.x64 );
}
IsUnity = true;
Console.WriteLine( "Facepunch.Steamworks Unity: " + platform );
Console.WriteLine( "Facepunch.Steamworks Os: " + SteamNative.Platform.Os );
Console.WriteLine( "Facepunch.Steamworks Arch: " + SteamNative.Platform.Arch );
@ -50,7 +47,13 @@ public static void ForUnity( string platform )
/// for releasing his shit open source under the MIT license so we can all learn and iterate.
///
/// </summary>
public static bool UseThisCall { get; set; } = true;
internal static bool UseThisCall { get { return SteamNative.Platform.Os == OperatingSystem.Windows && !IsUnity; } }
/// <summary>
/// Should be true if we're using Unity
/// </summary>
internal static bool IsUnity { get; set; }
/// <summary>

View File

@ -26,7 +26,7 @@
</PropertyGroup>
<ItemGroup>
<Compile Remove="*AssemblyInfo.cs"/>
<Compile Remove="*AssemblyInfo.cs" />
</ItemGroup>
<PropertyGroup>
@ -36,5 +36,10 @@
<PropertyGroup>
<FrameworkPathOverride Condition="'$(TargetFramework)' == 'net40'">C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client</FrameworkPathOverride>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|netstandard2.0|AnyCPU'">
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
</Project>

View File

@ -139,9 +139,9 @@ internal void Fill()
}
}
internal void OnSteamResult( SteamInventoryResultReady_t data, bool error )
internal void OnSteamResult( SteamInventoryResultReady_t data )
{
var success = data.Result == SteamNative.Result.OK && !error;
var success = data.Result == SteamNative.Result.OK;
if ( success )
{

View File

@ -54,8 +54,8 @@ internal Inventory( BaseSteamworks steamworks, SteamNative.SteamInventory c, boo
if ( !server )
{
SteamNative.SteamInventoryResultReady_t.RegisterCallback( steamworks, onResultReady );
SteamNative.SteamInventoryFullUpdate_t.RegisterCallback( steamworks, onFullUpdate );
steamworks.RegisterCallback<SteamNative.SteamInventoryResultReady_t>( onResultReady );
steamworks.RegisterCallback<SteamNative.SteamInventoryFullUpdate_t>( onFullUpdate );
//
// Get a list of our items immediately
@ -67,10 +67,8 @@ internal Inventory( BaseSteamworks steamworks, SteamNative.SteamInventory c, boo
/// <summary>
/// We've received a FULL update
/// </summary>
private void onFullUpdate( SteamInventoryFullUpdate_t data, bool error )
private void onFullUpdate( SteamInventoryFullUpdate_t data )
{
if ( error ) return;
var result = new Result( this, data.Handle, false );
result.Fill();
@ -80,15 +78,15 @@ private void onFullUpdate( SteamInventoryFullUpdate_t data, bool error )
/// <summary>
/// A generic result has returned.
/// </summary>
private void onResultReady( SteamInventoryResultReady_t data, bool error )
private void onResultReady( SteamInventoryResultReady_t data )
{
if ( Result.Pending.ContainsKey( data.Handle ) )
{
var result = Result.Pending[data.Handle];
result.OnSteamResult( data, error );
result.OnSteamResult( data );
if ( !error && data.Result == SteamNative.Result.OK )
if ( data.Result == SteamNative.Result.OK )
{
onResult( result, false );
}

View File

@ -26,8 +26,8 @@ internal Networking( BaseSteamworks steamworks, SteamNative.SteamNetworking netw
{
this.networking = networking;
SteamNative.P2PSessionRequest_t.RegisterCallback( steamworks, onP2PConnectionRequest );
SteamNative.P2PSessionConnectFail_t.RegisterCallback( steamworks, onP2PConnectionFailed );
steamworks.RegisterCallback<SteamNative.P2PSessionRequest_t>( onP2PConnectionRequest );
steamworks.RegisterCallback<SteamNative.P2PSessionConnectFail_t>( onP2PConnectionFailed );
}
public void Dispose()
@ -80,7 +80,7 @@ public void SetListenChannel( int ChannelId, bool Listen )
}
}
private void onP2PConnectionRequest( SteamNative.P2PSessionRequest_t o, bool b )
private void onP2PConnectionRequest( SteamNative.P2PSessionRequest_t o )
{
if ( OnIncomingConnection != null )
{
@ -116,7 +116,7 @@ public enum SessionError : byte
Max = 5
};
private void onP2PConnectionFailed( SteamNative.P2PSessionConnectFail_t o, bool b )
private void onP2PConnectionFailed( SteamNative.P2PSessionConnectFail_t o )
{
if ( OnConnectionFailed != null )
{

View File

@ -46,8 +46,8 @@ internal Workshop( BaseSteamworks steamworks, SteamNative.SteamUGC ugc, SteamNat
this.steamworks = steamworks;
this.remoteStorage = remoteStorage;
SteamNative.DownloadItemResult_t.RegisterCallback( steamworks, onDownloadResult );
SteamNative.ItemInstalled_t.RegisterCallback( steamworks, onItemInstalled );
steamworks.RegisterCallback<SteamNative.DownloadItemResult_t>( onDownloadResult );
steamworks.RegisterCallback<SteamNative.ItemInstalled_t>( onItemInstalled );
}
/// <summary>
@ -64,13 +64,13 @@ public void Dispose()
OnItemInstalled = null;
}
private void onItemInstalled( SteamNative.ItemInstalled_t obj, bool failed )
private void onItemInstalled( SteamNative.ItemInstalled_t obj )
{
if ( OnItemInstalled != null && obj.AppID == Client.Instance.AppId )
OnItemInstalled( obj.PublishedFileId );
}
private void onDownloadResult( SteamNative.DownloadItemResult_t obj, bool failed )
private void onDownloadResult( SteamNative.DownloadItemResult_t obj )
{
if ( OnFileDownloaded != null && obj.AppID == Client.Instance.AppId )
OnFileDownloaded( obj.PublishedFileId, (Callbacks.Result) obj.Result );

View File

@ -53,9 +53,10 @@ public Server( uint appId, ServerInit init) : base( appId )
SetupCommonInterfaces();
//
// Cache common, unchanging info
// Register Callbacks
//
AppId = appId;
SteamNative.Callbacks.RegisterCallbacks( this );
//
// Initial settings

View File

@ -35,10 +35,10 @@ internal ServerAuth( Server s )
{
server = s;
SteamNative.ValidateAuthTicketResponse_t.RegisterCallback( server, OnAuthTicketValidate );
server.RegisterCallback<SteamNative.ValidateAuthTicketResponse_t>( OnAuthTicketValidate );
}
void OnAuthTicketValidate( SteamNative.ValidateAuthTicketResponse_t data, bool b )
void OnAuthTicketValidate( SteamNative.ValidateAuthTicketResponse_t data )
{
if ( OnAuthChange != null )
OnAuthChange( data.SteamID, data.OwnerSteamID, (Status) data.AuthSessionResponse );

View File

@ -20,29 +20,50 @@ internal enum Flags : byte
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
public class VTable
{
public IntPtr ResultA;
public IntPtr ResultB;
public IntPtr GetSize;
[UnmanagedFunctionPointer( CallingConvention.StdCall )] public delegate void ResultD( IntPtr pvParam );
[UnmanagedFunctionPointer( CallingConvention.StdCall )] public delegate void ResultWithInfoD( IntPtr pvParam, bool bIOFailure, SteamNative.SteamAPICall_t hSteamAPICall );
[UnmanagedFunctionPointer( CallingConvention.StdCall )] public delegate int GetSizeD();
public ResultD ResultA;
public ResultWithInfoD ResultB;
public GetSizeD GetSize;
}
//
// All possible functions
//
internal class ThisCall
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
public class VTableWin
{
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate void Result( IntPtr thisptr, IntPtr pvParam );
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate void ResultWithInfo( IntPtr thisptr, IntPtr pvParam, bool bIOFailure, SteamNative.SteamAPICall_t hSteamAPICall );
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate int GetSize( IntPtr thisptr );
[UnmanagedFunctionPointer( CallingConvention.StdCall )] public delegate void ResultD( IntPtr pvParam );
[UnmanagedFunctionPointer( CallingConvention.StdCall )] public delegate void ResultWithInfoD( IntPtr pvParam, bool bIOFailure, SteamNative.SteamAPICall_t hSteamAPICall );
[UnmanagedFunctionPointer( CallingConvention.StdCall )] public delegate int GetSizeD();
public ResultWithInfoD ResultB;
public ResultD ResultA;
public GetSizeD GetSize;
}
internal class StdCall
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
public class VTableThis
{
[UnmanagedFunctionPointer( CallingConvention.StdCall )] public delegate void Result( IntPtr pvParam );
[UnmanagedFunctionPointer( CallingConvention.StdCall )] public delegate void ResultWithInfo( IntPtr pvParam, bool bIOFailure, SteamNative.SteamAPICall_t hSteamAPICall );
[UnmanagedFunctionPointer( CallingConvention.StdCall )] public delegate int GetSize();
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate void ResultD( IntPtr thisptr, IntPtr pvParam );
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate void ResultWithInfoD( IntPtr thisptr, IntPtr pvParam, bool bIOFailure, SteamNative.SteamAPICall_t hSteamAPICall );
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate int GetSizeD( IntPtr thisptr );
public ResultD ResultA;
public ResultWithInfoD ResultB;
public GetSizeD GetSize;
}
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
public class VTableWinThis
{
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate void ResultD( IntPtr thisptr, IntPtr pvParam );
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate void ResultWithInfoD( IntPtr thisptr, IntPtr pvParam, bool bIOFailure, SteamNative.SteamAPICall_t hSteamAPICall );
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate int GetSizeD( IntPtr thisptr );
public ResultWithInfoD ResultB;
public ResultD ResultA;
public GetSizeD GetSize;
}
};
//
@ -169,4 +190,9 @@ unsafe internal override void RunCallback()
}
}
}
internal class MonoPInvokeCallbackAttribute : Attribute
{
public MonoPInvokeCallbackAttribute( Type t ) { }
}
}

File diff suppressed because it is too large Load Diff

View File

@ -37,6 +37,8 @@ public class TypeDef
void Structs()
{
var callbackList = new List<SteamApiDefinition.StructDef>();
foreach ( var c in def.structs )
{
if ( SkipStructs.Contains( c.Name ) )
@ -133,12 +135,24 @@ void Structs()
if ( !string.IsNullOrEmpty( c.CallbackId ) )
{
Callback( c );
callbackList.Add( c );
}
}
EndBlock();
WriteLine();
}
StartBlock( $"internal static class Callbacks" );
StartBlock( $"internal static void RegisterCallbacks( Facepunch.Steamworks.BaseSteamworks steamworks )" );
{
foreach ( var c in callbackList )
{
WriteLine( $"{c.Name}.Register( steamworks );" );
}
}
EndBlock();
EndBlock();
}
private void StructFields( SteamApiDefinition.StructDef.StructFields[] fields )
@ -216,14 +230,14 @@ private void StructFields( SteamApiDefinition.StructDef.StructFields[] fields )
}
private void Callback( SteamApiDefinition.StructDef c )
{
{
WriteLine();
StartBlock( $"internal static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action<{c.Name}, bool> CallbackFunction )" );
StartBlock( $"internal static void Register( Facepunch.Steamworks.BaseSteamworks steamworks )" );
{
WriteLine( $"var handle = new CallbackHandle( steamworks );" );
WriteLine( $"" );
CallbackCallresultShared( c, false );
CallbackCall( c );
WriteLine( "" );
WriteLine( "//" );
@ -235,6 +249,42 @@ private void Callback( SteamApiDefinition.StructDef c )
WriteLine( "steamworks.RegisterCallbackHandle( handle );" );
}
EndBlock();
WriteLine();
WriteLine( "[MonoPInvokeCallback( typeof( SteamNative.Callback.VTableThis.ResultD ) )]" );
WriteLine( "internal static void OnResultThis( IntPtr self, IntPtr param ){ OnResult( param ); }" );
WriteLine( "[MonoPInvokeCallback( typeof( SteamNative.Callback.VTableThis.ResultD ) )]" );
WriteLine( "internal static void OnResultWithInfoThis( IntPtr self, IntPtr param, bool failure, SteamNative.SteamAPICall_t call ){ OnResultWithInfo( param, failure, call ); }" );
WriteLine( "[MonoPInvokeCallback( typeof( SteamNative.Callback.VTableThis.ResultD ) )]" );
WriteLine( "internal static int OnGetSizeThis( IntPtr self ){ return OnGetSize(); }" );
WriteLine( "[MonoPInvokeCallback( typeof( SteamNative.Callback.VTableThis.ResultD ) )]" );
WriteLine( "internal static int OnGetSize(){ return StructSize(); }" );
WriteLine();
WriteLine( "[MonoPInvokeCallback( typeof( SteamNative.Callback.VTableThis.ResultD ) )]" );
StartBlock( "internal static void OnResult( IntPtr param )" );
{
WriteLine( $"OnResultWithInfo( param, false, 0 );" );
}
EndBlock();
WriteLine();
WriteLine( "[MonoPInvokeCallback( typeof( SteamNative.Callback.VTableThis.ResultD ) )]" );
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();
}
@ -244,24 +294,12 @@ private void CallResult( SteamApiDefinition.StructDef c )
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 );" );
// 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 CallbackCallresultShared( SteamApiDefinition.StructDef c, bool Result )
private void CallbackCall( SteamApiDefinition.StructDef c )
{
WriteLine( "//" );
WriteLine( "// Create the functions we need for the vtable" );
@ -269,11 +307,11 @@ private void CallbackCallresultShared( SteamApiDefinition.StructDef c, bool Resu
StartBlock( "if ( Facepunch.Steamworks.Config.UseThisCall )" );
{
CallresultFunctions( c, Result, "ThisCall", "_" );
CallFunctions( c, "ThisCall", "_" );
}
Else();
{
CallresultFunctions( c, Result, "StdCall", "" );
CallFunctions( c, "StdCall", "" );
}
EndBlock();
@ -293,73 +331,51 @@ private void CallbackCallresultShared( SteamApiDefinition.StructDef c, bool Resu
WriteLine( $"handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned );" );
}
private void CallresultFunctions( SteamApiDefinition.StructDef c, bool Result, string ThisCall, string ThisArg )
private void CallFunctions( SteamApiDefinition.StructDef c, 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();
var This = ThisArg.Length > 0 ? "This" : "";
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 );" );
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();
WriteLine( "Marshal.StructureToPtr( vTable, handle.vTablePtr, false );" );
}
}
}