GestureRecognitionToolkit  Version: 0.2.5
The Gesture Recognition Toolkit (GRT) is a cross-platform, open-source, c++ machine learning library for real-time gesture recognition.
CircularBuffer.h
Go to the documentation of this file.
1 
7 /*
8  GRT MIT License
9  Copyright (c) <2012> <Nicholas Gillian, Media Lab, MIT>
10 
11  Permission is hereby granted, free of charge, to any person obtaining a copy of this software
12  and associated documentation files (the "Software"), to deal in the Software without restriction,
13  including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
15  subject to the following conditions:
16 
17  The above copyright notice and this permission notice shall be included in all copies or substantial
18  portions of the Software.
19 
20  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
21  LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  */
26 
27 #ifndef GRT_CIRCULAR_BUFFER_HEADER
28 #define GRT_CIRCULAR_BUFFER_HEADER
29 #include <iostream>
30 #include <vector>
31 #include "GRTTypedefs.h"
32 #include "ErrorLog.h"
33 
34 GRT_BEGIN_NAMESPACE
35 
44 template <class T>
46  public:
47 
52  errorLog.setKey("[ERROR CircularBuffer]");
53  bufferSize = 0;
54  numValuesInBuffer = 0;
55  readPtr = 0;
56  writePtr = 0;
57  bufferInit = false;
58  }
59 
66  errorLog.setKey("[ERROR CircularBuffer]");
67  this->bufferSize = 0;
68  this->numValuesInBuffer = 0;
69  this->readPtr = 0;
70  this->writePtr = 0;
71  this->bufferInit = false;
72 
73  if( rhs.bufferInit ){
74  this->bufferInit = rhs.bufferInit;
75  this->bufferSize = rhs.bufferSize;
76  this->numValuesInBuffer = rhs.numValuesInBuffer;
77  this->buffer.resize( rhs.bufferSize );
78  for(unsigned int i=0; i<rhs.bufferSize; i++){
79  this->buffer[i] = rhs.buffer[ i ];
80  }
81  this->readPtr = rhs.readPtr;
82  this->writePtr = rhs.writePtr;
83  }
84  }
85 
91  CircularBuffer(unsigned int bufferSize){
92  errorLog.setKey("[ERROR CircularBuffer]");
93  bufferInit = false;
94  resize(bufferSize);
95  }
96 
100  virtual ~CircularBuffer(){
101  if( bufferInit ){
102  clear();
103  }
104  }
105 
113  if( this != &rhs ){
114  this->clear();
115 
116  if( rhs.bufferInit ){
117  this->bufferInit = rhs.bufferInit;
118  this->bufferSize = rhs.bufferSize;
119  this->numValuesInBuffer = rhs.numValuesInBuffer;
120  this->buffer.resize( rhs.bufferSize );
121  for(unsigned int i=0; i<rhs.bufferSize; i++){
122  this->buffer[i] = rhs.buffer[ i ];
123  }
124  this->readPtr = rhs.readPtr;
125  this->writePtr = rhs.writePtr;
126  }
127  }
128  return *this;
129  }
130 
137  inline T& operator[](const unsigned int &index){
138  return buffer[ (readPtr + index) % bufferSize ];
139  }
140 
147  inline const T& operator[](const unsigned int &index) const{
148  return buffer[ (readPtr + index) % bufferSize ];
149  }
150 
157  inline T& operator()(const unsigned int &index){
158  return buffer[ index ];
159  }
160 
167  inline const T& operator()(const unsigned int &index) const{
168  return buffer[ index ];
169  }
170 
177  bool resize(const unsigned int newBufferSize){
178  return resize(newBufferSize,T());
179  }
180 
188  bool resize(const unsigned int newBufferSize,const T &defaultValue){
189 
190  //Cleanup the old memory
191  clear();
192 
193  if( newBufferSize == 0 ) return false;
194 
195  //Setup the memory for the new buffer
196  bufferSize = newBufferSize;
197  buffer.resize(bufferSize,defaultValue);
198  numValuesInBuffer = 0;
199  readPtr = 0;
200  writePtr = 0;
201 
202  //Flag that the filter has been initialised
203  bufferInit = true;
204 
205  return true;
206  }
207 
214  bool push_back(const T &value){
215 
216  if( !bufferInit ){
217  errorLog << "Can't push_back value to circular buffer as the buffer has not been initialized!" << std::endl;
218  return false;
219  }
220 
221  //Add the value to the buffer
222  buffer[ writePtr ] = value;
223 
224  //Update the write pointer
225  writePtr++;
226  writePtr = writePtr % bufferSize;
227 
228  //Check if the buffer is full
229  if( ++numValuesInBuffer > bufferSize ){
230  numValuesInBuffer = bufferSize;
231 
232  //Only update the read pointer if the buffer has been filled
233  readPtr++;
234  readPtr = readPtr % bufferSize;
235  }
236 
237  return true;
238  }
239 
246  bool setAllValues(const T &value){
247  if( !bufferInit ){
248  return false;
249  }
250 
251  for(unsigned int i=0; i<bufferSize; i++){
252  buffer[i] = value;
253  }
254 
255  return true;
256  }
257 
262  bool reset(){
263  numValuesInBuffer = 0;
264  readPtr = 0;
265  writePtr = 0;
266  return true;
267  }
268 
272  void clear(){
273  numValuesInBuffer = 0;
274  readPtr = 0;
275  writePtr = 0;
276  buffer.clear();
277  bufferInit = false;
278  }
279 
286  GRT_DEPRECATED_MSG("Use getData() instead!", std::vector< T > getDataAsVector() const );
287 
295  Vector< T > getData( const bool rawBuffer = false ) const{
296  if( bufferInit ){
297 
298  if( rawBuffer ){
299  return buffer; //Here we return the entire data buffer
300  }else{ //Here we return only valid elements and in order from oldest to newest
301  Vector< T > data( numValuesInBuffer );
302  for(unsigned int i=0; i<numValuesInBuffer; i++){
303  data[i] = (*this)[i]; //Gets the ordered element
304  }
305  return data;
306  }
307  }
308  return Vector< T >();
309  }
310 
316  bool getInit() const { return bufferInit; }
317 
323  bool getBufferFilled() const { return bufferInit ? numValuesInBuffer==bufferSize : false; }
324 
330  unsigned int getSize() const { return bufferInit ? bufferSize : 0; }
331 
337  unsigned int getNumValuesInBuffer() const { return bufferInit ? numValuesInBuffer : 0; }
338 
344  unsigned int getReadPointerPosition() const { return bufferInit ? readPtr : 0; }
345 
351  unsigned int getWritePointerPosition() const { return bufferInit ? writePtr : 0; }
352 
358  T getBack() const {
359  if( !bufferInit ) return T();
360  return buffer[ (readPtr + numValuesInBuffer - 1) % bufferSize ];
361  }
362 
363 protected:
364  bool bufferInit;
365  unsigned int bufferSize;
366  unsigned int numValuesInBuffer;
367  unsigned int readPtr;
368  unsigned int writePtr;
369  Vector< T > buffer;
370 
371  ErrorLog errorLog;
372 };
373 
374 //Deprecated function
375 template< class T > std::vector< T > CircularBuffer< T >::getDataAsVector() const{ return getData(); };
376 
377 GRT_END_NAMESPACE
378 
379 #endif //GRT_CIRCULAR_BUFFER_HEADER
bool push_back(const T &value)
const T & operator[](const unsigned int &index) const
bool getBufferFilled() const
CircularBuffer & operator=(const CircularBuffer &rhs)
virtual bool setKey(const std::string &key)
sets the key that gets written at the start of each message, this will be written in the format &#39;key ...
Definition: Log.h:166
T getBack() const
CircularBuffer(const CircularBuffer &rhs)
GRT_DEPRECATED_MSG("Use getData() instead!", std::vector< T > getDataAsVector() const )
unsigned int getWritePointerPosition() const
bool getInit() const
virtual ~CircularBuffer()
T & operator[](const unsigned int &index)
unsigned int getNumValuesInBuffer() const
unsigned int getReadPointerPosition() const
CircularBuffer(unsigned int bufferSize)
bool resize(const unsigned int newBufferSize, const T &defaultValue)
const T & operator()(const unsigned int &index) const
bool setAllValues(const T &value)
Definition: Vector.h:41
T & operator()(const unsigned int &index)
Vector< T > getData(const bool rawBuffer=false) const
unsigned int getSize() const
bool resize(const unsigned int newBufferSize)