using FishNet.Managing;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace FishNet.Serializing
{
///
/// Reader which is reused to save on garbage collection and performance.
///
public sealed class PooledReader : Reader, IDisposable
{
internal PooledReader(byte[] bytes, NetworkManager networkManager, Reader.DataSource source = Reader.DataSource.Unset) : base(bytes, networkManager, null, source) { }
internal PooledReader(ArraySegment segment, NetworkManager networkManager, Reader.DataSource source = Reader.DataSource.Unset) : base(segment, networkManager, null, source) { }
public void Store() => ReaderPool.Store(this);
[Obsolete("Use Store().")] //Remove on 2024/01/01.
public void Dispose() => this.Store();
}
///
/// Collection of PooledReader. Stores and gets PooledReader.
///
public static class ReaderPool
{
#region Private.
///
/// Pool of readers.
///
private static readonly Stack _pool = new Stack();
#endregion
///
/// Get the next reader in the pool
/// If pool is empty, creates a new Reader
///
[Obsolete("Use Retrieve(byte[], NetworkManager, DataSource)")] //Remove on 2024/01/01
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static PooledReader GetReader(byte[] bytes, NetworkManager networkManager, Reader.DataSource source = Reader.DataSource.Unset) => Retrieve(bytes, networkManager, source);
///
/// Get the next reader in the pool
/// If pool is empty, creates a new Reader
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static PooledReader Retrieve(byte[] bytes, NetworkManager networkManager, Reader.DataSource source = Reader.DataSource.Unset)
{
return Retrieve(new ArraySegment(bytes), networkManager, source);
}
///
/// Get the next reader in the pool or creates a new one if none are available.
///
[Obsolete("Use Retrieve(ArraySegment, NetworkManager, DataSource)")] //Remove on 2024/01/01
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static PooledReader GetReader(ArraySegment segment, NetworkManager networkManager, Reader.DataSource source = Reader.DataSource.Unset) => Retrieve(segment, networkManager, source);
///
/// Get the next reader in the pool or creates a new one if none are available.
///
public static PooledReader Retrieve(ArraySegment segment, NetworkManager networkManager, Reader.DataSource source = Reader.DataSource.Unset)
{
PooledReader result;
if (_pool.Count > 0)
{
result = _pool.Pop();
result.Initialize(segment, networkManager, source);
}
else
{
result = new PooledReader(segment, networkManager, source);
}
return result;
}
///
/// Puts reader back into pool
/// When pool is full, the extra reader is left for the GC
///
[Obsolete("Use Store(PooledReader)")] //Remove on 2024/01/01
public static void Recycle(PooledReader reader) => Store(reader);
///
/// Puts reader back into pool
/// When pool is full, the extra reader is left for the GC
///
public static void Store(PooledReader reader)
{
_pool.Push(reader);
}
}
}