00001
00020 #ifndef RingBuffer_h
00021 #define RingBuffer_h
00022
00023 #include <rtm/RTC.h>
00024
00025 #include <vector>
00026 #include <algorithm>
00027
00028 #include <rtm/BufferBase.h>
00029
00044 namespace RTC
00045 {
00081 template <class DataType>
00082 class RingBuffer
00083 : public BufferBase<DataType>
00084 {
00085 public:
00110 RingBuffer(long int length)
00111 : m_length(length < 2 ? 2 : length),
00112 m_oldPtr(0),
00113 m_newPtr(length < 2 ? 1 : length - 1)
00114 {
00115 m_buffer.resize(m_length);
00116 }
00117
00133 virtual ~RingBuffer(){};
00134
00156 void init(DataType& data)
00157 {
00158 for (long int i = 0; i < m_length; ++i)
00159 {
00160 put(data);
00161 }
00162 }
00163
00184 virtual long int length() const
00185 {
00186 return m_length;
00187 }
00188
00212 virtual bool write(const DataType& value)
00213 {
00214 put(value);
00215 return true;
00216 }
00217
00241 virtual bool read(DataType& value)
00242 {
00243 value = get();
00244 return true;
00245 }
00246
00266 virtual bool isFull() const
00267 {
00268 return false;
00269 }
00270
00297 virtual bool isEmpty() const
00298 {
00299 return !(this->isNew());
00300 }
00301
00325 bool isNew() const
00326 {
00327 return m_buffer[m_newPtr].isNew();
00328 }
00329
00330 protected:
00358 virtual void put(const DataType& data)
00359 {
00360 m_buffer[m_oldPtr].write(data);
00361
00362 m_newPtr = m_oldPtr;
00363 m_oldPtr = (++m_oldPtr) % m_length;
00364 }
00365
00385 virtual const DataType& get()
00386 {
00387 return m_buffer[m_newPtr].read();
00388 }
00389
00409 virtual DataType& getRef()
00410 {
00411 return m_buffer[m_newPtr].data;
00412 }
00413
00414 private:
00415 long int m_length;
00416 long int m_oldPtr;
00417 long int m_newPtr;
00418
00441 template <class D>
00442 class Data
00443 {
00444 public:
00445 Data() : data(), is_new(false){;}
00446 inline Data& operator=(const D& other)
00447 {
00448 this->data = other;
00449 this->is_new = true;
00450 return *this;
00451 }
00452 inline void write(const D& other)
00453 {
00454 this->is_new = true;
00455 this->data = other;
00456 }
00457 inline D& read()
00458 {
00459 this->is_new = false;
00460 return this->data;
00461 }
00462 inline bool isNew() const
00463 {
00464 return is_new;
00465 }
00466 D data;
00467 bool is_new;
00468 };
00469
00470 std::vector<Data<DataType> > m_buffer;
00471
00472 };
00473 };
00474
00475 #endif // RingBuffer_h