MNE-CPP  beta 1.0
circularbuffer.h
Go to the documentation of this file.
1 //=============================================================================================================
36 #ifndef CIRCULARBUFFER_H
37 #define CIRCULARBUFFER_H
38 
39 
40 //*************************************************************************************************************
41 //=============================================================================================================
42 // INCLUDES
43 //=============================================================================================================
44 
45 #include "generics_global.h"
46 
47 
48 //*************************************************************************************************************
49 //=============================================================================================================
50 // QT INCLUDES
51 //=============================================================================================================
52 
53 #include <QPair>
54 #include <QSemaphore>
55 #include <QSharedPointer>
56 
57 
58 //*************************************************************************************************************
59 //=============================================================================================================
60 // DEFINE NAMESPACE IOBuffer
61 //=============================================================================================================
62 
63 namespace IOBuffer
64 {
65 
66 
67 //*************************************************************************************************************
68 //=============================================================================================================
69 // USED NAMESPACES
70 //=============================================================================================================
71 
72 
73 //=============================================================================================================
79 template<typename _Tp>
81 {
82 public:
83  typedef QSharedPointer<CircularBuffer> SPtr;
84  typedef QSharedPointer<const CircularBuffer> ConstSPtr;
86  //=========================================================================================================
92  explicit CircularBuffer(unsigned int uiMaxNumElements);
93 
94  //=========================================================================================================
99 
100  //=========================================================================================================
107  inline void push(const _Tp* pArray, unsigned int size);
108 
109  //=========================================================================================================
115  inline void push(const _Tp& newElement);
116 
117  //=========================================================================================================
123  inline _Tp pop();
124 
125  //=========================================================================================================
129  void clear();
130 
131  //=========================================================================================================
135  inline void pause(bool);
136 
137  //=========================================================================================================
142  inline bool releaseFromPop();
143 
144  //=========================================================================================================
149  inline bool releaseFromPush();
150 
151 private:
152  //=========================================================================================================
159  inline unsigned int mapIndex(int& index);
160  unsigned int m_uiMaxNumElements;
161  _Tp* m_pBuffer;
162  int m_iCurrentReadIndex;
163  int m_iCurrentWriteIndex;
164  QSemaphore* m_pFreeElements;
165  QSemaphore* m_pUsedElements;
167  bool m_bPause;
168 };
169 
170 
171 //*************************************************************************************************************
172 //=============================================================================================================
173 // DEFINE MEMBER METHODS
174 //=============================================================================================================
175 
176 template<typename _Tp>
177 CircularBuffer<_Tp>::CircularBuffer(unsigned int uiMaxNumElements)
178 : m_uiMaxNumElements(uiMaxNumElements)
179 , m_pBuffer(new _Tp[m_uiMaxNumElements])
180 , m_iCurrentReadIndex(-1)
181 , m_iCurrentWriteIndex(-1)
182 , m_pFreeElements(new QSemaphore(m_uiMaxNumElements))
183 , m_pUsedElements(new QSemaphore(0))
184 , m_bPause(false)
185 {
186 
187 }
188 
189 
190 //*************************************************************************************************************
191 
192 template<typename _Tp>
194 {
195  delete m_pFreeElements;
196  delete m_pUsedElements;
197  delete [] m_pBuffer;
198 }
199 
200 
201 //*************************************************************************************************************
202 
203 template<typename _Tp>
204 inline void CircularBuffer<_Tp>::push(const _Tp* pArray, unsigned int size)
205 {
206  if(!m_bPause)
207  {
208  m_pFreeElements->acquire(size);
209  for(unsigned int i = 0; i < size; ++i)
210  m_pBuffer[mapIndex(m_iCurrentWriteIndex)] = pArray[i];
211  m_pUsedElements->release(size);
212  }
213 }
214 
215 
216 //*************************************************************************************************************
217 
218 template<typename _Tp>
219 inline void CircularBuffer<_Tp>::push(const _Tp& newElement)
220 {
221  m_pFreeElements->acquire();
222  m_pBuffer[mapIndex(m_iCurrentWriteIndex)] = newElement;
223  m_pUsedElements->release();
224 }
225 
226 
227 //*************************************************************************************************************
228 
229 template<typename _Tp>
231 {
232  _Tp element;
233  if(!m_bPause)
234  {
235  m_pUsedElements->acquire();
236  element = m_pBuffer[mapIndex(m_iCurrentReadIndex)];
237  m_pFreeElements->release();
238  }
239  else
240  element = 0;
241 
242  return element;
243 }
244 
245 
246 //*************************************************************************************************************
247 
248 template<typename _Tp>
249 inline unsigned int CircularBuffer<_Tp>::mapIndex(int& index)
250 {
251  int aux = index;
252  return index = ++aux % m_uiMaxNumElements;
253 }
254 
255 
256 //*************************************************************************************************************
257 
258 template<typename _Tp>
260 {
261  delete m_pFreeElements;
262  m_pFreeElements = new QSemaphore(m_uiMaxNumElements);
263  delete m_pUsedElements;
264  m_pUsedElements = new QSemaphore(0);
265 
266  m_iCurrentReadIndex = -1;
267  m_iCurrentWriteIndex = -1;
268 }
269 
270 
271 //*************************************************************************************************************
272 
273 template<typename _Tp>
274 inline void CircularBuffer<_Tp>::pause(bool bPause)
275 {
276  m_bPause = bPause;
277 }
278 
279 
280 //*************************************************************************************************************
281 
282 template<typename _Tp>
284 {
285  if((uint)m_pUsedElements->available() < 1)
286  {
287  //The last value which is to be popped from the buffer is supposed to be a zero
288  m_pBuffer[mapIndex(m_iCurrentWriteIndex)] = 0;
289 
290  //Release (create) values from m_pUsedElements so that the pop function can leave the acquire statement in the pop function
291  m_pUsedElements->release(1);
292 
293  return true;
294  }
295 
296  return false;
297 }
298 
299 
300 //*************************************************************************************************************
301 
302 template<typename _Tp>
304 {
305  if((uint)m_pFreeElements->available() < 1)
306  {
307  //The last value which is to be pushed to the buffer is supposed to be a zero
308  m_pBuffer[mapIndex(m_iCurrentWriteIndex)] = 0;
309 
310  //Release (create) value from m_pFreeElements so that the push function can leave the acquire statement in the push function
311  m_pFreeElements->release(1);
312 
313  return true;
314  }
315 
316  return false;
317 }
318 
319 
320 //*************************************************************************************************************
321 //=============================================================================================================
322 // TYPEDEF
323 //=============================================================================================================
324 
325 //ToDo Typedef -> warning visibility ignored -> dllexport/dllimport problem
326 
327 typedef GENERICSSHARED_EXPORT CircularBuffer<int> _int_CircularBuffer;
328 typedef GENERICSSHARED_EXPORT CircularBuffer<short> _short_CircularBuffer;
329 typedef GENERICSSHARED_EXPORT CircularBuffer<char> _char_CircularBuffer;
330 typedef GENERICSSHARED_EXPORT CircularBuffer<double> _double_CircularBuffer;
331 typedef GENERICSSHARED_EXPORT CircularBuffer< QPair<int, int> > _int_int_pair_CircularBuffer;
332 typedef GENERICSSHARED_EXPORT CircularBuffer< QPair<double, double> > _double_double_pair_CircularBuffer;
334 typedef GENERICSSHARED_EXPORT _double_CircularBuffer dBuffer;
335 typedef GENERICSSHARED_EXPORT _int_CircularBuffer iBuffer;
336 typedef GENERICSSHARED_EXPORT _char_CircularBuffer cBuffer;
337 typedef GENERICSSHARED_EXPORT _double_CircularBuffer MEGBuffer;
339 } // NAMESPACE
340 
341 #endif // CIRCULARBUFFER_H
QSharedPointer< CircularBuffer > SPtr
#define GENERICSSHARED_EXPORT
generics library export/import macros.
CircularBuffer(unsigned int uiMaxNumElements)
void push(const _Tp *pArray, unsigned int size)
The TEMPLATE CIRCULAR BUFFER provides a template for thread safe circular buffers.
QSharedPointer< const CircularBuffer > ConstSPtr