v2.0.0
Loading...
Searching...
No Matches
circularbuffer.h
Go to the documentation of this file.
1//=============================================================================================================
30
31#ifndef CIRCULARBUFFER_H
32#define CIRCULARBUFFER_H
33
34//=============================================================================================================
35// INCLUDES
36//=============================================================================================================
37
38#include "../utils_global.h"
39
40//=============================================================================================================
41// QT INCLUDES
42//=============================================================================================================
43
44#include <QPair>
45#include <QSemaphore>
46#include <QSharedPointer>
47
48#include <memory>
49
50//=============================================================================================================
51// EIGEN INCLUDES
52//=============================================================================================================
53
54#include <Eigen/Core>
55
56//=============================================================================================================
57// DEFINE NAMESPACE UTILSLIB
58//=============================================================================================================
59
60namespace UTILSLIB
61{
62
63//=============================================================================================================
71template<typename T>
73{
74public:
75 typedef QSharedPointer<CircularBuffer> SPtr;
76 typedef QSharedPointer<const CircularBuffer> ConstSPtr;
77
78 //=========================================================================================================
84 explicit CircularBuffer(unsigned int uiMaxNumElements);
85
86 //=========================================================================================================
91
92 //=========================================================================================================
101 inline bool push(const T* pArray, unsigned int size);
102
103 //=========================================================================================================
111 inline bool push(const T& newElement);
112
113 //=========================================================================================================
121 inline bool pop(T& element);
122
123 //=========================================================================================================
127 void clear();
128
129 //=========================================================================================================
135 inline void pause(bool);
136
137 //=========================================================================================================
144
145 //=========================================================================================================
152
153private:
154 //=========================================================================================================
161 inline unsigned int mapIndex(int& index);
162 unsigned int m_uiMaxNumElements;
163 std::unique_ptr<T[]> m_pBuffer;
164 int m_iCurrentReadIndex;
165 int m_iCurrentWriteIndex;
166 std::unique_ptr<QSemaphore> m_pFreeElements;
167 std::unique_ptr<QSemaphore> m_pUsedElements;
168 int m_iTimeout;
169
170 bool m_bPause;
171};
172
173//=============================================================================================================
174// DEFINE MEMBER METHODS
175//=============================================================================================================
176
177template<typename T>
178CircularBuffer<T>::CircularBuffer(unsigned int uiMaxNumElements)
179: m_uiMaxNumElements(uiMaxNumElements)
180, m_pBuffer(std::make_unique<T[]>(m_uiMaxNumElements))
181, m_iCurrentReadIndex(-1)
182, m_iCurrentWriteIndex(-1)
183, m_pFreeElements(std::make_unique<QSemaphore>(m_uiMaxNumElements))
184, m_pUsedElements(std::make_unique<QSemaphore>(0))
185, m_iTimeout(1000)
186, m_bPause(false)
187{
188}
189
190//=============================================================================================================
191
192template<typename T>
194
195//=============================================================================================================
196
197template<typename T>
198inline bool CircularBuffer<T>::push(const T* pArray, unsigned int size)
199{
200 if (m_bPause) {
201 return false;
202 }
203
204 if (m_pFreeElements->tryAcquire(size, m_iTimeout)) {
205 for (unsigned int i = 0; i < size; ++i) {
206 m_pBuffer[mapIndex(m_iCurrentWriteIndex)] = pArray[i];
207 }
208 const QSemaphoreReleaser releaser(m_pUsedElements.get(), size);
209 } else {
210 return false;
211 }
212
213 return true;
214}
215
216//=============================================================================================================
217
218template<typename T>
219inline bool CircularBuffer<T>::push(const T& newElement)
220{
221 if (m_bPause) {
222 return false;
223 }
224
225 if (m_pFreeElements->tryAcquire(1, m_iTimeout)) {
226 m_pBuffer[mapIndex(m_iCurrentWriteIndex)] = newElement;
227 const QSemaphoreReleaser releaser(m_pUsedElements.get(), 1);
228 } else {
229 return false;
230 }
231
232 return true;
233}
234
235//=============================================================================================================
236
237template<typename T>
238inline bool CircularBuffer<T>::pop(T& element)
239{
240 if (m_bPause) {
241 return false;
242 }
243
244 if (m_pUsedElements->tryAcquire(1, m_iTimeout)) {
245 element = m_pBuffer[mapIndex(m_iCurrentReadIndex)];
246 const QSemaphoreReleaser releaser(m_pFreeElements.get(), 1);
247 } else {
248 return false;
249 }
250
251 return true;
252}
253
254//=============================================================================================================
255
256template<typename T>
257inline unsigned int CircularBuffer<T>::mapIndex(int& index)
258{
259 int aux = index;
260 return index = ++aux % m_uiMaxNumElements;
261}
262
263//=============================================================================================================
264
265template<typename T>
267{
268 m_pFreeElements = std::make_unique<QSemaphore>(m_uiMaxNumElements);
269 m_pUsedElements = std::make_unique<QSemaphore>(0);
270
271 m_iCurrentReadIndex = -1;
272 m_iCurrentWriteIndex = -1;
273}
274
275//=============================================================================================================
276
277template<typename T>
278inline void CircularBuffer<T>::pause(bool bPause)
279{
280 m_bPause = bPause;
281}
282
283//=============================================================================================================
284
285template<typename T>
287{
288 return m_pUsedElements->available();
289}
290
291//=============================================================================================================
292
293template<typename T>
295{
296 return m_pFreeElements->available();
297}
298
299//=============================================================================================================
300// TYPEDEF
301//=============================================================================================================
302
311
312} // NAMESPACE
313
314#endif // CIRCULARBUFFER_H
Public umbrella header for UTILSLIB exposing the UTILSSHARED_EXPORT macro and build-info accessors.
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
CircularBuffer< QPair< int, int > > CircularBuffer_pair_int_int
CircularBuffer< QPair< double, double > > CircularBuffer_pair_double_double
CircularBuffer< short > CircularBuffer_short
CircularBuffer< double > CircularBuffer_double
CircularBuffer< Eigen::MatrixXd > CircularBuffer_Matrix_double
CircularBuffer< char > CircularBuffer_char
CircularBuffer< Eigen::MatrixXf > CircularBuffer_Matrix_float
CircularBuffer< int > CircularBuffer_int
Thread-safe lock-free circular (ring) buffer for producer-consumer data exchange between threads.
CircularBuffer(unsigned int uiMaxNumElements)
QSharedPointer< const CircularBuffer > ConstSPtr
bool push(const T *pArray, unsigned int size)
QSharedPointer< CircularBuffer > SPtr
bool push(const T &newElement)