polygone/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Serialization/Pooled/NetworkBufferPool.cs
2021-08-02 05:44:37 -04:00

90 lines
No EOL
3.4 KiB
C#

using System;
using System.Collections.Generic;
using MLAPI.Logging;
namespace MLAPI.Serialization.Pooled
{
/// <summary>
/// Static class containing PooledNetworkBuffers
/// </summary>
public static class NetworkBufferPool
{
private static uint s_CreatedBuffers = 0;
private static Queue<WeakReference> s_OverflowBuffers = new Queue<WeakReference>();
private static Queue<PooledNetworkBuffer> s_Buffers = new Queue<PooledNetworkBuffer>();
private const uint k_MaxBitPoolBuffers = 1024;
private const uint k_MaxCreatedDelta = 768;
/// <summary>
/// Retrieves an expandable PooledNetworkBuffer from the pool
/// </summary>
/// <returns>An expandable PooledNetworkBuffer</returns>
public static PooledNetworkBuffer GetBuffer()
{
if (s_Buffers.Count == 0)
{
if (s_OverflowBuffers.Count > 0)
{
if (NetworkLog.CurrentLogLevel <= LogLevel.Developer)
{
NetworkLog.LogInfo($"Retrieving {nameof(PooledNetworkBuffer)} from overflow pool. Recent burst?");
}
object weakBuffer = null;
while (s_OverflowBuffers.Count > 0 && ((weakBuffer = s_OverflowBuffers.Dequeue().Target) == null)) ;
if (weakBuffer != null)
{
PooledNetworkBuffer strongBuffer = (PooledNetworkBuffer)weakBuffer;
strongBuffer.SetLength(0);
strongBuffer.Position = 0;
return strongBuffer;
}
}
if (s_CreatedBuffers == k_MaxBitPoolBuffers)
{
if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) NetworkLog.LogWarning($"{k_MaxBitPoolBuffers} buffers have been created. Did you forget to dispose?");
}
else if (s_CreatedBuffers < k_MaxBitPoolBuffers) s_CreatedBuffers++;
return new PooledNetworkBuffer();
}
PooledNetworkBuffer buffer = s_Buffers.Dequeue();
buffer.SetLength(0);
buffer.Position = 0;
return buffer;
}
/// <summary>
/// Puts a PooledNetworkBuffer back into the pool
/// </summary>
/// <param name="buffer">The buffer to put in the pool</param>
public static void PutBackInPool(PooledNetworkBuffer buffer)
{
if (s_Buffers.Count > k_MaxCreatedDelta)
{
// The user just created lots of buffers without returning them in between.
// Buffers are essentially byte array wrappers. This is valuable memory.
// Thus we put this buffer as a weak reference incase of another burst
// But still leave it to GC
if (NetworkLog.CurrentLogLevel <= LogLevel.Developer)
{
NetworkLog.LogInfo($"Putting {nameof(PooledNetworkBuffer)} into overflow pool. Did you forget to dispose?");
}
s_OverflowBuffers.Enqueue(new WeakReference(buffer));
}
else
{
s_Buffers.Enqueue(buffer);
}
}
}
}