QtPdCom  1.5.2
ValueRing.h
Go to the documentation of this file.
1/*****************************************************************************
2 *
3 * Copyright (C) 2009 - 2012 Florian Pose <fp@igh-essen.com>
4 *
5 * This file is part of the QtPdCom library.
6 *
7 * The QtPdCom library is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation, either version 3 of the License,
10 * or (at your option) any later version.
11 *
12 * The QtPdCom library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with the QtPdCom Library. If not, see
19 * <http://www.gnu.org/licenses/>.
20 *
21 ****************************************************************************/
22
23#ifndef PD_VALUERING_H
24#define PD_VALUERING_H
25
26#include <QList>
27#include <QPair>
28
29#include <chrono>
30
31#define VALUERING_DEBUG 0
32
33#if VALUERING_DEBUG
34#include <QDebug>
35#endif
36
37namespace QtPdCom {
38
39/****************************************************************************/
40
43template <class T> class ValueRing
44{
45 public:
46 ValueRing();
47 ~ValueRing();
48
49 void setRange(std::chrono::nanoseconds);
50 std::chrono::nanoseconds getRange() const { return range; }
51
52 void append(std::chrono::nanoseconds time, const T &value);
53 void copyUntil(const ValueRing<T> &, std::chrono::nanoseconds);
54 void clear();
55
56 unsigned int getLength() const;
57
58 typedef QPair<std::chrono::nanoseconds, T> TimeValuePair;
59 TimeValuePair &operator[](unsigned int index);
60 const TimeValuePair &operator[](unsigned int index) const;
61 TimeValuePair &operator[](int index);
62 const TimeValuePair &operator[](int index) const;
63
64 private:
65 QList<TimeValuePair> ring;
66 unsigned int offset;
67 unsigned int length;
68 std::chrono::nanoseconds range;
71
72 void removeDeprecated();
73 void reshape();
74};
75
76/****************************************************************************/
77
80template <class T> ValueRing<T>::ValueRing():
81 offset(0),
82 length(0)
83{}
84
85/****************************************************************************/
86
89template <class T> ValueRing<T>::~ValueRing()
90{}
91
92/****************************************************************************/
93
96template <class T> void ValueRing<T>::setRange(std::chrono::nanoseconds r)
97{
98 range = r;
100}
101
102/****************************************************************************/
103
106template <class T>
107void ValueRing<T>::append(std::chrono::nanoseconds time, const T &value)
108{
109 TimeValuePair newPair(time, value);
110
111 if ((int) length < ring.size()) {
112 unsigned int o = (offset + length) % ring.size();
113 ring[o] = newPair;
114 }
115 else {
116#if VALUERING_DEBUG
117 qDebug() << ring.size() << "reached.";
118#endif
119 // ring is full
120 if (offset) {
121 reshape();
122 }
123 ring.append(newPair);
124 }
125
126 length++;
128}
129
130/****************************************************************************/
131
134template <class T> void ValueRing<T>::copyUntil(
135 const ValueRing<T> &other,
136 std::chrono::nanoseconds time)
137{
138 clear();
139
140 for (unsigned int i = 0; i < other.length; i++) {
141 TimeValuePair p = other[i];
142 if (p.first > time) {
143 break;
144 }
145
146 ring.append(p);
147 length++;
148 }
149}
150
151/****************************************************************************/
152
155template <class T> void ValueRing<T>::clear()
156{
157 ring.clear();
158 offset = 0;
159 length = 0;
160}
161
162/****************************************************************************/
163
167template <class T> inline unsigned int ValueRing<T>::getLength() const
168{
169 return length;
170}
171
172/****************************************************************************/
173
176template <class T> inline typename ValueRing<T>::TimeValuePair &
177ValueRing<T>::operator[](unsigned int index)
178{
179 return ring[(offset + index) % ring.size()];
180}
181
182/****************************************************************************/
183
186template <class T> inline const typename ValueRing<T>::TimeValuePair &
187ValueRing<T>::operator[](unsigned int index) const
188{
189 return ring.at((offset + index) % ring.size());
190}
191
192/****************************************************************************/
193
198template <class T> inline typename ValueRing<T>::TimeValuePair &
200{
201 if (index >= 0) {
202 return ring[(offset + index) % ring.size()];
203 }
204 else {
205 return ring[(offset + length + index) % ring.size()];
206 }
207}
208
209/****************************************************************************/
210
215template <class T> inline const typename ValueRing<T>::TimeValuePair &
217{
218 if (index >= 0) {
219 return ring.at((offset + index) % ring.size());
220 }
221 else {
222 return ring.at((offset + length + index) % ring.size());
223 }
224}
225
226/****************************************************************************/
227
230template <class T> void ValueRing<T>::removeDeprecated()
231{
232 if (length) {
233 std::chrono::nanoseconds depTime((*this)[length - 1].first - range);
234 while (length) {
235 if (ring[offset].first < depTime) {
236 offset = (offset + 1) % ring.size();
237 length--;
238 }
239 else {
240 break;
241 }
242 }
243 }
244}
245
246/****************************************************************************/
247
250template <class T> void ValueRing<T>::reshape()
251{
252 QList<TimeValuePair> newRing;
253 unsigned int i;
254
255#if VALUERING_DEBUG
256 qDebug() << "reshaping" << length << "values";
257#endif
258
259 for (i = 0; i < length; i++) {
260 newRing.append((*this)[i]);
261 }
262 ring = newRing;
263 offset = 0;
264}
265
266/****************************************************************************/
267
268} // namespace QtPdCom
269
270#endif
Time/Value ring buffer.
Definition ValueRing.h:44
void copyUntil(const ValueRing< T > &, std::chrono::nanoseconds)
Copies data from another ring, up to a specific time.
Definition ValueRing.h:134
QPair< std::chrono::nanoseconds, T > TimeValuePair
Definition ValueRing.h:58
QList< TimeValuePair > ring
Time/Value ring.
Definition ValueRing.h:65
void removeDeprecated()
Remove values that exceed the time range.
Definition ValueRing.h:230
TimeValuePair & operator[](unsigned int index)
Index operator.
Definition ValueRing.h:177
void reshape()
Reshape the ring to move the offset to zero.
Definition ValueRing.h:250
~ValueRing()
Destructor.
Definition ValueRing.h:89
unsigned int getLength() const
Definition ValueRing.h:167
void clear()
Clears the ring.
Definition ValueRing.h:155
unsigned int offset
Ring offset.
Definition ValueRing.h:66
void setRange(std::chrono::nanoseconds)
Sets the range.
Definition ValueRing.h:96
unsigned int length
Number of valid elements at offset.
Definition ValueRing.h:67
ValueRing()
Constructor.
Definition ValueRing.h:80
void append(std::chrono::nanoseconds time, const T &value)
Appends a value to the ring.
Definition ValueRing.h:107
std::chrono::nanoseconds getRange() const
Definition ValueRing.h:50
std::chrono::nanoseconds range
Time range covered by the ring.
Definition ValueRing.h:68
Definition BroadcastModel.h:32