今天在做资源多线程异步加载的时候,在引擎里加了一个精简的类kfifo的环形缓冲区实现。环形缓冲的特性就是保证先入先出的时序性的同时,数据不需要做整体的搬移,其实就是一个环形队列。在网络编程里面应用的比较多,boost库里也有对应的数据结构实现boost::circular_buffer。相比之前在做协议收发数据解析的环形缓冲来说,在处理资源异步加载的时候,资源加载线程是引擎层在处理,只需一个简单的时序控制队列实现即可。

这里要求缓冲区长度必须是2的幂,方便通过位与来计算索引,规避求余。

template<class T>

class CircularBuffer
{
public:
	CircularBuffer() :_elems(0)
	{}
	inline void Init(int size)
	{
		_size = size;
		_start = 0;
		_end = 0;
		_elems = (T*)calloc(size, sizeof(T));
	}
	~CircularBuffer()
	{
		if (_elems)
			free(_elems);
	}

	inline int IsFull() 
	{
		return _end == (_start ^ _size);
	}

	inline int IsEmpty() {
		return _end == _start;
	}

	inline int Incr(int p) 
	{
		return (p + 1)&(2 * _size - 1);
	}

	inline void Write(const T *elem) 
	{
		_elems[_end&(_size - 1)] = *elem;
		if (IsFull())
			_start = Incr(_start);
		_end = Incr(_end);
	}

	inline void Read(T *elem)
	{
		if(!IsEmpty())
		{
			*elem = _elems[_start&(_size - 1)];
			_start = Incr(_start);
		}
	}

private:
	int _size;
	int _start;
	int _end;
	T *_elems;
} ;