00001
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef RingBuffer_h
00029 #define RingBuffer_h
00030
00031 #include <vector>
00032 #include <algorithm>
00033
00034 #include <rtm/BufferBase.h>
00035
00036 namespace RTC
00037 {
00038 template <class DataType>
00039 class RingBuffer
00040 : public BufferBase<DataType>
00041 {
00042 public:
00043 RingBuffer(long int length)
00044 : m_length(length < 2 ? 2 : length - 1),
00045 m_oldPtr(0),
00046 m_newPtr(length < 2 ? 2 : length - 1)
00047 {
00048 m_buffer.resize(m_length);
00049 }
00050
00062 virtual ~RingBuffer(){};
00063
00064
00065 void init(DataType& data)
00066 {
00067 for (long int i = 0; i < m_length; ++i)
00068 {
00069 put(data);
00070 }
00071 }
00072
00084 virtual long int length() const
00085 {
00086 return m_length;
00087 }
00088
00100 virtual bool write(const DataType& value)
00101 {
00102 put(value);
00103 return true;
00104 }
00105
00117 virtual bool read(DataType& value)
00118 {
00119 value = get();
00120 return true;
00121 }
00122
00134 virtual bool isFull() const
00135 {
00136 return false;
00137 }
00149 virtual bool isEmpty() const
00150 {
00151 return !(this->isNew());
00152 }
00153
00154 bool isNew() const
00155 {
00156 return m_buffer[m_newPtr].isNew();
00157 }
00158
00159 protected:
00171 virtual void put(const DataType& data)
00172 {
00173 m_buffer[m_oldPtr].write(data);
00174
00175 m_newPtr = m_oldPtr;
00176 m_oldPtr = (++m_oldPtr) % m_length;
00177 }
00178
00190 virtual const DataType& get()
00191 {
00192 return m_buffer[m_newPtr].read();
00193 }
00194
00206 virtual DataType& getRef()
00207 {
00208 return m_buffer[m_newPtr].data;
00209 }
00210
00211 private:
00212 long int m_length;
00213 long int m_oldPtr;
00214 long int m_newPtr;
00215
00223 template <class D>
00224 class Data
00225 {
00226 public:
00227 Data() : data(), is_new(false){;}
00228 inline Data& operator=(const D& other)
00229 {
00230 this->data = other;
00231 this->is_new = true;
00232 return *this;
00233 }
00234 inline void write(const D& other)
00235 {
00236 this->is_new = true;
00237 this->data = other;
00238 }
00239 inline D& read()
00240 {
00241 this->is_new = false;
00242 return this->data;
00243 }
00244 inline bool isNew() const
00245 {
00246 return is_new;
00247 }
00248 D data;
00249 bool is_new;
00250 };
00251
00252 std::vector<Data<DataType> > m_buffer;
00253
00254 };
00255 };
00256
00257 #endif // RingBuffer_h