#if !USE_CUSTOM_VSTRING_SCRIPT
namespace Giant.Common
{
    using System;
    using System.Runtime.InteropServices;

    /// <summary>
    /// Ring buffer for temporary
    /// </summary>
    public sealed class NativeRingBuffer
    {
        /// <summary>
        /// 3MB
        /// </summary>
        private const int kTotalSize = 3 * 1024 * 1024;



        /// <summary>
        /// 内存块地址
        /// </summary>
        private IntPtr m_Buffer;



        /// <summary>
        /// 尾部指针
        /// </summary>
        private Int64 m_Tail;



        /// <summary>
        /// 头部指针
        /// </summary>
        private Int64 m_Start;



        /// <summary>
        /// 当前位置
        /// </summary>
        private Int64 m_Current;



        private static NativeRingBuffer m_Instance;
        public static NativeRingBuffer Instance
        {
            get
            {
                if (null == m_Instance)
                    InitBuffer();
                return m_Instance;
            }
        }



        private static void InitBuffer()
        {
            if (m_Instance == null)
            {
                m_Instance = new NativeRingBuffer();
                m_Instance.Init();
            }
        }



        private NativeRingBuffer() { }



        ~NativeRingBuffer()
        {
            Free();
        }



        /// <summary>
        /// Init memory
        /// </summary>
        private void Init()
        {
            m_Buffer  = Marshal.AllocHGlobal(kTotalSize);
            m_Start   = m_Buffer.ToInt64();
            m_Tail    = m_Start + kTotalSize;
            m_Current = m_Start;
        }



        /// <summary>
        /// Free memory
        /// </summary>
        private void Free()
        {
            if(IntPtr.Zero != m_Buffer)
            {
                Marshal.FreeHGlobal(m_Buffer);
                m_Buffer = IntPtr.Zero;
            }
        }



        /// <summary>
        /// Gets memory
        /// </summary>
        public Int64 AllocMemory(int _Size)
        {
            if (_Size > kTotalSize || _Size < 0)
                throw new System.ArgumentException("AllocMemory failed, _Size is large than 3MB or negative");
            Int64 tStart = m_Current;
            m_Current += _Size;
            //如果超出范围，从头开始分配
            if (m_Current >= m_Tail)
            {
                tStart = m_Start;
                m_Current = m_Start + _Size;
            }
            return tStart;      
        }  
    }
}
#endif