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); } } }