00001
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef RtcRingBuffer_h
00029 #define RtcRingBuffer_h
00030
00031 #include <vector>
00032 #include <iostream>
00033 #include <ace/Synch.h>
00034
00035 namespace RTM {
00036
00061 template <class T> class RingBuffer
00062 {
00063 public:
00085 RingBuffer(int length)
00086 : m_Oldest(0), m_Newest(length)
00087 {
00088 if (length > 1)
00089 {
00090 m_Length = length;
00091 }
00092 else
00093 {
00094 m_Length = 2;
00095 }
00096 m_Buffer.resize(m_Length);
00097 }
00098
00122 RingBuffer(int length, T inival)
00123 : m_Oldest(0), m_Newest(length)
00124 {
00125 if (length > 1)
00126 {
00127 m_Length = length;
00128 }
00129 else
00130 {
00131 m_Length = 2;
00132 }
00133
00134 m_Buffer.resize(m_Length);
00135
00136 for (int i = 0; i < m_Length; i++)
00137 {
00138 m_Buffer[i] = inival;
00139 }
00140 }
00141
00161 inline void put(const T& value)
00162 {
00163 m_Buffer[m_Oldest].write(value);
00164
00165 ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex);
00166 m_Newest = m_Oldest;
00167 m_Oldest = (++m_Oldest) % m_Length;
00168
00169 }
00170
00186 inline const T& get_new()
00187 {
00188 ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex);
00189
00190 return m_Buffer[m_Newest].read();
00191 }
00192
00193
00205 inline std::vector<T> get_new_rlist()
00206 {
00207 ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex);
00208
00209 std::vector<T> data;
00210 int cnt(0);
00211 for (int i(m_Newest);
00212 m_Buffer[i].is_new() && cnt < m_Length;
00213 ++cnt, --i < 0 ? (i = m_Length - 1) : 0)
00214 {
00215 data.push_back(m_Buffer[i].read());
00216 }
00217
00218 return data;
00219 }
00220
00221
00233 inline std::vector<T> get_new_list()
00234 {
00235 ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex);
00236
00237 std::vector<T> data;
00238 int len(new_data_len());
00239 data.resize(len);
00240 int npos;
00241 npos = m_Newest - (len - 1) < 0 ?
00242 m_Newest - (len - 1) + m_Length : m_Newest - (len - 1);
00243 int cnt(0);
00244 for ( ; cnt < len; ++cnt, ++npos > m_Length - 1 ? npos = 0 : 0)
00245 {
00246 data[cnt] = m_Buffer[npos].read();
00247 }
00248
00249 return data;
00250 }
00251
00263 inline int new_data_len()
00264 {
00265 ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex);
00266
00267 int cnt(0);
00268 for (int i(m_Newest);
00269 m_Buffer[i].is_new() && cnt < m_Length;
00270 ++cnt, --i < 0 ? (i = m_Length - 1) : 0)
00271 {;}
00272
00273 return cnt;
00274 }
00275
00276
00292 inline T& get_old()
00293 {
00294 ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex);
00295
00296 return m_Buffer[m_Oldest].read();
00297 }
00298
00314 virtual T& get_back(int pos)
00315 {
00316 ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex);
00317 pos = pos % m_Length;
00318
00319 return m_Buffer[(m_Length + m_Newest - pos) % m_Length].read();
00320 }
00321
00337 inline T& get_front(int pos)
00338 {
00339 ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex);
00340 pos = pos % m_Length;
00341
00342 return m_Buffer[(m_Oldest + pos) % m_Length].read();
00343 }
00344
00360 inline int buff_length()
00361 {
00362 return m_Length;
00363 }
00364
00376 inline bool is_new()
00377 {
00378 return m_Buffer[m_Newest].is_new();
00379 }
00380
00381
00382 protected:
00390 ACE_Thread_Mutex m_Mutex;
00391
00399 int m_Length;
00400
00408 template <class D> class Data
00409 {
00410 public:
00411 Data() : _data(), _is_new(false){;}
00412 inline Data& operator=(const D& other)
00413 {
00414 this->_data = other;
00415 this->_is_new = true;
00416 return *this;
00417 }
00418 inline void write(const D& other)
00419 {
00420 this->_is_new = true;
00421 this->_data = other;
00422 }
00423 inline D& read()
00424 {
00425 this->_is_new = false;
00426 return this->_data;
00427 }
00428 inline bool is_new()
00429 {
00430 return _is_new;
00431 }
00432 protected:
00433 D _data;
00434 bool _is_new;
00435 };
00436 std::vector<Data<T> > m_Buffer;
00437
00445 int m_Newest;
00446
00454 int m_Oldest;
00455 };
00456
00457 };
00458
00459
00460 #endif // RtcRingBuffer_h