Add Steamworks.Dispatch.OnDebugCallback

This commit is contained in:
Garry Newman 2020-02-27 10:01:43 +00:00
parent 8db2b46729
commit 9db103cb2f
5 changed files with 75 additions and 13 deletions

View File

@ -15,6 +15,13 @@ namespace Steamworks
[AssemblyInitialize]
public static void AssemblyInit( TestContext context )
{
Steamworks.Dispatch.OnDebugCallback = ( type, str, server ) =>
{
Console.WriteLine( $"[Callback {type} {(server ? "server" : "client")}]" );
Console.WriteLine( str );
Console.WriteLine( $"" );
};
Steamworks.SteamClient.OnCallbackException = ( e ) =>
{
Console.Error.WriteLine( e.Message );

View File

@ -9,11 +9,24 @@ using System.Linq;
namespace Steamworks
{
/// <summary>
/// Manually pumps Steam's message queue and dispatches those
/// Responsible for all callback/callresult handling
///
/// This manually pumps Steam's message queue and dispatches those
/// events to any waiting callbacks/callresults.
/// </summary>
internal static class Dispatch
public static class Dispatch
{
/// <summary>
/// If set then we'll call this function every time a callback is generated.
///
/// This is SLOW!! - it's for debugging - don't keep it on all the time. If you want to access a specific
/// callback then please create an issue on github and I'll add it!
///
/// Params are : [Callback Type] [Callback Contents] [server]
///
/// </summary>
public static Action<CallbackType, string, bool> OnDebugCallback;
#region interop
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ManualDispatch_Init", CallingConvention = CallingConvention.Cdecl )]
internal static extern void SteamAPI_ManualDispatch_Init();
@ -45,9 +58,9 @@ namespace Steamworks
/// <summary>
/// This gets called from Client/Server Init
/// It's important to switch to the manual dipatcher
/// It's important to switch to the manual dispatcher
/// </summary>
public static void Init()
internal static void Init()
{
SteamAPI_ManualDispatch_Init();
}
@ -56,7 +69,7 @@ namespace Steamworks
/// <summary>
/// Calls RunFrame and processes events from this Steam Pipe
/// </summary>
public static void Frame( HSteamPipe pipe )
internal static void Frame( HSteamPipe pipe )
{
SteamAPI_ManualDispatch_RunFrame( pipe );
SteamNetworkingUtils.OutputDebugMessages();
@ -88,6 +101,11 @@ namespace Steamworks
return;
}
if ( OnDebugCallback != null )
{
OnDebugCallback( msg.Type, CallbackToString( msg ), isServer );
}
if ( Callbacks.TryGetValue( msg.Type, out var list ) )
{
foreach ( var item in list )
@ -100,6 +118,28 @@ namespace Steamworks
}
}
/// <summary>
/// Given a callback, try to turn it into a string
/// </summary>
private static string CallbackToString( CallbackMsg_t msg )
{
if ( !CallbackTypeFactory.All.TryGetValue( msg.Type, out var t ) )
return "[not in sdk]";
var strct = msg.Data.ToType( t );
if ( strct == null )
return "[null]";
var str = "";
foreach ( var field in t.GetFields( System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic ) )
{
str += $"{field.Name}: \"{field.GetValue( strct )}\"\n";
}
return str.Trim( '\n' );
}
/// <summary>
/// A result is a reply to a specific command
/// </summary>
@ -129,7 +169,7 @@ namespace Steamworks
/// have to think about it. This has the advantage that
/// you can call .Wait() on async shit and it still works.
/// </summary>
public static async void LoopClientAsync()
internal static async void LoopClientAsync()
{
while ( ClientPipe != 0 )
{
@ -143,7 +183,7 @@ namespace Steamworks
/// have to think about it. This has the advantage that
/// you can call .Wait() on async shit and it still works.
/// </summary>
public static async void LoopServerAsync()
internal static async void LoopServerAsync()
{
while ( ServerPipe != 0 )
{

View File

@ -86,9 +86,9 @@ namespace Steamworks
UserAchievementIconFetched = 1109,
GlobalAchievementPercentagesReady = 1110,
LeaderboardUGCSet = 1111,
PS3TrophiesInstalled = 1112,
// PS3TrophiesInstalled = 1112,
GlobalStatsReceived = 1112,
SocketStatusCallback = 1201,
// SocketStatusCallback = 1201,
P2PSessionRequest = 1202,
P2PSessionConnectFail = 1203,
SteamNetConnectionStatusChangedCallback = 1221,
@ -292,12 +292,12 @@ namespace Steamworks
{ CallbackType.LeaderboardScoreUploaded, typeof( LeaderboardScoreUploaded_t )},
{ CallbackType.NumberOfCurrentPlayers, typeof( NumberOfCurrentPlayers_t )},
{ CallbackType.UserStatsUnloaded, typeof( UserStatsUnloaded_t )},
{ CallbackType.GSStatsUnloaded, typeof( GSStatsUnloaded_t )},
// { CallbackType.GSStatsUnloaded, typeof( GSStatsUnloaded_t )},
{ CallbackType.UserAchievementIconFetched, typeof( UserAchievementIconFetched_t )},
{ CallbackType.GlobalAchievementPercentagesReady, typeof( GlobalAchievementPercentagesReady_t )},
{ CallbackType.LeaderboardUGCSet, typeof( LeaderboardUGCSet_t )},
{ CallbackType.PS3TrophiesInstalled, typeof( PS3TrophiesInstalled_t )},
{ CallbackType.GlobalStatsReceived, typeof( GlobalStatsReceived_t )},
// { CallbackType.PS3TrophiesInstalled, typeof( PS3TrophiesInstalled_t )},
// { CallbackType.GlobalStatsReceived, typeof( GlobalStatsReceived_t )},
// { CallbackType.SocketStatusCallback, typeof( SocketStatusCallback_t )},
{ CallbackType.P2PSessionRequest, typeof( P2PSessionRequest_t )},
{ CallbackType.P2PSessionConnectFail, typeof( P2PSessionConnectFail_t )},

View File

@ -18,6 +18,14 @@ namespace Steamworks
return (T)Marshal.PtrToStructure( ptr, typeof( T ) );
}
static internal object ToType( this IntPtr ptr, System.Type t )
{
if ( ptr == IntPtr.Zero )
return default;
return Marshal.PtrToStructure( ptr, t );
}
static internal uint Swap( uint x )
{
return ((x & 0x000000ff) << 24) +

View File

@ -13,18 +13,25 @@ namespace Generator
StartBlock( "public enum CallbackType" );
foreach ( var c in def.callback_structs.OrderBy( x => x.CallbackId ) )
{
if ( Cleanup.IsDeprecated( c.Name ) )
Write( "// " );
WriteLine( $"{c.Name.Replace( "_t", "" ) } = {c.CallbackId}," );
}
EndBlock();
int last = -1;
StartBlock( "internal static partial class CallbackTypeFactory" );
StartBlock( "internal static System.Collections.Generic.Dictionary<CallbackType, System.Type> All = new System.Collections.Generic.Dictionary<CallbackType, System.Type>" );
foreach ( var c in def.callback_structs.OrderBy( x => x.CallbackId ) )
{
if ( Cleanup.IsDeprecated( c.Name ) )
if ( Cleanup.IsDeprecated( c.Name ) || last == c.CallbackId )
Write( "// " );
WriteLine( $"{{ CallbackType.{c.Name.Replace( "_t", "" ) }, typeof( {Cleanup.ConvertType(c.Name)} )}}," );
last = c.CallbackId;
}
EndBlock( ";" );
EndBlock();