Added interface versions of Connection/SocketManagers

This commit is contained in:
Garry Newman 2020-02-27 14:01:27 +00:00
parent 66b221984f
commit ebf77a8fde
6 changed files with 164 additions and 29 deletions

View File

@ -6,7 +6,21 @@ namespace Steamworks
{
public class ConnectionManager
{
/// <summary>
/// An optional interface to use instead of deriving
/// </summary>
public IConnectionManager Interface { get; set; }
/// <summary>
/// The actual connection we're managing
/// </summary>
public Connection Connection;
/// <summary>
/// The last received ConnectionInfo
/// </summary>
public ConnectionInfo ConnectionInfo { get; internal set; }
public bool Connected = false;
public bool Connecting = true;
@ -28,6 +42,8 @@ namespace Steamworks
public virtual void OnConnectionChanged( ConnectionInfo info )
{
ConnectionInfo = info;
switch ( info.State )
{
case ConnectionState.Connecting:
@ -49,6 +65,8 @@ namespace Steamworks
/// </summary>
public virtual void OnConnecting( ConnectionInfo info )
{
Interface?.OnConnecting( info );
Connecting = true;
}
@ -57,6 +75,8 @@ namespace Steamworks
/// </summary>
public virtual void OnConnected( ConnectionInfo info )
{
Interface?.OnConnected( info );
Connected = true;
Connecting = false;
}
@ -66,6 +86,8 @@ namespace Steamworks
/// </summary>
public virtual void OnDisconnected( ConnectionInfo info )
{
Interface?.OnDisconnected( info );
Connected = false;
Connecting = false;
}
@ -114,7 +136,7 @@ namespace Steamworks
public virtual void OnMessage( IntPtr data, int size, long messageNum, long recvTime, int channel )
{
Interface?.OnMessage( data, size, messageNum, recvTime, channel );
}
}
}

View File

@ -0,0 +1,28 @@
using System;
using Steamworks.Data;
namespace Steamworks
{
public interface IConnectionManager
{
/// <summary>
/// We started connecting to this guy
/// </summary>
void OnConnecting( ConnectionInfo info );
/// <summary>
/// Called when the connection is fully connected and can start being communicated with
/// </summary>
void OnConnected( ConnectionInfo info );
/// <summary>
/// We got disconnected
/// </summary>
void OnDisconnected( ConnectionInfo info );
/// <summary>
/// Received a message
/// </summary>
void OnMessage( IntPtr data, int size, long messageNum, long recvTime, int channel );
}
}

View File

@ -0,0 +1,28 @@
using System;
using Steamworks.Data;
namespace Steamworks
{
public interface ISocketManager
{
/// <summary>
/// Must call Accept or Close on the connection within a second or so
/// </summary>
void OnConnecting( Connection connection, ConnectionInfo info );
/// <summary>
/// Called when the connection is fully connected and can start being communicated with
/// </summary>
void OnConnected( Connection connection, ConnectionInfo info );
/// <summary>
/// Called when the connection leaves
/// </summary>
void OnDisconnected( Connection connection, ConnectionInfo info );
/// <summary>
/// Received a message from a connection
/// </summary>
void OnMessage( Connection connection, NetIdentity identity, IntPtr data, int size, long messageNum, long recvTime, int channel );
}
}

View File

@ -20,10 +20,10 @@ namespace Steamworks.Data
return SteamNetworkingSockets.Internal.CloseListenSocket( Id );
}
public SocketManager Interface
public SocketManager Manager
{
get => SteamNetworkingSockets.GetSocketInterface( Id );
set => SteamNetworkingSockets.SetSocketInterface( Id, value );
get => SteamNetworkingSockets.GetSocketManager( Id );
set => SteamNetworkingSockets.SetSocketManager( Id, value );
}
}
}

View File

@ -12,8 +12,10 @@ namespace Steamworks
/// You can override all the virtual functions to turn it into what you
/// want it to do.
/// </summary>
public class SocketManager
public partial class SocketManager
{
public ISocketManager Interface { get; set; }
public List<Connection> Connecting = new List<Connection>();
public List<Connection> Connected = new List<Connection>();
public Socket Socket { get; internal set; }
@ -47,12 +49,16 @@ namespace Steamworks
case ConnectionState.Connecting:
if ( !Connecting.Contains( connection ) )
{
Connecting.Add( connection );
OnConnecting( connection, info );
}
break;
case ConnectionState.Connected:
if ( !Connected.Contains( connection ) )
{
Connecting.Remove( connection );
Connected.Add( connection );
OnConnected( connection, info );
}
break;
@ -72,8 +78,15 @@ namespace Steamworks
/// </summary>
public virtual void OnConnecting( Connection connection, ConnectionInfo info )
{
connection.Accept();
Connecting.Add( connection );
if ( Interface != null )
{
Interface.OnConnecting( connection, info );
return;
}
else
{
connection.Accept();
}
}
/// <summary>
@ -81,9 +94,9 @@ namespace Steamworks
/// </summary>
public virtual void OnConnected( Connection connection, ConnectionInfo info )
{
Connecting.Remove( connection );
Connected.Add( connection );
SteamNetworkingSockets.Internal.SetConnectionPollGroup( connection, pollGroup );
Interface?.OnConnected( connection, info );
}
/// <summary>
@ -97,6 +110,8 @@ namespace Steamworks
Connecting.Remove( connection );
Connected.Remove( connection );
Interface?.OnDisconnected( connection, info );
}
public void Receive( int bufferSize = 32 )
@ -144,7 +159,7 @@ namespace Steamworks
public virtual void OnMessage( Connection connection, NetIdentity identity, IntPtr data, int size, long messageNum, long recvTime, int channel )
{
Interface?.OnMessage( connection, identity, data, size, messageNum, recvTime, channel );
}
}
}

View File

@ -15,18 +15,14 @@ namespace Steamworks
internal override void InitializeInterface( bool server )
{
SetInterface( server, new ISteamNetworkingSockets( server ) );
SocketInterfaces = new Dictionary<uint, SocketManager>();
ConnectionInterfaces = new Dictionary<uint, ConnectionManager>();
InstallEvents( server );
}
#region SocketInterface
static Dictionary<uint, SocketManager> SocketInterfaces;
static readonly Dictionary<uint, SocketManager> SocketInterfaces = new Dictionary<uint, SocketManager>();
internal static SocketManager GetSocketInterface( uint id )
internal static SocketManager GetSocketManager( uint id )
{
if ( SocketInterfaces == null ) return null;
if ( id == 0 ) throw new System.ArgumentException( "Invalid Socket" );
@ -37,18 +33,17 @@ namespace Steamworks
return null;
}
internal static void SetSocketInterface( uint id, SocketManager iface )
internal static void SetSocketManager( uint id, SocketManager manager )
{
if ( id == 0 ) throw new System.ArgumentException( "Invalid Socket" );
SocketInterfaces[id] = iface;
SocketInterfaces[id] = manager;
}
#endregion
#region ConnectionInterface
static Dictionary<uint, ConnectionManager> ConnectionInterfaces;
static readonly Dictionary<uint, ConnectionManager> ConnectionInterfaces = new Dictionary<uint, ConnectionManager>();
internal static ConnectionManager GetConnectionInterface( uint id )
internal static ConnectionManager GetConnectionManager( uint id )
{
if ( ConnectionInterfaces == null ) return null;
if ( id == 0 ) return null;
@ -59,10 +54,10 @@ namespace Steamworks
return null;
}
internal static void SetConnectionInterface( uint id, ConnectionManager iface )
internal static void SetConnectionManager( uint id, ConnectionManager manager )
{
if ( id == 0 ) throw new System.ArgumentException( "Invalid Connection" );
ConnectionInterfaces[id] = iface;
ConnectionInterfaces[id] = manager;
}
#endregion
@ -81,12 +76,12 @@ namespace Steamworks
//
if ( data.Nfo.listenSocket.Id > 0 )
{
var iface = GetSocketInterface( data.Nfo.listenSocket.Id );
var iface = GetSocketManager( data.Nfo.listenSocket.Id );
iface?.OnConnectionChanged( data.Conn, data.Nfo );
}
else
{
var iface = GetConnectionInterface( data.Conn.Id );
var iface = GetConnectionManager( data.Conn.Id );
iface?.OnConnectionChanged( data.Nfo );
}
@ -99,6 +94,9 @@ namespace Steamworks
/// <summary>
/// Creates a "server" socket that listens for clients to connect to by calling
/// Connect, over ordinary UDP (IPv4 or IPv6)
///
/// To use this derive a class from SocketManager and override as much as you want.
///
/// </summary>
public static T CreateNormalSocket<T>( NetAddress address ) where T : SocketManager, new()
{
@ -107,7 +105,33 @@ namespace Steamworks
t.Socket = Internal.CreateListenSocketIP( ref address, options.Length, options );
t.Initialize();
SetSocketInterface( t.Socket.Id, t );
SetSocketManager( t.Socket.Id, t );
return t;
}
/// <summary>
/// Creates a "server" socket that listens for clients to connect to by calling
/// Connect, over ordinary UDP (IPv4 or IPv6).
///
/// To use this you should pass a class that inherits ISocketManager. You can use
/// SocketManager to get connections and send messages, but the ISocketManager class
/// will received all the appropriate callbacks.
///
/// </summary>
public static SocketManager CreateNormalSocket( NetAddress address, ISocketManager intrface )
{
var options = Array.Empty<NetKeyValue>();
var socket = Internal.CreateListenSocketIP( ref address, options.Length, options );
var t = new SocketManager
{
Socket = socket,
Interface = intrface
};
t.Initialize();
SetSocketManager( t.Socket.Id, t );
return t;
}
@ -119,7 +143,25 @@ namespace Steamworks
var t = new T();
var options = Array.Empty<NetKeyValue>();
t.Connection = Internal.ConnectByIPAddress( ref address, options.Length, options );
SetConnectionInterface( t.Connection.Id, t );
SetConnectionManager( t.Connection.Id, t );
return t;
}
/// <summary>
/// Connect to a socket created via <method>CreateListenSocketIP</method>
/// </summary>
public static ConnectionManager ConnectNormal( NetAddress address, IConnectionManager iface )
{
var options = Array.Empty<NetKeyValue>();
var connection = Internal.ConnectByIPAddress( ref address, options.Length, options );
var t = new ConnectionManager
{
Connection = connection,
Interface = iface
};
SetConnectionManager( t.Connection.Id, t );
return t;
}
@ -131,8 +173,8 @@ namespace Steamworks
var t = new T();
var options = Array.Empty<NetKeyValue>();
t.Socket = Internal.CreateListenSocketP2P( virtualport, options.Length, options );
SetSocketInterface( t.Socket.Id, t );
t.Initialize();
SetSocketManager( t.Socket.Id, t );
return t;
}
@ -145,7 +187,7 @@ namespace Steamworks
NetIdentity identity = serverId;
var options = Array.Empty<NetKeyValue>();
t.Connection = Internal.ConnectP2P( ref identity, virtualport, options.Length, options );
SetConnectionInterface( t.Connection.Id, t );
SetConnectionManager( t.Connection.Id, t );
return t;
}
}