Skip to content

Commit 0149ea3

Browse files
feat: Make NetworkMetricsPipelineStage public
1 parent 8ba1f85 commit 0149ea3

File tree

5 files changed

+77
-15
lines changed

5 files changed

+77
-15
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
1010

1111
### Added
1212

13+
- The `NetworkMetricsPipelineStage` for Unity Transport is now part of the public API. This allows using it in custom implementations of `INetworkStreamDriverConstructor` that want to maintain compatibility with the multiplayer tools package.
1314

1415
### Changed
1516

com.unity.netcode.gameobjects/Runtime/Transports/UTP/INetworkStreamDriverConstructor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ namespace Unity.Netcode.Transports.UTP
3535
/// {
3636
/// var settings = transport.GetDefaultNetworkSettings();
3737
/// driver = NetworkDriver.Create(new IPCNetworkInterface(), settings);
38+
///
39+
/// driver.RegisterPipelineStage(new NetworkMetricsPipelineStage());
3840
///
3941
/// transport.GetDefaultPipelineConfigurations(
4042
/// out var unreliableFragmentedPipelineStages,

com.unity.netcode.gameobjects/Runtime/Transports/UTP/NetworkMetricsPipelineStage.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,32 @@
77

88
namespace Unity.Netcode.Transports.UTP
99
{
10+
/// <summary>
11+
/// A pipeline stage that tracks some internal metrics that are then used by the multiplayer
12+
/// tools package. This should only be used when creating a custom <see cref="NetworkDriver"/>
13+
/// with <see cref="INetworkStreamDriverConstructor"/> if compatibility with the multiplayer
14+
/// tools package is desired. In that situation, this stage needs to be registered with the
15+
/// constructed driver with <see cref="NetworkDriver.RegisterPipelineStage{T}"/>.
16+
/// </summary>
1017
[BurstCompile]
11-
internal unsafe struct NetworkMetricsPipelineStage : INetworkPipelineStage
18+
public unsafe struct NetworkMetricsPipelineStage : INetworkPipelineStage
1219
{
13-
private static TransportFunctionPointer<NetworkPipelineStage.ReceiveDelegate> s_ReceiveFunction = new TransportFunctionPointer<NetworkPipelineStage.ReceiveDelegate>(Receive);
14-
private static TransportFunctionPointer<NetworkPipelineStage.SendDelegate> s_SendFunction = new TransportFunctionPointer<NetworkPipelineStage.SendDelegate>(Send);
15-
private static TransportFunctionPointer<NetworkPipelineStage.InitializeConnectionDelegate> s_InitializeConnectionFunction = new TransportFunctionPointer<NetworkPipelineStage.InitializeConnectionDelegate>(InitializeConnection);
16-
20+
/// <inheritdoc/>
1721
public NetworkPipelineStage StaticInitialize(byte* staticInstanceBuffer,
1822
int staticInstanceBufferLength,
1923
NetworkSettings settings)
2024
{
2125
return new NetworkPipelineStage(
22-
s_ReceiveFunction,
23-
s_SendFunction,
24-
s_InitializeConnectionFunction,
26+
new TransportFunctionPointer<NetworkPipelineStage.ReceiveDelegate>(Receive),
27+
new TransportFunctionPointer<NetworkPipelineStage.SendDelegate>(Send),
28+
new TransportFunctionPointer<NetworkPipelineStage.InitializeConnectionDelegate>(InitializeConnection),
2529
ReceiveCapacity: 0,
2630
SendCapacity: 0,
2731
HeaderCapacity: 0,
2832
SharedStateCapacity: UnsafeUtility.SizeOf<NetworkMetricsContext>());
2933
}
3034

35+
/// <inheritdoc/>
3136
public int StaticSize => 0;
3237

3338
[BurstCompile(DisableDirectCall = true)]

com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,13 +1234,28 @@ private void ExtractNetworkMetricsFromPipeline(NetworkPipeline pipeline, Network
12341234
return;
12351235
}
12361236

1237-
//Don't need to dispose of the buffers, they are filled with data pointers.
1238-
m_Driver.GetPipelineBuffers(pipeline,
1239-
NetworkPipelineStageId.Get<NetworkMetricsPipelineStage>(),
1240-
networkConnection,
1241-
out _,
1242-
out _,
1243-
out var sharedBuffer);
1237+
try
1238+
{
1239+
// Don't need to dispose of the buffers, they are filled with data pointers.
1240+
m_Driver.GetPipelineBuffers(pipeline,
1241+
NetworkPipelineStageId.Get<NetworkMetricsPipelineStage>(),
1242+
networkConnection,
1243+
out _,
1244+
out _,
1245+
out var sharedBuffer);
1246+
}
1247+
catch (InvalidOperationException)
1248+
{
1249+
// Can happen if using a custom driver that isn't configured with the metrics stage.
1250+
return;
1251+
}
1252+
1253+
// That InvalidOperationException above is only thrown in the editor. In runtime builds
1254+
// we instead get default return values when the pipeline stage is invalid.
1255+
if (sharedBuffer == default)
1256+
{
1257+
return;
1258+
}
12441259

12451260
unsafe
12461261
{

com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,5 +229,44 @@ public void UnityTransport_HostnameValidation((string, bool) testCase)
229229
transport.Shutdown();
230230
}
231231
#endif
232+
233+
private class IPCDriverConstructor : INetworkStreamDriverConstructor
234+
{
235+
public void CreateDriver(
236+
UnityTransport transport,
237+
out NetworkDriver driver,
238+
out NetworkPipeline unreliableFragmentedPipeline,
239+
out NetworkPipeline unreliableSequencedFragmentedPipeline,
240+
out NetworkPipeline reliableSequencedPipeline)
241+
{
242+
var settings = transport.GetDefaultNetworkSettings();
243+
driver = NetworkDriver.Create(new IPCNetworkInterface(), settings);
244+
245+
driver.RegisterPipelineStage(new NetworkMetricsPipelineStage());
246+
247+
transport.GetDefaultPipelineConfigurations(
248+
out var unreliableFragmentedPipelineStages,
249+
out var unreliableSequencedFragmentedPipelineStages,
250+
out var reliableSequencedPipelineStages);
251+
252+
unreliableFragmentedPipeline = driver.CreatePipeline(unreliableFragmentedPipelineStages);
253+
unreliableSequencedFragmentedPipeline = driver.CreatePipeline(unreliableSequencedFragmentedPipelineStages);
254+
reliableSequencedPipeline = driver.CreatePipeline(reliableSequencedPipelineStages);
255+
}
256+
}
257+
258+
[Test]
259+
public void UnityTransport_CustomDriverConstructorWithDefaultPipelines()
260+
{
261+
UnityTransport transport = new GameObject().AddComponent<UnityTransport>();
262+
UnityTransport.s_DriverConstructor = new IPCDriverConstructor();
263+
transport.Initialize();
264+
265+
Assert.True(transport.StartServer());
266+
267+
transport.Shutdown();
268+
269+
UnityTransport.s_DriverConstructor = null;
270+
}
232271
}
233272
}

0 commit comments

Comments
 (0)