perf(transport): BREAKING: callbacks instead of unityevent for transports (#2417)

* delegate and callbacks instead of unityevent

* using callbacks in Mirror

* Using new callbacks instead of events
* moving methods next to each other in NetworkClient
* moving add/remove to methods in NetworkServer

* replacing uses of events within transports and tests

* fixing tests

* fixing more tests

* replacing delegates with actions

* adding comments to show what action variable's are

* removing extra function created in rebase

* renaming callbacks

* adding reset methods so that actions arn't null

* fixing rename

* breaking defines

* Update Assets/Mirror/Runtime/Transport/KCP/MirrorTransport/KcpTransport.cs

* Update KcpTransport.cs

* Update Transport.cs

* removing ResetHandlers methods

transports can now call events after stop is called

Co-authored-by: vis2k <info@noobtuts.com>
This commit is contained in:
James Frowen 2020-11-20 15:47:56 +00:00 committed by GitHub
parent c3a06b297a
commit d3d3113f7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 149 additions and 156 deletions

View File

@ -36,7 +36,8 @@ public static void AddDefineSymbols()
"MIRROR_24_0_OR_NEWER", "MIRROR_24_0_OR_NEWER",
"MIRROR_26_0_OR_NEWER", "MIRROR_26_0_OR_NEWER",
"MIRROR_27_0_OR_NEWER", "MIRROR_27_0_OR_NEWER",
"MIRROR_28_0_OR_NEWER" "MIRROR_28_0_OR_NEWER",
"MIRROR_29_0_OR_NEWER"
}; };
// only touch PlayerSettings if we actually modified it. // only touch PlayerSettings if we actually modified it.

View File

@ -147,19 +147,10 @@ public static void DisconnectLocalServer()
static void AddTransportHandlers() static void AddTransportHandlers()
{ {
Transport.activeTransport.OnClientConnected.AddListener(OnConnected); Transport.activeTransport.OnClientConnected = OnConnected;
Transport.activeTransport.OnClientDataReceived.AddListener(OnDataReceived); Transport.activeTransport.OnClientDataReceived = OnDataReceived;
Transport.activeTransport.OnClientDisconnected.AddListener(OnDisconnected); Transport.activeTransport.OnClientDisconnected = OnDisconnected;
Transport.activeTransport.OnClientError.AddListener(OnError); Transport.activeTransport.OnClientError = OnError;
}
static void RemoveTransportHandlers()
{
// so that we don't register them more than once
Transport.activeTransport.OnClientConnected.RemoveListener(OnConnected);
Transport.activeTransport.OnClientDataReceived.RemoveListener(OnDataReceived);
Transport.activeTransport.OnClientDisconnected.RemoveListener(OnDisconnected);
Transport.activeTransport.OnClientError.RemoveListener(OnError);
} }
static void OnError(Exception exception) static void OnError(Exception exception)
@ -225,7 +216,6 @@ public static void Disconnect()
{ {
connection.Disconnect(); connection.Disconnect();
connection = null; connection = null;
RemoveTransportHandlers();
} }
} }
} }

View File

@ -90,8 +90,6 @@ public static void Shutdown()
Transport.activeTransport.ServerStop(); Transport.activeTransport.ServerStop();
} }
RemoveTransportHandlers();
initialized = false; initialized = false;
} }
dontListen = false; dontListen = false;
@ -491,18 +489,10 @@ static void CheckForInactiveConnections()
static void AddTransportHandlers() static void AddTransportHandlers()
{ {
Transport.activeTransport.OnServerDisconnected.AddListener(OnDisconnected); Transport.activeTransport.OnServerConnected = OnConnected;
Transport.activeTransport.OnServerConnected.AddListener(OnConnected); Transport.activeTransport.OnServerDataReceived = OnDataReceived;
Transport.activeTransport.OnServerDataReceived.AddListener(OnDataReceived); Transport.activeTransport.OnServerDisconnected = OnDisconnected;
Transport.activeTransport.OnServerError.AddListener(OnError); Transport.activeTransport.OnServerError = OnError;
}
static void RemoveTransportHandlers()
{
Transport.activeTransport.OnServerDisconnected.RemoveListener(OnDisconnected);
Transport.activeTransport.OnServerConnected.RemoveListener(OnConnected);
Transport.activeTransport.OnServerDataReceived.RemoveListener(OnDataReceived);
Transport.activeTransport.OnServerError.RemoveListener(OnError);
} }
static void OnConnected(int connectionId) static void OnConnected(int connectionId)

View File

@ -20,8 +20,6 @@ public void Awake()
{ {
throw new Exception("FallbackTransport requires at least 1 underlying transport"); throw new Exception("FallbackTransport requires at least 1 underlying transport");
} }
InitClient();
InitServer();
available = GetAvailableTransport(); available = GetAvailableTransport();
Debug.Log("FallbackTransport available: " + available.GetType()); Debug.Log("FallbackTransport available: " + available.GetType());
} }
@ -54,21 +52,12 @@ public override bool Available()
return available.Available(); return available.Available();
} }
// clients always pick the first transport
void InitClient()
{
// wire all the base transports to our events
foreach (Transport transport in transports)
{
transport.OnClientConnected.AddListener(OnClientConnected.Invoke);
transport.OnClientDataReceived.AddListener(OnClientDataReceived.Invoke);
transport.OnClientError.AddListener(OnClientError.Invoke);
transport.OnClientDisconnected.AddListener(OnClientDisconnected.Invoke);
}
}
public override void ClientConnect(string address) public override void ClientConnect(string address)
{ {
available.OnClientConnected = OnClientConnected;
available.OnClientDataReceived = OnClientDataReceived;
available.OnClientError = OnClientError;
available.OnClientDisconnected = OnClientDisconnected;
available.ClientConnect(address); available.ClientConnect(address);
} }
@ -107,18 +96,6 @@ public override void ClientSend(int channelId, ArraySegment<byte> segment)
available.ClientSend(channelId, segment); available.ClientSend(channelId, segment);
} }
void InitServer()
{
// wire all the base transports to our events
foreach (Transport transport in transports)
{
transport.OnServerConnected.AddListener(OnServerConnected.Invoke);
transport.OnServerDataReceived.AddListener(OnServerDataReceived.Invoke);
transport.OnServerError.AddListener(OnServerError.Invoke);
transport.OnServerDisconnected.AddListener(OnServerDisconnected.Invoke);
}
}
// right now this just returns the first available uri, // right now this just returns the first available uri,
// should we return the list of all available uri? // should we return the list of all available uri?
public override Uri ServerUri() => available.ServerUri(); public override Uri ServerUri() => available.ServerUri();
@ -145,6 +122,10 @@ public override void ServerSend(int connectionId, int channelId, ArraySegment<by
public override void ServerStart() public override void ServerStart()
{ {
available.OnServerConnected = OnServerConnected;
available.OnServerDataReceived = OnServerDataReceived;
available.OnServerError = OnServerError;
available.OnServerDisconnected = OnServerDisconnected;
available.ServerStart(); available.ServerStart();
} }

View File

@ -12,26 +12,20 @@ public abstract class MiddlewareTransport : Transport
/// </summary> /// </summary>
public Transport inner; public Transport inner;
public virtual void Awake()
{
// listen for inner events and invoke when they are called
inner.OnClientConnected.AddListener(OnClientConnected.Invoke);
inner.OnClientDataReceived.AddListener(OnClientDataReceived.Invoke);
inner.OnClientDisconnected.AddListener(OnClientDisconnected.Invoke);
inner.OnClientError.AddListener(OnClientError.Invoke);
inner.OnServerConnected.AddListener(OnServerConnected.Invoke);
inner.OnServerDataReceived.AddListener(OnServerDataReceived.Invoke);
inner.OnServerDisconnected.AddListener(OnServerDisconnected.Invoke);
inner.OnServerError.AddListener(OnServerError.Invoke);
}
public override bool Available() => inner.Available(); public override bool Available() => inner.Available();
public override int GetMaxPacketSize(int channelId = 0) => inner.GetMaxPacketSize(channelId); public override int GetMaxPacketSize(int channelId = 0) => inner.GetMaxPacketSize(channelId);
public override void Shutdown() => inner.Shutdown(); public override void Shutdown() => inner.Shutdown();
#region Client #region Client
public override void ClientConnect(string address) => inner.ClientConnect(address); public override void ClientConnect(string address)
{
inner.OnClientConnected = OnClientConnected;
inner.OnClientDataReceived = OnClientDataReceived;
inner.OnClientDisconnected = OnClientDisconnected;
inner.OnClientError = OnClientError;
inner.ClientConnect(address);
}
public override bool ClientConnected() => inner.ClientConnected(); public override bool ClientConnected() => inner.ClientConnected();
public override void ClientDisconnect() => inner.ClientDisconnect(); public override void ClientDisconnect() => inner.ClientDisconnect();
public override void ClientSend(int channelId, ArraySegment<byte> segment) => inner.ClientSend(channelId, segment); public override void ClientSend(int channelId, ArraySegment<byte> segment) => inner.ClientSend(channelId, segment);
@ -39,7 +33,15 @@ public virtual void Awake()
#region Server #region Server
public override bool ServerActive() => inner.ServerActive(); public override bool ServerActive() => inner.ServerActive();
public override void ServerStart() => inner.ServerStart(); public override void ServerStart()
{
inner.OnServerConnected = OnServerConnected;
inner.OnServerDataReceived = OnServerDataReceived;
inner.OnServerDisconnected = OnServerDisconnected;
inner.OnServerError = OnServerError;
inner.ServerStart();
}
public override void ServerStop() => inner.ServerStop(); public override void ServerStop() => inner.ServerStop();
public override void ServerSend(int connectionId, int channelId, ArraySegment<byte> segment) => inner.ServerSend(connectionId, channelId, segment); public override void ServerSend(int connectionId, int channelId, ArraySegment<byte> segment) => inner.ServerSend(connectionId, channelId, segment);
public override bool ServerDisconnect(int connectionId) => inner.ServerDisconnect(connectionId); public override bool ServerDisconnect(int connectionId) => inner.ServerDisconnect(connectionId);

View File

@ -17,8 +17,6 @@ public void Awake()
{ {
Debug.LogError("Multiplex transport requires at least 1 underlying transport"); Debug.LogError("Multiplex transport requires at least 1 underlying transport");
} }
InitClient();
InitServer();
} }
void OnEnable() void OnEnable()
@ -51,18 +49,6 @@ public override bool Available()
} }
#region Client #region Client
// clients always pick the first transport
void InitClient()
{
// wire all the base transports to my events
foreach (Transport transport in transports)
{
transport.OnClientConnected.AddListener(OnClientConnected.Invoke);
transport.OnClientDataReceived.AddListener(OnClientDataReceived.Invoke);
transport.OnClientError.AddListener(OnClientError.Invoke);
transport.OnClientDisconnected.AddListener(OnClientDisconnected.Invoke);
}
}
public override void ClientConnect(string address) public override void ClientConnect(string address)
{ {
@ -71,6 +57,10 @@ public override void ClientConnect(string address)
if (transport.Available()) if (transport.Available())
{ {
available = transport; available = transport;
transport.OnClientConnected = OnClientConnected;
transport.OnClientDataReceived = OnClientDataReceived;
transport.OnClientError = OnClientError;
transport.OnClientDisconnected = OnClientDisconnected;
transport.ClientConnect(address); transport.ClientConnect(address);
return; return;
} }
@ -86,8 +76,12 @@ public override void ClientConnect(Uri uri)
{ {
try try
{ {
transport.ClientConnect(uri);
available = transport; available = transport;
transport.OnClientConnected = OnClientConnected;
transport.OnClientDataReceived = OnClientDataReceived;
transport.OnClientError = OnClientError;
transport.OnClientDisconnected = OnClientDisconnected;
transport.ClientConnect(uri);
return; return;
} }
catch (ArgumentException) catch (ArgumentException)
@ -138,7 +132,7 @@ int ToTransportId(int connectionId)
return connectionId % transports.Length; return connectionId % transports.Length;
} }
void InitServer() void AddServerCallbacks()
{ {
// wire all the base transports to my events // wire all the base transports to my events
for (int i = 0; i < transports.Length; i++) for (int i = 0; i < transports.Length; i++)
@ -148,24 +142,24 @@ void InitServer()
int locali = i; int locali = i;
Transport transport = transports[i]; Transport transport = transports[i];
transport.OnServerConnected.AddListener(baseConnectionId => transport.OnServerConnected = (baseConnectionId =>
{ {
OnServerConnected.Invoke(FromBaseId(locali, baseConnectionId)); OnServerConnected.Invoke(FromBaseId(locali, baseConnectionId));
}); });
transport.OnServerDataReceived.AddListener((baseConnectionId, data, channel) => transport.OnServerDataReceived = (baseConnectionId, data, channel) =>
{ {
OnServerDataReceived.Invoke(FromBaseId(locali, baseConnectionId), data, channel); OnServerDataReceived.Invoke(FromBaseId(locali, baseConnectionId), data, channel);
}); };
transport.OnServerError.AddListener((baseConnectionId, error) => transport.OnServerError = (baseConnectionId, error) =>
{ {
OnServerError.Invoke(FromBaseId(locali, baseConnectionId), error); OnServerError.Invoke(FromBaseId(locali, baseConnectionId), error);
}); };
transport.OnServerDisconnected.AddListener(baseConnectionId => transport.OnServerDisconnected = baseConnectionId =>
{ {
OnServerDisconnected.Invoke(FromBaseId(locali, baseConnectionId)); OnServerDisconnected.Invoke(FromBaseId(locali, baseConnectionId));
}); };
} }
} }
@ -222,6 +216,7 @@ public override void ServerStart()
{ {
foreach (Transport transport in transports) foreach (Transport transport in transports)
{ {
AddServerCallbacks();
transport.ServerStart(); transport.ServerStart();
} }
} }

View File

@ -1,16 +1,8 @@
using System; using System;
using UnityEngine; using UnityEngine;
using UnityEngine.Events;
namespace Mirror namespace Mirror
{ {
// UnityEvent definitions
[Serializable] public class ClientDataReceivedEvent : UnityEvent<ArraySegment<byte>, int> { }
[Serializable] public class UnityEventException : UnityEvent<Exception> { }
[Serializable] public class UnityEventInt : UnityEvent<int> { }
[Serializable] public class ServerDataReceivedEvent : UnityEvent<int, ArraySegment<byte>, int> { }
[Serializable] public class UnityEventIntException : UnityEvent<int, Exception> { }
/// <summary> /// <summary>
/// Abstract transport layer component /// Abstract transport layer component
/// </summary> /// </summary>
@ -36,24 +28,27 @@ public abstract class Transport : MonoBehaviour
#region Client #region Client
/// <summary> /// <summary>
/// Notify subscribers when when this client establish a successful connection to the server /// Notify subscribers when when this client establish a successful connection to the server
/// <para>callback()</para>
/// </summary> /// </summary>
[HideInInspector] public UnityEvent OnClientConnected = new UnityEvent(); public Action OnClientConnected = () => Debug.LogWarning("OnClientConnected called with no handler");
/// <summary> /// <summary>
/// Notify subscribers when this client receive data from the server /// Notify subscribers when this client receive data from the server
/// <para>callback(ArraySegment&lt;byte&gt; data, int channel)</para>
/// </summary> /// </summary>
// Note: we provide channelId for NetworkDiagnostics. public Action<ArraySegment<byte>, int> OnClientDataReceived = (data, channel) => Debug.LogWarning("OnClientDataReceived called with no handler");
[HideInInspector] public ClientDataReceivedEvent OnClientDataReceived = new ClientDataReceivedEvent();
/// <summary> /// <summary>
/// Notify subscribers when this client encounters an error communicating with the server /// Notify subscribers when this client encounters an error communicating with the server
/// <para>callback(Exception e)</para>
/// </summary> /// </summary>
[HideInInspector] public UnityEventException OnClientError = new UnityEventException(); public Action<Exception> OnClientError = (error) => Debug.LogWarning("OnClientError called with no handler");
/// <summary> /// <summary>
/// Notify subscribers when this client disconnects from the server /// Notify subscribers when this client disconnects from the server
/// <para>callback()</para>
/// </summary> /// </summary>
[HideInInspector] public UnityEvent OnClientDisconnected = new UnityEvent(); public Action OnClientDisconnected = () => Debug.LogWarning("OnClientDisconnected called with no handler");
/// <summary> /// <summary>
/// Determines if we are currently connected to the server /// Determines if we are currently connected to the server
@ -106,24 +101,27 @@ public virtual void ClientConnect(Uri uri)
/// <summary> /// <summary>
/// Notify subscribers when a client connects to this server /// Notify subscribers when a client connects to this server
/// <para>callback(int connId)</para>
/// </summary> /// </summary>
[HideInInspector] public UnityEventInt OnServerConnected = new UnityEventInt(); public Action<int> OnServerConnected = (connId) => Debug.LogWarning("OnServerConnected called with no handler");
/// <summary> /// <summary>
/// Notify subscribers when this server receives data from the client /// Notify subscribers when this server receives data from the client
/// <para>callback(int connId, ArraySegment&lt;byte&gt; data, int channel)</para>
/// </summary> /// </summary>
// Note: we provide channelId for NetworkDiagnostics. public Action<int, ArraySegment<byte>, int> OnServerDataReceived = (connId, data, channel) => Debug.LogWarning("OnServerDataReceived called with no handler");
[HideInInspector] public ServerDataReceivedEvent OnServerDataReceived = new ServerDataReceivedEvent();
/// <summary> /// <summary>
/// Notify subscribers when this server has some problem communicating with the client /// Notify subscribers when this server has some problem communicating with the client
/// <para>callback(int connId, Exception e)</para>
/// </summary> /// </summary>
[HideInInspector] public UnityEventIntException OnServerError = new UnityEventIntException(); public Action<int, Exception> OnServerError = (connId, error) => Debug.LogWarning("OnServerError called with no handler");
/// <summary> /// <summary>
/// Notify subscribers when a client disconnects from this server /// Notify subscribers when a client disconnects from this server
/// <para>callback(int connId)</para>
/// </summary> /// </summary>
[HideInInspector] public UnityEventInt OnServerDisconnected = new UnityEventInt(); public Action<int> OnServerDisconnected = (connId) => Debug.LogWarning("OnServerDisconnected called with no handler");
/// <summary> /// <summary>
/// Determines if the server is up and running /// Determines if the server is up and running

View File

@ -1,4 +1,4 @@
// memory transport for easier testing // memory transport for easier testing
// note: file needs to be outside of Editor folder, otherwise AddComponent // note: file needs to be outside of Editor folder, otherwise AddComponent
// can't be called with MemoryTransport // can't be called with MemoryTransport
using System; using System;

View File

@ -2,7 +2,6 @@
using NSubstitute; using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
using UnityEngine; using UnityEngine;
using UnityEngine.Events;
namespace Mirror.Tests namespace Mirror.Tests
{ {
@ -114,9 +113,12 @@ public void TestClient1Connected()
transport1.Available().Returns(true); transport1.Available().Returns(true);
transport2.Available().Returns(true); transport2.Available().Returns(true);
UnityAction callback = Substitute.For<UnityAction>(); Action callback = Substitute.For<Action>();
// find available
transport.Awake(); transport.Awake();
transport.OnClientConnected.AddListener(callback); // set event and connect to give event to inner
transport.OnClientConnected = callback;
transport.ClientConnect("localhost");
transport1.OnClientConnected.Invoke(); transport1.OnClientConnected.Invoke();
callback.Received().Invoke(); callback.Received().Invoke();
} }
@ -124,12 +126,15 @@ public void TestClient1Connected()
[Test] [Test]
public void TestClient2Connected() public void TestClient2Connected()
{ {
transport1.Available().Returns(true); transport1.Available().Returns(false);
transport2.Available().Returns(true); transport2.Available().Returns(true);
UnityAction callback = Substitute.For<UnityAction>(); Action callback = Substitute.For<Action>();
// find available
transport.Awake(); transport.Awake();
transport.OnClientConnected.AddListener(callback); // set event and connect to give event to inner
transport.OnClientConnected = callback;
transport.ClientConnect("localhost");
transport2.OnClientConnected.Invoke(); transport2.OnClientConnected.Invoke();
callback.Received().Invoke(); callback.Received().Invoke();
} }
@ -146,15 +151,19 @@ public void TestServerConnected()
transport1.Available().Returns(true); transport1.Available().Returns(true);
transport2.Available().Returns(true); transport2.Available().Returns(true);
// find available
transport.Awake(); transport.Awake();
// on connect, send a message back // on connect, send a message back
void SendMessage(int connectionId) void SendMessage(int connectionId)
{ {
transport.ServerSend(connectionId, 5, segment); transport.ServerSend(connectionId, 5, segment);
} }
transport.OnServerConnected.AddListener(SendMessage); // set event and Start to give event to inner
transport.OnServerConnected = SendMessage;
transport.ServerStart();
transport1.OnServerConnected.Invoke(1); transport1.OnServerConnected.Invoke(1);

View File

@ -23,8 +23,6 @@ public void Setup()
middleware = gameObject.AddComponent<MyMiddleware>(); middleware = gameObject.AddComponent<MyMiddleware>();
middleware.inner = inner; middleware.inner = inner;
//manually call awake in editmode
middleware.Awake();
} }
[TearDown] [TearDown]
@ -204,13 +202,15 @@ public void TestServerUri(string address)
} }
[Test] [Test]
public void TestOnClientConnected() public void TestClientConnectedCallback()
{ {
int called = 0; int called = 0;
middleware.OnClientConnected.AddListener(() => middleware.OnClientConnected = () =>
{ {
called++; called++;
}); };
// connect to give callback to inner
middleware.ClientConnect("localhost");
inner.OnClientConnected.Invoke(); inner.OnClientConnected.Invoke();
Assert.That(called, Is.EqualTo(1)); Assert.That(called, Is.EqualTo(1));
@ -222,21 +222,22 @@ public void TestOnClientConnected()
[Test] [Test]
[TestCase(0)] [TestCase(0)]
[TestCase(1)] [TestCase(1)]
public void TestOnClientDataReceived(int channel) public void TestClientDataReceivedCallback(int channel)
{ {
byte[] data = new byte[4]; byte[] data = new byte[4];
ArraySegment<byte> segment = new ArraySegment<byte>(data, 1, 2); ArraySegment<byte> segment = new ArraySegment<byte>(data, 1, 2);
int called = 0; int called = 0;
middleware.OnClientDataReceived.AddListener((d, c) => middleware.OnClientDataReceived = (d, c) =>
{ {
called++; called++;
Assert.That(c, Is.EqualTo(channel)); Assert.That(c, Is.EqualTo(channel));
Assert.That(d.Array, Is.EqualTo(segment.Array)); Assert.That(d.Array, Is.EqualTo(segment.Array));
Assert.That(d.Offset, Is.EqualTo(segment.Offset)); Assert.That(d.Offset, Is.EqualTo(segment.Offset));
Assert.That(d.Count, Is.EqualTo(segment.Count)); Assert.That(d.Count, Is.EqualTo(segment.Count));
}); };
// connect to give callback to inner
middleware.ClientConnect("localhost");
inner.OnClientDataReceived.Invoke(segment, channel); inner.OnClientDataReceived.Invoke(segment, channel);
Assert.That(called, Is.EqualTo(1)); Assert.That(called, Is.EqualTo(1));
@ -250,13 +251,15 @@ public void TestOnClientDataReceived(int channel)
} }
[Test] [Test]
public void TestOnClientDisconnected() public void TestClientDisconnectedCallback()
{ {
int called = 0; int called = 0;
middleware.OnClientDisconnected.AddListener(() => middleware.OnClientDisconnected = () =>
{ {
called++; called++;
}); };
// connect to give callback to inner
middleware.ClientConnect("localhost");
inner.OnClientDisconnected.Invoke(); inner.OnClientDisconnected.Invoke();
Assert.That(called, Is.EqualTo(1)); Assert.That(called, Is.EqualTo(1));
@ -266,16 +269,18 @@ public void TestOnClientDisconnected()
} }
[Test] [Test]
public void TestOnClientError() public void TestClientErrorCallback()
{ {
Exception exception = new InvalidDataException(); Exception exception = new InvalidDataException();
int called = 0; int called = 0;
middleware.OnClientError.AddListener((e) => middleware.OnClientError = (e) =>
{ {
called++; called++;
Assert.That(e, Is.EqualTo(exception)); Assert.That(e, Is.EqualTo(exception));
}); };
// connect to give callback to inner
middleware.ClientConnect("localhost");
inner.OnClientError.Invoke(exception); inner.OnClientError.Invoke(exception);
Assert.That(called, Is.EqualTo(1)); Assert.That(called, Is.EqualTo(1));
@ -290,14 +295,16 @@ public void TestOnClientError()
[TestCase(0)] [TestCase(0)]
[TestCase(1)] [TestCase(1)]
[TestCase(19)] [TestCase(19)]
public void TestOnServerConnected(int id) public void TestServerConnectedCallback(int id)
{ {
int called = 0; int called = 0;
middleware.OnServerConnected.AddListener((i) => middleware.OnServerConnected = (i) =>
{ {
called++; called++;
Assert.That(i, Is.EqualTo(id)); Assert.That(i, Is.EqualTo(id));
}); };
// start to give callback to inner
middleware.ServerStart();
inner.OnServerConnected.Invoke(id); inner.OnServerConnected.Invoke(id);
Assert.That(called, Is.EqualTo(1)); Assert.That(called, Is.EqualTo(1));
@ -313,13 +320,13 @@ public void TestOnServerConnected(int id)
[TestCase(0, 1)] [TestCase(0, 1)]
[TestCase(1, 1)] [TestCase(1, 1)]
[TestCase(19, 1)] [TestCase(19, 1)]
public void TestOnServerDataReceived(int id, int channel) public void TestServerDataReceivedCallback(int id, int channel)
{ {
byte[] data = new byte[4]; byte[] data = new byte[4];
ArraySegment<byte> segment = new ArraySegment<byte>(data, 1, 2); ArraySegment<byte> segment = new ArraySegment<byte>(data, 1, 2);
int called = 0; int called = 0;
middleware.OnServerDataReceived.AddListener((i, d, c) => middleware.OnServerDataReceived = (i, d, c) =>
{ {
called++; called++;
Assert.That(i, Is.EqualTo(id)); Assert.That(i, Is.EqualTo(id));
@ -327,8 +334,9 @@ public void TestOnServerDataReceived(int id, int channel)
Assert.That(d.Array, Is.EqualTo(segment.Array)); Assert.That(d.Array, Is.EqualTo(segment.Array));
Assert.That(d.Offset, Is.EqualTo(segment.Offset)); Assert.That(d.Offset, Is.EqualTo(segment.Offset));
Assert.That(d.Count, Is.EqualTo(segment.Count)); Assert.That(d.Count, Is.EqualTo(segment.Count));
}); };
// start to give callback to inner
middleware.ServerStart();
inner.OnServerDataReceived.Invoke(id, segment, channel); inner.OnServerDataReceived.Invoke(id, segment, channel);
Assert.That(called, Is.EqualTo(1)); Assert.That(called, Is.EqualTo(1));
@ -345,14 +353,16 @@ public void TestOnServerDataReceived(int id, int channel)
[TestCase(0)] [TestCase(0)]
[TestCase(1)] [TestCase(1)]
[TestCase(19)] [TestCase(19)]
public void TestOnServerDisconnected(int id) public void TestServerDisconnectedCallback(int id)
{ {
int called = 0; int called = 0;
middleware.OnServerDisconnected.AddListener((i) => middleware.OnServerDisconnected = (i) =>
{ {
called++; called++;
Assert.That(i, Is.EqualTo(id)); Assert.That(i, Is.EqualTo(id));
}); };
// start to give callback to inner
middleware.ServerStart();
inner.OnServerDisconnected.Invoke(id); inner.OnServerDisconnected.Invoke(id);
Assert.That(called, Is.EqualTo(1)); Assert.That(called, Is.EqualTo(1));
@ -365,17 +375,19 @@ public void TestOnServerDisconnected(int id)
[TestCase(0)] [TestCase(0)]
[TestCase(1)] [TestCase(1)]
[TestCase(19)] [TestCase(19)]
public void TestOnServerError(int id) public void TestServerErrorCallback(int id)
{ {
Exception exception = new InvalidDataException(); Exception exception = new InvalidDataException();
int called = 0; int called = 0;
middleware.OnServerError.AddListener((i, e) => middleware.OnServerError = (i, e) =>
{ {
called++; called++;
Assert.That(i, Is.EqualTo(id)); Assert.That(i, Is.EqualTo(id));
Assert.That(e, Is.EqualTo(exception)); Assert.That(e, Is.EqualTo(exception));
}); };
// start to give callback to inner
middleware.ServerStart();
inner.OnServerError.Invoke(id, exception); inner.OnServerError.Invoke(id, exception);
Assert.That(called, Is.EqualTo(1)); Assert.That(called, Is.EqualTo(1));

View File

@ -2,7 +2,6 @@
using NSubstitute; using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
using UnityEngine; using UnityEngine;
using UnityEngine.Events;
namespace Mirror.Tests namespace Mirror.Tests
{ {
@ -137,8 +136,15 @@ public void TestClientSend()
[Test] [Test]
public void TestClient1Connected() public void TestClient1Connected()
{ {
UnityAction callback = Substitute.For<UnityAction>(); transport1.Available().Returns(true);
transport.OnClientConnected.AddListener(callback); transport2.Available().Returns(true);
Action callback = Substitute.For<Action>();
// find available
transport.Awake();
// set event and connect to give event to inner
transport.OnClientConnected = callback;
transport.ClientConnect("localhost");
transport1.OnClientConnected.Invoke(); transport1.OnClientConnected.Invoke();
callback.Received().Invoke(); callback.Received().Invoke();
} }
@ -146,8 +152,15 @@ public void TestClient1Connected()
[Test] [Test]
public void TestClient2Connected() public void TestClient2Connected()
{ {
UnityAction callback = Substitute.For<UnityAction>(); transport1.Available().Returns(false);
transport.OnClientConnected.AddListener(callback); transport2.Available().Returns(true);
Action callback = Substitute.For<Action>();
// find available
transport.Awake();
// set event and connect to give event to inner
transport.OnClientConnected = callback;
transport.ClientConnect("localhost");
transport2.OnClientConnected.Invoke(); transport2.OnClientConnected.Invoke();
callback.Received().Invoke(); callback.Received().Invoke();
} }
@ -169,7 +182,9 @@ void SendMessage(int connectionId)
transport.ServerSend(connectionId, 5, segment); transport.ServerSend(connectionId, 5, segment);
} }
transport.OnServerConnected.AddListener(SendMessage); // set event and Start to give event to inner
transport.OnServerConnected = SendMessage;
transport.ServerStart();
transport1.OnServerConnected.Invoke(1); transport1.OnServerConnected.Invoke(1);

View File

@ -506,7 +506,7 @@ PlayerSettings:
webGLLinkerTarget: 1 webGLLinkerTarget: 1
webGLThreadsSupport: 0 webGLThreadsSupport: 0
scriptingDefineSymbols: scriptingDefineSymbols:
1: MIRROR;MIRROR_1726_OR_NEWER;MIRROR_3_0_OR_NEWER;MIRROR_3_12_OR_NEWER;MIRROR_4_0_OR_NEWER;MIRROR_5_0_OR_NEWER;MIRROR_6_0_OR_NEWER;MIRROR_7_0_OR_NEWER;MIRROR_8_0_OR_NEWER;MIRROR_9_0_OR_NEWER;MIRROR_10_0_OR_NEWER;MIRROR_11_0_OR_NEWER;MIRROR_12_0_OR_NEWER;MIRROR_13_0_OR_NEWER;MIRROR_14_0_OR_NEWER;MIRROR_15_0_OR_NEWER;MIRROR_16_0_OR_NEWER;MIRROR_17_0_OR_NEWER;MIRROR_18_0_OR_NEWER;MIRROR_24_0_OR_NEWER;MIRROR_26_0_OR_NEWER;MIRROR_27_0_OR_NEWER;MIRROR_28_0_OR_NEWER 1: MIRROR;MIRROR_1726_OR_NEWER;MIRROR_3_0_OR_NEWER;MIRROR_3_12_OR_NEWER;MIRROR_4_0_OR_NEWER;MIRROR_5_0_OR_NEWER;MIRROR_6_0_OR_NEWER;MIRROR_7_0_OR_NEWER;MIRROR_8_0_OR_NEWER;MIRROR_9_0_OR_NEWER;MIRROR_10_0_OR_NEWER;MIRROR_11_0_OR_NEWER;MIRROR_12_0_OR_NEWER;MIRROR_13_0_OR_NEWER;MIRROR_14_0_OR_NEWER;MIRROR_15_0_OR_NEWER;MIRROR_16_0_OR_NEWER;MIRROR_17_0_OR_NEWER;MIRROR_18_0_OR_NEWER;MIRROR_24_0_OR_NEWER;MIRROR_26_0_OR_NEWER;MIRROR_27_0_OR_NEWER;MIRROR_28_0_OR_NEWER;MIRROR_29_0_OR_NEWER
platformArchitecture: {} platformArchitecture: {}
scriptingBackend: {} scriptingBackend: {}
il2cppCompilerConfiguration: {} il2cppCompilerConfiguration: {}