⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nringbuffer.h

📁 奇迹世界公用文件源代码,研究网络游戏的朋友可以研究下
💻 H
字号:
#ifndef N_RINGBUFFER_H
#define N_RINGBUFFER_H

//------------------------------------------------------------------------------
/**
    @brief A ring buffer class.

    @author
    - RadonLabs GmbH 

    @since
    - 2005.6.30
    @remarks
    - 瘤肯 眠啊 
*/

#include <memory.h>
#include "../ProgramCommon/Define.h"
//------------------------------------------------------------------------------
template<class TYPE> class nRingBuffer
{
public:
    /// constructor 1
    nRingBuffer(int capacity);
    /// default constructor
    nRingBuffer();
    /// destructor
    ~nRingBuffer();
    /// assignment operator
    nRingBuffer<TYPE>& operator=(const nRingBuffer<TYPE>& src);
    /// initialize, only use when default constructor has been used
    void Initialize(int capacity);
    /// returns true if ringbuffer is valid
    bool IsValid() const;
    /// return true if ringbuffer is empty
    bool IsEmpty() const;
    /// return true if ringbuffer is full
    bool IsFull() const;
    /// add unitialized element to buffer
    TYPE* Add();
    /// deletes the oldest element
    void DeleteTail();
    /// return pointer to head element
    TYPE* GetHead() const;
    /// return pointer to tail element
    TYPE* GetTail() const;
    /// return pointer to next element
    TYPE* GetNext(TYPE* e) const;
    /// return pointer to previous element
    TYPE* GetPrev(TYPE* e) const;
    /// return pointer to start of ringbuffer array
    TYPE* GetStart() const;
    /// return pointer to end of ringbuffer array
    TYPE *GetEnd() const;

private:
    /// copy content
    void Copy(const nRingBuffer<TYPE>& src);
    /// delete all content
    void Delete();

    TYPE *start;                        // start of ring buffer array
    TYPE *end;                          // last element of ring buffer array
    TYPE *tail;                         // oldest valid element
    TYPE *head;                         // youngest element+1
};

//------------------------------------------------------------------------------
/**
*/
template<class TYPE>
nRingBuffer<TYPE>::nRingBuffer<TYPE>(int capacity)
{
    //_num++; // there is always 1 empty element in buffer
    this->start = new TYPE[capacity+1];
    this->end   = this->start + capacity;
    this->tail  = this->start;
    this->head  = this->start;
}

//------------------------------------------------------------------------------
/**
    NOTE: you must call Initialize() when using the default constructor!
*/
template<class TYPE>
nRingBuffer<TYPE>::nRingBuffer<TYPE>() :
    start(0),
    end(0),
    tail(0),
    head(0)
{
    // empty
}

//---------------------------------------------------------------
/**
*/
template<class TYPE>
nRingBuffer<TYPE>::~nRingBuffer<TYPE>()
{
    this->Delete();
}

//---------------------------------------------------------------
/**
*/
template<class TYPE>
void
nRingBuffer<TYPE>::Delete()
{
    if (this->start)
    {
        delete[] this->start;
    }
    start = 0;
    end = 0;
    tail = 0;
    head = 0;
}

//------------------------------------------------------------------------------
/**
*/
template<class TYPE>
void
nRingBuffer<TYPE>::Copy(const nRingBuffer<TYPE>& src)
{
    if(0 != this->start)
    {
        int capacity = src.end - src.start;
        this->start = new TYPE[capacity+1];
        this->end   = this->start + capacity;
        this->tail  = this->start;
        this->head  = this->start;

        memcpy(src.start, this->start, capacity+1);
    }
}

//------------------------------------------------------------------------------
/**
    Initialize with n elements, may only be called when
    default constructor has been used.
*/
template<class TYPE>
void
nRingBuffer<TYPE>::Initialize(int capacity)
{
    ASSERT(!this->start);
    //_num++; // there is always 1 empty element in buffer
    this->start = new TYPE[capacity+1];
    this->end   = this->start + capacity;
    this->tail  = this->start;
    this->head  = this->start;
}

//------------------------------------------------------------------------------
/**
*/
template<class TYPE>
nRingBuffer<TYPE>&
nRingBuffer<TYPE>::operator=(const nRingBuffer<TYPE>& src)
{
    this->Delete();
    this->Copy(src);
    return *this;
}

//------------------------------------------------------------------------------
/**
    Return true if ring buffer is valid.
*/
template<class TYPE>
bool
nRingBuffer<TYPE>::IsValid() const
{
    return (0 != this->start);
}

//------------------------------------------------------------------------------
/**
    Checks if ring buffer is empty

    Returns true if head and tail are in the same position otherwise
    false.
*/
template<class TYPE>
bool
nRingBuffer<TYPE>::IsEmpty() const
{
    return (this->head == this->tail);
}

//------------------------------------------------------------------------------
/**
    Checks if ring buffer is full
*/
template<class TYPE>
bool
nRingBuffer<TYPE>::IsFull() const
{
    TYPE* e = this->head;
    if (e == this->end)
    {
        e = this->start;
    }
    else
    {
        e++;
    }

    return (e == this->tail);
}

//------------------------------------------------------------------------------
/**
    Add new unitialized head element to ringbuffer.
*/
template<class TYPE>
TYPE*
nRingBuffer<TYPE>::Add()
{
    ASSERT(this->start);
    ASSERT(!this->IsFull());
    TYPE *e = this->head;
    if (this->head == this->end)
    {
        this->head = this->start;
    }
    else
    {
        this->head++;
    }
    return e;
}

//------------------------------------------------------------------------------
/**
    Delete the oldest element
*/
template<class TYPE>
void
nRingBuffer<TYPE>::DeleteTail()
{
    ASSERT(this->start);
    ASSERT(!this->IsEmpty());
    if (this->tail == this->end)
    {
        this->tail = this->start;
    } else
    {
        this->tail++;
    }
}

//------------------------------------------------------------------------------
/**
    Return head element (youngest element).
*/
template<class TYPE>
TYPE*
nRingBuffer<TYPE>::GetHead() const
{
    if (this->head == this->tail)
    {
        // empty ringbuffer
        return 0;
    }
    TYPE *e = this->head - 1;
    if (e < this->start)
    {
        e = this->end;
    }
    return e;
}

//------------------------------------------------------------------------------
/**
    Return tail element (oldest element).
*/
template<class TYPE>
TYPE*
nRingBuffer<TYPE>::GetTail() const
{
    if (this->head == this->tail)
    {
        // empty ringbuffer
        return 0;
    }
    return this->tail;
};

//------------------------------------------------------------------------------
/**
    Get next element (from tail to head).
*/
template<class TYPE>
TYPE*
nRingBuffer<TYPE>::GetNext(TYPE* e) const
{
    ASSERT(e);
    ASSERT(this->start);
    if (e == this->end)
    {
        e = this->start;
    } else
    {
        e++;
    }
    if (e == this->head)
    {
        return 0;
    } else
    {
        return e;
    }
}

//------------------------------------------------------------------------------
/**
    Get previous element (from head to tail).
*/
template<class TYPE>
TYPE*
nRingBuffer<TYPE>::GetPrev(TYPE* e) const
{
    ASSERT(e);
    if (e == tail)
    {
        return 0;
    }

    if (e == start)
    {
        return end;
    }
    else
    {
        return e-1;
    }
}

//------------------------------------------------------------------------------
/**
    Return physical start of ringbuffer array.
    Only useful for accessing the ringbuffer array elements directly.
*/
template<class TYPE>
TYPE*
nRingBuffer<TYPE>::GetStart() const
{
    return this->start;
}

//------------------------------------------------------------------------------
/**
    Return physical end of ringbuffer array.
    Only useful for accessing the ringbuffer array elements directly.
*/
template<class TYPE>
TYPE*
nRingBuffer<TYPE>::GetEnd() const
{
    return this->end;
}

//------------------------------------------------------------------------------
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -