breaking: NetworkReader/WriterPool API simplified: GetReader/Writer => Get; Recycle => Return; (#3112)

* breaking: NetworkReader/WriterPool API simplified: GetReader/Writer => Take; Recycle => Return;

* rename Take() to Get()

* Pool<T> Take() => Get()
This commit is contained in:
vis2k 2022-03-10 19:37:21 +08:00 committed by GitHub
parent 006efa090e
commit f0c9a81c10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 86 additions and 62 deletions

View File

@ -175,7 +175,7 @@ async Task ReceiveRequestAsync(UdpClient udpClient)
UdpReceiveResult udpReceiveResult = await udpClient.ReceiveAsync(); UdpReceiveResult udpReceiveResult = await udpClient.ReceiveAsync();
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(udpReceiveResult.Buffer)) using (PooledNetworkReader networkReader = NetworkReaderPool.Get(udpReceiveResult.Buffer))
{ {
long handshake = networkReader.ReadLong(); long handshake = networkReader.ReadLong();
if (handshake != secretHandshake) if (handshake != secretHandshake)
@ -206,7 +206,7 @@ protected virtual void ProcessClientRequest(Request request, IPEndPoint endpoint
if (info == null) if (info == null)
return; return;
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter()) using (PooledNetworkWriter writer = NetworkWriterPool.Get())
{ {
try try
{ {
@ -369,7 +369,7 @@ public void BroadcastDiscoveryRequest()
IPEndPoint endPoint = new IPEndPoint(IPAddress.Broadcast, serverBroadcastListenPort); IPEndPoint endPoint = new IPEndPoint(IPAddress.Broadcast, serverBroadcastListenPort);
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter()) using (PooledNetworkWriter writer = NetworkWriterPool.Get())
{ {
writer.WriteLong(secretHandshake); writer.WriteLong(secretHandshake);
@ -406,7 +406,7 @@ async Task ReceiveGameBroadcastAsync(UdpClient udpClient)
UdpReceiveResult udpReceiveResult = await udpClient.ReceiveAsync(); UdpReceiveResult udpReceiveResult = await udpClient.ReceiveAsync();
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(udpReceiveResult.Buffer)) using (PooledNetworkReader networkReader = NetworkReaderPool.Get(udpReceiveResult.Buffer))
{ {
if (networkReader.ReadLong() != secretHandshake) if (networkReader.ReadLong() != secretHandshake)
return; return;

View File

@ -106,7 +106,7 @@ void FixedUpdate()
continue; continue;
} }
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter()) using (PooledNetworkWriter writer = NetworkWriterPool.Get())
{ {
WriteParameters(writer); WriteParameters(writer);
SendAnimationMessage(stateHash, normalizedTime, i, layerWeight[i], writer.ToArray()); SendAnimationMessage(stateHash, normalizedTime, i, layerWeight[i], writer.ToArray());
@ -193,7 +193,7 @@ void CheckSendRate()
{ {
nextSendTime = now + syncInterval; nextSendTime = now + syncInterval;
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter()) using (PooledNetworkWriter writer = NetworkWriterPool.Get())
{ {
if (WriteParameters(writer)) if (WriteParameters(writer))
SendAnimationParametersMessage(writer.ToArray()); SendAnimationParametersMessage(writer.ToArray());
@ -527,7 +527,7 @@ void CmdOnAnimationServerMessage(int stateHash, float normalizedTime, int layerI
//Debug.Log($"OnAnimationMessage for netId {netId}"); //Debug.Log($"OnAnimationMessage for netId {netId}");
// handle and broadcast // handle and broadcast
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(parameters)) using (PooledNetworkReader networkReader = NetworkReaderPool.Get(parameters))
{ {
HandleAnimMsg(stateHash, normalizedTime, layerId, weight, networkReader); HandleAnimMsg(stateHash, normalizedTime, layerId, weight, networkReader);
RpcOnAnimationClientMessage(stateHash, normalizedTime, layerId, weight, parameters); RpcOnAnimationClientMessage(stateHash, normalizedTime, layerId, weight, parameters);
@ -542,7 +542,7 @@ void CmdOnAnimationParametersServerMessage(byte[] parameters)
return; return;
// handle and broadcast // handle and broadcast
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(parameters)) using (PooledNetworkReader networkReader = NetworkReaderPool.Get(parameters))
{ {
HandleAnimParamsMsg(networkReader); HandleAnimParamsMsg(networkReader);
RpcOnAnimationParametersClientMessage(parameters); RpcOnAnimationParametersClientMessage(parameters);
@ -600,14 +600,14 @@ void CmdSetAnimatorSpeed(float newSpeed)
[ClientRpc] [ClientRpc]
void RpcOnAnimationClientMessage(int stateHash, float normalizedTime, int layerId, float weight, byte[] parameters) void RpcOnAnimationClientMessage(int stateHash, float normalizedTime, int layerId, float weight, byte[] parameters)
{ {
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(parameters)) using (PooledNetworkReader networkReader = NetworkReaderPool.Get(parameters))
HandleAnimMsg(stateHash, normalizedTime, layerId, weight, networkReader); HandleAnimMsg(stateHash, normalizedTime, layerId, weight, networkReader);
} }
[ClientRpc] [ClientRpc]
void RpcOnAnimationParametersClientMessage(byte[] parameters) void RpcOnAnimationParametersClientMessage(byte[] parameters)
{ {
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(parameters)) using (PooledNetworkReader networkReader = NetworkReaderPool.Get(parameters))
HandleAnimParamsMsg(networkReader); HandleAnimParamsMsg(networkReader);
} }

View File

@ -38,7 +38,7 @@ public static MethodDefinition ProcessCommandCall(WeaverTypes weaverTypes, Write
NetworkBehaviourProcessor.WriteSetupLocals(worker, weaverTypes); NetworkBehaviourProcessor.WriteSetupLocals(worker, weaverTypes);
// NetworkWriter writer = new NetworkWriter(); // NetworkWriter writer = new NetworkWriter();
NetworkBehaviourProcessor.WriteCreateWriter(worker, weaverTypes); NetworkBehaviourProcessor.WriteGetWriter(worker, weaverTypes);
// write all the arguments that the user passed to the Cmd call // write all the arguments that the user passed to the Cmd call
if (!NetworkBehaviourProcessor.WriteArguments(worker, writers, Log, md, RemoteCallType.Command, ref WeavingFailed)) if (!NetworkBehaviourProcessor.WriteArguments(worker, writers, Log, md, RemoteCallType.Command, ref WeavingFailed))
@ -59,7 +59,7 @@ public static MethodDefinition ProcessCommandCall(WeaverTypes weaverTypes, Write
worker.Emit(requiresAuthority ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0); worker.Emit(requiresAuthority ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
worker.Emit(OpCodes.Call, weaverTypes.sendCommandInternal); worker.Emit(OpCodes.Call, weaverTypes.sendCommandInternal);
NetworkBehaviourProcessor.WriteRecycleWriter(worker, weaverTypes); NetworkBehaviourProcessor.WriteReturnWriter(worker, weaverTypes);
worker.Emit(OpCodes.Ret); worker.Emit(OpCodes.Ret);
return cmd; return cmd;

View File

@ -140,18 +140,18 @@ public static void WriteSetupLocals(ILProcessor worker, WeaverTypes weaverTypes)
worker.Body.Variables.Add(new VariableDefinition(weaverTypes.Import<PooledNetworkWriter>())); worker.Body.Variables.Add(new VariableDefinition(weaverTypes.Import<PooledNetworkWriter>()));
} }
public static void WriteCreateWriter(ILProcessor worker, WeaverTypes weaverTypes) public static void WriteGetWriter(ILProcessor worker, WeaverTypes weaverTypes)
{ {
// create writer // create writer
worker.Emit(OpCodes.Call, weaverTypes.GetPooledWriterReference); worker.Emit(OpCodes.Call, weaverTypes.GetWriterReference);
worker.Emit(OpCodes.Stloc_0); worker.Emit(OpCodes.Stloc_0);
} }
public static void WriteRecycleWriter(ILProcessor worker, WeaverTypes weaverTypes) public static void WriteReturnWriter(ILProcessor worker, WeaverTypes weaverTypes)
{ {
// NetworkWriterPool.Recycle(writer); // NetworkWriterPool.Recycle(writer);
worker.Emit(OpCodes.Ldloc_0); worker.Emit(OpCodes.Ldloc_0);
worker.Emit(OpCodes.Call, weaverTypes.RecycleWriterReference); worker.Emit(OpCodes.Call, weaverTypes.ReturnWriterReference);
} }
public static bool WriteArguments(ILProcessor worker, Writers writers, Logger Log, MethodDefinition method, RemoteCallType callType, ref bool WeavingFailed) public static bool WriteArguments(ILProcessor worker, Writers writers, Logger Log, MethodDefinition method, RemoteCallType callType, ref bool WeavingFailed)

View File

@ -68,7 +68,7 @@ public static MethodDefinition ProcessRpcCall(WeaverTypes weaverTypes, Writers w
//worker.Emit(OpCodes.Ldstr, $"Call ClientRpc function {md.Name}"); //worker.Emit(OpCodes.Ldstr, $"Call ClientRpc function {md.Name}");
//worker.Emit(OpCodes.Call, WeaverTypes.logErrorReference); //worker.Emit(OpCodes.Call, WeaverTypes.logErrorReference);
NetworkBehaviourProcessor.WriteCreateWriter(worker, weaverTypes); NetworkBehaviourProcessor.WriteGetWriter(worker, weaverTypes);
// write all the arguments that the user passed to the Rpc call // write all the arguments that the user passed to the Rpc call
if (!NetworkBehaviourProcessor.WriteArguments(worker, writers, Log, md, RemoteCallType.ClientRpc, ref WeavingFailed)) if (!NetworkBehaviourProcessor.WriteArguments(worker, writers, Log, md, RemoteCallType.ClientRpc, ref WeavingFailed))
@ -89,7 +89,7 @@ public static MethodDefinition ProcessRpcCall(WeaverTypes weaverTypes, Writers w
worker.Emit(includeOwner ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0); worker.Emit(includeOwner ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
worker.Emit(OpCodes.Callvirt, weaverTypes.sendRpcInternal); worker.Emit(OpCodes.Callvirt, weaverTypes.sendRpcInternal);
NetworkBehaviourProcessor.WriteRecycleWriter(worker, weaverTypes); NetworkBehaviourProcessor.WriteReturnWriter(worker, weaverTypes);
worker.Emit(OpCodes.Ret); worker.Emit(OpCodes.Ret);

View File

@ -100,7 +100,7 @@ public static MethodDefinition ProcessTargetRpcCall(WeaverTypes weaverTypes, Wri
NetworkBehaviourProcessor.WriteSetupLocals(worker, weaverTypes); NetworkBehaviourProcessor.WriteSetupLocals(worker, weaverTypes);
NetworkBehaviourProcessor.WriteCreateWriter(worker, weaverTypes); NetworkBehaviourProcessor.WriteGetWriter(worker, weaverTypes);
// write all the arguments that the user passed to the TargetRpc call // write all the arguments that the user passed to the TargetRpc call
// (skip first one if first one is NetworkConnection) // (skip first one if first one is NetworkConnection)
@ -127,7 +127,7 @@ public static MethodDefinition ProcessTargetRpcCall(WeaverTypes weaverTypes, Wri
worker.Emit(OpCodes.Ldc_I4, targetRpcAttr.GetField("channel", 0)); worker.Emit(OpCodes.Ldc_I4, targetRpcAttr.GetField("channel", 0));
worker.Emit(OpCodes.Callvirt, weaverTypes.sendTargetRpcInternal); worker.Emit(OpCodes.Callvirt, weaverTypes.sendTargetRpcInternal);
NetworkBehaviourProcessor.WriteRecycleWriter(worker, weaverTypes); NetworkBehaviourProcessor.WriteReturnWriter(worker, weaverTypes);
worker.Emit(OpCodes.Ret); worker.Emit(OpCodes.Ret);

View File

@ -11,8 +11,8 @@ public class WeaverTypes
public MethodReference ScriptableObjectCreateInstanceMethod; public MethodReference ScriptableObjectCreateInstanceMethod;
public MethodReference NetworkBehaviourDirtyBitsReference; public MethodReference NetworkBehaviourDirtyBitsReference;
public MethodReference GetPooledWriterReference; public MethodReference GetWriterReference;
public MethodReference RecycleWriterReference; public MethodReference ReturnWriterReference;
public MethodReference NetworkClientConnectionReference; public MethodReference NetworkClientConnectionReference;
@ -95,8 +95,8 @@ public WeaverTypes(AssemblyDefinition assembly, Logger Log, ref bool WeavingFail
NetworkBehaviourDirtyBitsReference = Resolvers.ResolveProperty(NetworkBehaviourType, assembly, "syncVarDirtyBits"); NetworkBehaviourDirtyBitsReference = Resolvers.ResolveProperty(NetworkBehaviourType, assembly, "syncVarDirtyBits");
TypeReference NetworkWriterPoolType = Import(typeof(NetworkWriterPool)); TypeReference NetworkWriterPoolType = Import(typeof(NetworkWriterPool));
GetPooledWriterReference = Resolvers.ResolveMethod(NetworkWriterPoolType, assembly, Log, "GetWriter", ref WeavingFailed); GetWriterReference = Resolvers.ResolveMethod(NetworkWriterPoolType, assembly, Log, "Get", ref WeavingFailed);
RecycleWriterReference = Resolvers.ResolveMethod(NetworkWriterPoolType, assembly, Log, "Recycle", ref WeavingFailed); ReturnWriterReference = Resolvers.ResolveMethod(NetworkWriterPoolType, assembly, Log, "Return", ref WeavingFailed);
NetworkClientConnectionReference = Resolvers.ResolveMethod(NetworkClientType, assembly, Log, "get_connection", ref WeavingFailed); NetworkClientConnectionReference = Resolvers.ResolveMethod(NetworkClientType, assembly, Log, "get_connection", ref WeavingFailed);

View File

@ -52,7 +52,7 @@ public void AddMessage(ArraySegment<byte> message)
// would add a size header. we want to write directly. // would add a size header. we want to write directly.
// -> will be returned to pool when making the batch! // -> will be returned to pool when making the batch!
// IMPORTANT: NOT adding a size header / msg saves LOTS of bandwidth // IMPORTANT: NOT adding a size header / msg saves LOTS of bandwidth
PooledNetworkWriter writer = NetworkWriterPool.GetWriter(); PooledNetworkWriter writer = NetworkWriterPool.Get();
writer.WriteBytes(message.Array, message.Offset, message.Count); writer.WriteBytes(message.Array, message.Offset, message.Count);
messages.Enqueue(writer); messages.Enqueue(writer);
} }
@ -83,7 +83,7 @@ public bool MakeNextBatch(NetworkWriter writer, double timeStamp)
writer.WriteBytes(segment.Array, segment.Offset, segment.Count); writer.WriteBytes(segment.Array, segment.Offset, segment.Count);
// return the writer to pool // return the writer to pool
NetworkWriterPool.Recycle(message); NetworkWriterPool.Return(message);
} }
// keep going as long as we have more messages, // keep going as long as we have more messages,
// AND the next one would fit into threshold. // AND the next one would fit into threshold.

View File

@ -55,7 +55,7 @@ public bool AddBatch(ArraySegment<byte> batch)
// -> WriteBytes instead of WriteSegment because the latter // -> WriteBytes instead of WriteSegment because the latter
// would add a size header. we want to write directly. // would add a size header. we want to write directly.
// -> will be returned to pool when sending! // -> will be returned to pool when sending!
PooledNetworkWriter writer = NetworkWriterPool.GetWriter(); PooledNetworkWriter writer = NetworkWriterPool.Get();
writer.WriteBytes(batch.Array, batch.Offset, batch.Count); writer.WriteBytes(batch.Array, batch.Offset, batch.Count);
// first batch? then point reader there // first batch? then point reader there
@ -112,7 +112,7 @@ public bool GetNextMessage(out NetworkReader message, out double remoteTimeStamp
{ {
// retire the batch // retire the batch
PooledNetworkWriter writer = batches.Dequeue(); PooledNetworkWriter writer = batches.Dequeue();
NetworkWriterPool.Recycle(writer); NetworkWriterPool.Return(writer);
// do we have another batch? // do we have another batch?
if (batches.Count > 0) if (batches.Count > 0)

View File

@ -21,7 +21,7 @@ internal override void Send(ArraySegment<byte> segment, int channelId = Channels
// => WriteBytes instead of WriteArraySegment because the latter // => WriteBytes instead of WriteArraySegment because the latter
// includes a 4 bytes header. we just want to write raw. // includes a 4 bytes header. we just want to write raw.
//Debug.Log($"Enqueue {BitConverter.ToString(segment.Array, segment.Offset, segment.Count)}"); //Debug.Log($"Enqueue {BitConverter.ToString(segment.Array, segment.Offset, segment.Count)}");
PooledNetworkWriter writer = NetworkWriterPool.GetWriter(); PooledNetworkWriter writer = NetworkWriterPool.Get();
writer.WriteBytes(segment.Array, segment.Offset, segment.Count); writer.WriteBytes(segment.Array, segment.Offset, segment.Count);
connectionToServer.queue.Enqueue(writer); connectionToServer.queue.Enqueue(writer);
} }

View File

@ -37,7 +37,7 @@ internal override void Send(ArraySegment<byte> segment, int channelId = Channels
// flush it to the server's OnTransportData immediately. // flush it to the server's OnTransportData immediately.
// local connection to server always invokes immediately. // local connection to server always invokes immediately.
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter()) using (PooledNetworkWriter writer = NetworkWriterPool.Get())
{ {
// make a batch with our local time (double precision) // make a batch with our local time (double precision)
if (batcher.MakeNextBatch(writer, NetworkTime.localTime)) if (batcher.MakeNextBatch(writer, NetworkTime.localTime))
@ -71,7 +71,7 @@ internal override void Update()
Batcher batcher = GetBatchForChannelId(Channels.Reliable); Batcher batcher = GetBatchForChannelId(Channels.Reliable);
batcher.AddMessage(message); batcher.AddMessage(message);
using (PooledNetworkWriter batchWriter = NetworkWriterPool.GetWriter()) using (PooledNetworkWriter batchWriter = NetworkWriterPool.Get())
{ {
// make a batch with our local time (double precision) // make a batch with our local time (double precision)
if (batcher.MakeNextBatch(batchWriter, NetworkTime.localTime)) if (batcher.MakeNextBatch(batchWriter, NetworkTime.localTime))
@ -80,7 +80,7 @@ internal override void Update()
} }
} }
NetworkWriterPool.Recycle(writer); NetworkWriterPool.Return(writer);
} }
// should we still process a disconnected event? // should we still process a disconnected event?

View File

@ -1005,7 +1005,7 @@ internal static void ApplySpawnPayload(NetworkIdentity identity, SpawnMessage me
// (Count is 0 if there were no components) // (Count is 0 if there were no components)
if (message.payload.Count > 0) if (message.payload.Count > 0)
{ {
using (PooledNetworkReader payloadReader = NetworkReaderPool.GetReader(message.payload)) using (PooledNetworkReader payloadReader = NetworkReaderPool.Get(message.payload))
{ {
identity.OnDeserializeAllSafely(payloadReader, true); identity.OnDeserializeAllSafely(payloadReader, true);
} }
@ -1238,7 +1238,7 @@ static void OnEntityStateMessage(EntityStateMessage message)
// Debug.Log($"NetworkClient.OnUpdateVarsMessage {msg.netId}"); // Debug.Log($"NetworkClient.OnUpdateVarsMessage {msg.netId}");
if (spawned.TryGetValue(message.netId, out NetworkIdentity localObject) && localObject != null) if (spawned.TryGetValue(message.netId, out NetworkIdentity localObject) && localObject != null)
{ {
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(message.payload)) using (PooledNetworkReader networkReader = NetworkReaderPool.Get(message.payload))
localObject.OnDeserializeAllSafely(networkReader, false); localObject.OnDeserializeAllSafely(networkReader, false);
} }
else Debug.LogWarning($"Did not find target for sync message for {message.netId} . Note: this can be completely normal because UDP messages may arrive out of order, so this message might have arrived after a Destroy message."); else Debug.LogWarning($"Did not find target for sync message for {message.netId} . Note: this can be completely normal because UDP messages may arrive out of order, so this message might have arrived after a Destroy message.");
@ -1249,7 +1249,7 @@ static void OnRPCMessage(RpcMessage message)
// Debug.Log($"NetworkClient.OnRPCMessage hash:{msg.functionHash} netId:{msg.netId}"); // Debug.Log($"NetworkClient.OnRPCMessage hash:{msg.functionHash} netId:{msg.netId}");
if (spawned.TryGetValue(message.netId, out NetworkIdentity identity)) if (spawned.TryGetValue(message.netId, out NetworkIdentity identity))
{ {
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(message.payload)) using (PooledNetworkReader networkReader = NetworkReaderPool.Get(message.payload))
identity.HandleRemoteCall(message.componentIndex, message.functionHash, RemoteCallType.ClientRpc, networkReader); identity.HandleRemoteCall(message.componentIndex, message.functionHash, RemoteCallType.ClientRpc, networkReader);
} }
} }

View File

@ -129,7 +129,7 @@ protected static bool ValidatePacketSize(ArraySegment<byte> segment, int channel
public void Send<T>(T message, int channelId = Channels.Reliable) public void Send<T>(T message, int channelId = Channels.Reliable)
where T : struct, NetworkMessage where T : struct, NetworkMessage
{ {
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter()) using (PooledNetworkWriter writer = NetworkWriterPool.Get())
{ {
// pack message and send allocation free // pack message and send allocation free
MessagePacking.Pack(message, writer); MessagePacking.Pack(message, writer);
@ -176,7 +176,7 @@ internal virtual void Update()
// make and send as many batches as necessary from the stored // make and send as many batches as necessary from the stored
// messages. // messages.
Batcher batcher = kvp.Value; Batcher batcher = kvp.Value;
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter()) using (PooledNetworkWriter writer = NetworkWriterPool.Get())
{ {
// make a batch with our local time (double precision) // make a batch with our local time (double precision)
while (batcher.MakeNextBatch(writer, NetworkTime.localTime)) while (batcher.MakeNextBatch(writer, NetworkTime.localTime))

View File

@ -8,7 +8,7 @@ public sealed class PooledNetworkReader : NetworkReader, IDisposable
{ {
internal PooledNetworkReader(byte[] bytes) : base(bytes) {} internal PooledNetworkReader(byte[] bytes) : base(bytes) {}
internal PooledNetworkReader(ArraySegment<byte> segment) : base(segment) {} internal PooledNetworkReader(ArraySegment<byte> segment) : base(segment) {}
public void Dispose() => NetworkReaderPool.Recycle(this); public void Dispose() => NetworkReaderPool.Return(this);
} }
/// <summary>Pool of NetworkReaders to avoid allocations.</summary> /// <summary>Pool of NetworkReaders to avoid allocations.</summary>
@ -24,29 +24,41 @@ public static class NetworkReaderPool
1000 1000
); );
// DEPRECATED 2022-03-10
[Obsolete("GetReader() was renamed to Get()")]
public static PooledNetworkReader GetReader(byte[] bytes) => Get(bytes);
/// <summary>Get the next reader in the pool. If pool is empty, creates a new Reader</summary> /// <summary>Get the next reader in the pool. If pool is empty, creates a new Reader</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static PooledNetworkReader GetReader(byte[] bytes) public static PooledNetworkReader Get(byte[] bytes)
{ {
// grab from pool & set buffer // grab from pool & set buffer
PooledNetworkReader reader = Pool.Take(); PooledNetworkReader reader = Pool.Get();
reader.SetBuffer(bytes); reader.SetBuffer(bytes);
return reader; return reader;
} }
// DEPRECATED 2022-03-10
[Obsolete("GetReader() was renamed to Get()")]
public static PooledNetworkReader GetReader(ArraySegment<byte> segment) => Get(segment);
/// <summary>Get the next reader in the pool. If pool is empty, creates a new Reader</summary> /// <summary>Get the next reader in the pool. If pool is empty, creates a new Reader</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static PooledNetworkReader GetReader(ArraySegment<byte> segment) public static PooledNetworkReader Get(ArraySegment<byte> segment)
{ {
// grab from pool & set buffer // grab from pool & set buffer
PooledNetworkReader reader = Pool.Take(); PooledNetworkReader reader = Pool.Get();
reader.SetBuffer(segment); reader.SetBuffer(segment);
return reader; return reader;
} }
// DEPRECATED 2022-03-10
[Obsolete("Recycle() was renamed to Return()")]
public static void Recycle(PooledNetworkReader reader) => Return(reader);
/// <summary>Returns a reader to the pool.</summary> /// <summary>Returns a reader to the pool.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Recycle(PooledNetworkReader reader) public static void Return(PooledNetworkReader reader)
{ {
Pool.Return(reader); Pool.Return(reader);
} }

View File

@ -282,7 +282,7 @@ public static void SendToAll<T>(T message, int channelId = Channels.Reliable, bo
} }
// Debug.Log($"Server.SendToAll {typeof(T)}"); // Debug.Log($"Server.SendToAll {typeof(T)}");
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter()) using (PooledNetworkWriter writer = NetworkWriterPool.Get())
{ {
// pack message only once // pack message only once
MessagePacking.Pack(message, writer); MessagePacking.Pack(message, writer);
@ -328,7 +328,7 @@ static void SendToObservers<T>(NetworkIdentity identity, T message, int channelI
if (identity == null || identity.observers == null || identity.observers.Count == 0) if (identity == null || identity.observers == null || identity.observers.Count == 0)
return; return;
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter()) using (PooledNetworkWriter writer = NetworkWriterPool.Get())
{ {
// pack message into byte[] once // pack message into byte[] once
MessagePacking.Pack(message, writer); MessagePacking.Pack(message, writer);
@ -352,7 +352,7 @@ public static void SendToReadyObservers<T>(NetworkIdentity identity, T message,
if (identity == null || identity.observers == null || identity.observers.Count == 0) if (identity == null || identity.observers == null || identity.observers.Count == 0)
return; return;
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter()) using (PooledNetworkWriter writer = NetworkWriterPool.Get())
{ {
// pack message only once // pack message only once
MessagePacking.Pack(message, writer); MessagePacking.Pack(message, writer);
@ -960,7 +960,7 @@ static void OnCommandMessage(NetworkConnectionToClient conn, CommandMessage msg,
// Debug.Log($"OnCommandMessage for netId:{msg.netId} conn:{conn}"); // Debug.Log($"OnCommandMessage for netId:{msg.netId} conn:{conn}");
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(msg.payload)) using (PooledNetworkReader networkReader = NetworkReaderPool.Get(msg.payload))
identity.HandleRemoteCall(msg.componentIndex, msg.functionHash, RemoteCallType.Command, networkReader, conn as NetworkConnectionToClient); identity.HandleRemoteCall(msg.componentIndex, msg.functionHash, RemoteCallType.Command, networkReader, conn as NetworkConnectionToClient);
} }
@ -996,7 +996,7 @@ internal static void SendSpawnMessage(NetworkIdentity identity, NetworkConnectio
//Debug.Log($"Server SendSpawnMessage: name:{identity.name} sceneId:{identity.sceneId:X} netid:{identity.netId}"); //Debug.Log($"Server SendSpawnMessage: name:{identity.name} sceneId:{identity.sceneId:X} netid:{identity.netId}");
// one writer for owner, one for observers // one writer for owner, one for observers
using (PooledNetworkWriter ownerWriter = NetworkWriterPool.GetWriter(), observersWriter = NetworkWriterPool.GetWriter()) using (PooledNetworkWriter ownerWriter = NetworkWriterPool.Get(), observersWriter = NetworkWriterPool.Get())
{ {
bool isOwner = identity.connectionToClient == conn; bool isOwner = identity.connectionToClient == conn;
ArraySegment<byte> payload = CreateSpawnMessagePayload(isOwner, identity, ownerWriter, observersWriter); ArraySegment<byte> payload = CreateSpawnMessagePayload(isOwner, identity, ownerWriter, observersWriter);

View File

@ -6,7 +6,7 @@ namespace Mirror
/// <summary>Pooled NetworkWriter, automatically returned to pool when using 'using'</summary> /// <summary>Pooled NetworkWriter, automatically returned to pool when using 'using'</summary>
public sealed class PooledNetworkWriter : NetworkWriter, IDisposable public sealed class PooledNetworkWriter : NetworkWriter, IDisposable
{ {
public void Dispose() => NetworkWriterPool.Recycle(this); public void Dispose() => NetworkWriterPool.Return(this);
} }
/// <summary>Pool of NetworkWriters to avoid allocations.</summary> /// <summary>Pool of NetworkWriters to avoid allocations.</summary>
@ -24,19 +24,27 @@ public static class NetworkWriterPool
1000 1000
); );
// DEPRECATED 2022-03-10
[Obsolete("GetWriter() was renamed to Get()")]
public static PooledNetworkWriter GetWriter() => Get();
/// <summary>Get a writer from the pool. Creates new one if pool is empty.</summary> /// <summary>Get a writer from the pool. Creates new one if pool is empty.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static PooledNetworkWriter GetWriter() public static PooledNetworkWriter Get()
{ {
// grab from pool & reset position // grab from pool & reset position
PooledNetworkWriter writer = Pool.Take(); PooledNetworkWriter writer = Pool.Get();
writer.Reset(); writer.Reset();
return writer; return writer;
} }
// DEPRECATED 2022-03-10
[Obsolete("Recycle() was renamed to Return()")]
public static void Recycle(PooledNetworkWriter writer) => Return(writer);
/// <summary>Return a writer to the pool.</summary> /// <summary>Return a writer to the pool.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Recycle(PooledNetworkWriter writer) public static void Return(PooledNetworkWriter writer)
{ {
Pool.Return(writer); Pool.Return(writer);
} }

View File

@ -24,9 +24,13 @@ public Pool(Func<T> objectGenerator, int initialCapacity)
objects.Push(objectGenerator()); objects.Push(objectGenerator());
} }
// DEPRECATED 2022-03-10
[Obsolete("Take() was renamed to Get()")]
public T Take() => Get();
// take an element from the pool, or create a new one if empty // take an element from the pool, or create a new one if empty
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public T Take() => objects.Count > 0 ? objects.Pop() : objectGenerator(); public T Get() => objects.Count > 0 ? objects.Pop() : objectGenerator();
// return an element to the pool // return an element to the pool
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]

View File

@ -14,7 +14,7 @@ public struct EmptyMessage : NetworkMessage {}
public static byte[] PackToByteArray<T>(T message) public static byte[] PackToByteArray<T>(T message)
where T : struct, NetworkMessage where T : struct, NetworkMessage
{ {
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter()) using (PooledNetworkWriter writer = NetworkWriterPool.Get())
{ {
MessagePacking.Pack(message, writer); MessagePacking.Pack(message, writer);
return writer.ToArray(); return writer.ToArray();
@ -25,7 +25,7 @@ public static byte[] PackToByteArray<T>(T message)
public static T UnpackFromByteArray<T>(byte[] data) public static T UnpackFromByteArray<T>(byte[] data)
where T : struct, NetworkMessage where T : struct, NetworkMessage
{ {
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(data)) using (PooledNetworkReader networkReader = NetworkReaderPool.Get(data))
{ {
int msgType = MessagePacking.GetId<T>(); int msgType = MessagePacking.GetId<T>();

View File

@ -125,11 +125,11 @@ public class NetworkBehaviourSerializeTest : MirrorEditModeTest
{ {
static void SyncNetworkBehaviour(NetworkBehaviour source, NetworkBehaviour target, bool initialState) static void SyncNetworkBehaviour(NetworkBehaviour source, NetworkBehaviour target, bool initialState)
{ {
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter()) using (PooledNetworkWriter writer = NetworkWriterPool.Get())
{ {
source.OnSerialize(writer, initialState); source.OnSerialize(writer, initialState);
using (PooledNetworkReader reader = NetworkReaderPool.GetReader(writer.ToArraySegment())) using (PooledNetworkReader reader = NetworkReaderPool.Get(writer.ToArraySegment()))
{ {
target.OnDeserialize(reader, initialState); target.OnDeserialize(reader, initialState);
} }

View File

@ -66,7 +66,7 @@ public void ReadBytesCountTooBigTest()
// should throw an exception // should throw an exception
byte[] bytes = { 0x00, 0x01 }; byte[] bytes = { 0x00, 0x01 };
using (PooledNetworkReader reader = NetworkReaderPool.GetReader(bytes)) using (PooledNetworkReader reader = NetworkReaderPool.Get(bytes))
{ {
try try
{ {

View File

@ -22,7 +22,7 @@ public void TearDown()
public void TakeFromEmpty() public void TakeFromEmpty()
{ {
// taking from an empty pool should give us a completely new string // taking from an empty pool should give us a completely new string
Assert.That(pool.Take(), Is.EqualTo("new string")); Assert.That(pool.Get(), Is.EqualTo("new string"));
} }
[Test] [Test]
@ -31,7 +31,7 @@ public void ReturnAndTake()
// returning and then taking should get the returned one, not a // returning and then taking should get the returned one, not a
// newly generated one. // newly generated one.
pool.Return("returned"); pool.Return("returned");
Assert.That(pool.Take(), Is.EqualTo("returned")); Assert.That(pool.Get(), Is.EqualTo("returned"));
} }
[Test] [Test]

View File

@ -420,11 +420,11 @@ public static class SyncObjectTestMethods
{ {
public static uint GetChangeCount(this SyncObject syncObject) public static uint GetChangeCount(this SyncObject syncObject)
{ {
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter()) using (PooledNetworkWriter writer = NetworkWriterPool.Get())
{ {
syncObject.OnSerializeDelta(writer); syncObject.OnSerializeDelta(writer);
using (PooledNetworkReader reader = NetworkReaderPool.GetReader(writer.ToArraySegment())) using (PooledNetworkReader reader = NetworkReaderPool.Get(writer.ToArraySegment()))
{ {
return reader.ReadUInt(); return reader.ReadUInt();
} }