Newer
Older
PrismSoftware / ECTrainer2 / RingBuffer.h
#pragma once

#include <mutex>


template<class T>
class RingBuffer
{
	T* _data;
	std::mutex* _mtxData;
	std::mutex _mtxIndex;
	int _size;
	int _write;
	int _read;
	bool _update;
public:
	RingBuffer(int size);
	~RingBuffer();
	void Put(T value);
	T Get(int past = 0);
	bool IsNew() { return _update; };
};

template<class T>
RingBuffer<T>::RingBuffer(int size)
	: _data(NULL)
	, _write(0)
	, _read(0)
	, _update(false)
{
	_size = size;
	_data = new T[_size];
	_mtxData = new std::mutex[_size];
}

template<class T>
RingBuffer<T>::~RingBuffer() {
	delete[] _data;
	delete[] _mtxData;
}

template<class T>
void RingBuffer<T>::Put(T value) {
	int write = _write;
	_mtxData[write].lock();
	_data[write] = value;
	_mtxData[write].unlock();

	_mtxIndex.lock();
	_read = write;
	_write = (write + 1) % _size;
	_update = true;
	_mtxIndex.unlock();
}

template<class T>
T RingBuffer<T>::Get(int past) {
	int read = (_read + _size - past) % _size;
	_mtxData[read].lock();
	T value = _data[read];
	_mtxData[read].unlock();

	_mtxIndex.lock();
	_update = false;
	_mtxIndex.unlock();

	return value;
}