Remove Marshal usage in ConnectionManager (removes allocations)

This commit is contained in:
Rohan Singh 2021-01-13 10:03:41 -05:00
parent c5c31280c1
commit 8057413ea3

View File

@ -1,6 +1,5 @@
using Steamworks.Data; using Steamworks.Data;
using System; using System;
using System.Runtime.InteropServices;
namespace Steamworks namespace Steamworks
{ {
@ -109,47 +108,46 @@ namespace Steamworks
Interface?.OnDisconnected( info ); Interface?.OnDisconnected( info );
} }
public int Receive( int bufferSize = 32, bool receiveToEnd = true ) public unsafe int Receive( int bufferSize = 32, bool receiveToEnd = true )
{ {
int processed = 0; if ( bufferSize > 256 ) throw new ArgumentOutOfRangeException( nameof( bufferSize ) );
IntPtr messageBuffer = Marshal.AllocHGlobal( IntPtr.Size * bufferSize );
try int totalProcessed = 0;
{ NetMsg** messageBuffer = stackalloc NetMsg*[bufferSize];
processed = SteamNetworkingSockets.Internal.ReceiveMessagesOnConnection( Connection, messageBuffer, bufferSize );
while ( true )
{
int processed = SteamNetworkingSockets.Internal.ReceiveMessagesOnConnection( Connection, new IntPtr( &messageBuffer ), bufferSize );
totalProcessed += processed;
for ( int i = 0; i < processed; i++ ) for ( int i = 0; i < processed; i++ )
{ {
ReceiveMessage( Marshal.ReadIntPtr( messageBuffer, i * IntPtr.Size ) ); // TODO: if this throws we will leak the remaining NetMsgs (probably not going to happen much though)
} ReceiveMessage( messageBuffer[i] );
} }
finally
{ //
Marshal.FreeHGlobal( messageBuffer ); // Keep going if receiveToEnd and we filled the buffer
//
if ( !receiveToEnd || processed < bufferSize )
break;
} }
// return totalProcessed;
// Overwhelmed our buffer, keep going
//
if ( receiveToEnd && processed == bufferSize )
processed += Receive( bufferSize );
return processed;
} }
internal unsafe void ReceiveMessage( IntPtr msgPtr ) internal unsafe void ReceiveMessage( NetMsg* msg )
{ {
var msg = Marshal.PtrToStructure<NetMsg>( msgPtr );
try try
{ {
OnMessage( msg.DataPtr, msg.DataSize, msg.RecvTime, msg.MessageNumber, msg.Channel ); OnMessage( msg->DataPtr, msg->DataSize, msg->RecvTime, msg->MessageNumber, msg->Channel );
} }
finally finally
{ {
// //
// Releases the message // Releases the message
// //
NetMsg.InternalRelease( (NetMsg*) msgPtr ); NetMsg.InternalRelease( msg );
} }
} }