PdQmlWidgets  2.0.0
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 PdQmlWidgets library.
6  *
7  * The PdQmlWidgets 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 PdQmlWidgets 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 PdQmlWidgets 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 <pdcom5.h>
30 
31 #define VALUERING_DEBUG 0
32 
33 #if VALUERING_DEBUG
34 #include <QDebug>
35 #endif
36 
37 namespace PdQmlWidgets {
38 
39 /****************************************************************************/
40 
43 template <class T>
44 class ValueRing
45 {
46  public:
47  ValueRing();
48  ~ValueRing();
49 
50  void setRange(std::chrono::nanoseconds);
51  std::chrono::nanoseconds getRange() const { return range; }
52 
53  void append(std::chrono::nanoseconds time, const T &value);
54  void copyUntil(const ValueRing<T> &, std::chrono::nanoseconds);
55  void clear();
56 
57  unsigned int getLength() const;
58 
59  typedef QPair<std::chrono::nanoseconds, T> TimeValuePair;
60  TimeValuePair &operator[](unsigned int index);
61  const TimeValuePair &operator[](unsigned int index) const;
62  TimeValuePair &operator[](int index);
63  const TimeValuePair &operator[](int index) const;
64 
65  private:
66  QList<TimeValuePair> ring;
67  unsigned int offset;
68  unsigned int length;
69  std::chrono::nanoseconds range;
73  void removeDeprecated();
74  void reshape();
75 };
76 
77 /****************************************************************************/
78 
81 template <class T>
83  offset(0),
84  length(0)
85 {
86 }
87 
88 /****************************************************************************/
89 
92 template <class T>
94 {
95 }
96 
97 /****************************************************************************/
98 
101 template <class T>
102 void ValueRing<T>::setRange(std::chrono::nanoseconds r)
103 {
104  range = r;
105  removeDeprecated();
106 }
107 
108 /****************************************************************************/
109 
112 template <class T>
113 void ValueRing<T>::append(std::chrono::nanoseconds time, const T &value)
114 {
115  TimeValuePair newPair(time, value);
116 
117  if ((int) length < ring.size()) {
118  unsigned int o = (offset + length) % ring.size();
119  ring[o] = newPair;
120  } else {
121 #if VALUERING_DEBUG
122  qDebug() << ring.size() << "reached.";
123 #endif
124  // ring is full
125  if (offset) {
126  reshape();
127  }
128  ring.append(newPair);
129  }
130 
131  length++;
132  removeDeprecated();
133 }
134 
135 /****************************************************************************/
136 
139 template <class T>
141  const ValueRing<T> &other,
142  std::chrono::nanoseconds time
143  )
144 {
145  clear();
146 
147  for (unsigned int i = 0; i < other.length; i++) {
148  TimeValuePair p = other[i];
149  if (p.first > time) {
150  break;
151  }
152 
153  ring.append(p);
154  length++;
155  }
156 }
157 
158 /****************************************************************************/
159 
162 template <class T>
164 {
165  ring.clear();
166  offset = 0;
167  length = 0;
168 }
169 
170 /****************************************************************************/
171 
175 template <class T>
176 inline unsigned int ValueRing<T>::getLength() const
177 {
178  return length;
179 }
180 
181 /****************************************************************************/
182 
185 template <class T>
187  unsigned int index
188  )
189 {
190  return ring[(offset + index) % ring.size()];
191 }
192 
193 /****************************************************************************/
194 
197 template <class T>
199  unsigned int index
200  ) const
201 {
202  return ring.at((offset + index) % ring.size());
203 }
204 
205 /****************************************************************************/
206 
211 template <class T>
213  int index
214  )
215 {
216  if (index >= 0) {
217  return ring[(offset + index) % ring.size()];
218  }
219  else {
220  return ring[(offset + length + index) % ring.size()];
221  }
222 }
223 
224 /****************************************************************************/
225 
230 template <class T>
232  int index
233  ) const
234 {
235  if (index >= 0) {
236  return ring.at((offset + index) % ring.size());
237  }
238  else {
239  return ring.at((offset + length + index) % ring.size());
240  }
241 }
242 
243 /****************************************************************************/
244 
247 template <class T>
249 {
250  if (length) {
251  std::chrono::nanoseconds depTime((*this)[length - 1].first - range);
252  while (length) {
253  if (ring[offset].first < depTime) {
254  offset = (offset + 1) % ring.size();
255  length--;
256  } else {
257  break;
258  }
259  }
260  }
261 }
262 
263 /****************************************************************************/
264 
267 template <class T>
268 void ValueRing<T>::reshape()
269 {
270  QList<TimeValuePair> newRing;
271  unsigned int i;
272 
273 #if VALUERING_DEBUG
274  qDebug() << "reshaping" << length << "values";
275 #endif
276 
277  for (i = 0; i < length; i++) {
278  newRing.append((*this)[i]);
279  }
280  ring = newRing;
281  offset = 0;
282 }
283 
284 /****************************************************************************/
285 
286 } // namespace
287 
288 #endif
std::chrono::nanoseconds getRange() const
Definition: ValueRing.h:51
TimeValuePair & operator[](unsigned int index)
Index operator.
Definition: ValueRing.h:186
unsigned int getLength() const
Definition: ValueRing.h:176
~ValueRing()
Destructor.
Definition: ValueRing.h:93
ValueRing()
Constructor.
Definition: ValueRing.h:82
Definition: LiveSvg.h:18
void append(std::chrono::nanoseconds time, const T &value)
Appends a value to the ring.
Definition: ValueRing.h:113
void copyUntil(const ValueRing< T > &, std::chrono::nanoseconds)
Copies data from another ring, up to a specific time.
Definition: ValueRing.h:140
QPair< std::chrono::nanoseconds, T > TimeValuePair
Definition: ValueRing.h:59
void clear()
Clears the ring.
Definition: ValueRing.h:163
Time/Value ring buffer.
Definition: ValueRing.h:44
void setRange(std::chrono::nanoseconds)
Sets the #range.
Definition: ValueRing.h:102