public ObjectUsage <T> Get(UsageType usage)
        {
            switch (usage)
            {
            case UsageType.Write:
                lock (buffers)
                {
                    while (buffers[write]?.Usage == UsageType.Read || write == lastWrite)
                    {
                        write = (write + 1) % 3;
                    }
                }

                if (buffers[write] == null)
                {
                    buffers[write] = new ObjectUsage <T>
                    {
                        Finish = finishDelegate,
                        Usage  = UsageType.Write,
                        Index  = write,
                    };
                }
                else
                {
                    buffers[write].Usage = UsageType.Write;
                }

                buffers[write].FrameId = Interlocked.Increment(ref currentFrame);
                return(buffers[write]);

            case UsageType.Read:
                if (lastWrite < 0)
                {
                    return(null);
                }

                lock (buffers)
                {
                    read = lastWrite;
                    buffers[read].Usage = UsageType.Read;
                }

                return(buffers[read]);
            }

            return(null);
        }
        private void finish(ObjectUsage <T> obj, UsageType type)
        {
            switch (type)
            {
            case UsageType.Read:
                lock (buffers)
                    buffers[read].Usage = UsageType.None;
                break;

            case UsageType.Write:
                lock (buffers)
                {
                    buffers[write].Usage = UsageType.None;
                    lastWrite            = write;
                }
                break;
            }
        }