Mercurial > hg > svcore
comparison base/EventSeries.h @ 1624:dcd510bd89db single-point
Try out Qt containers
author | Chris Cannam |
---|---|
date | Mon, 11 Mar 2019 11:17:30 +0000 |
parents | f594fd249473 |
children | 7dbb2a7b592e |
comparison
equal
deleted
inserted
replaced
1623:676e32fa403e | 1624:dcd510bd89db |
---|---|
16 #define SV_EVENT_SERIES_H | 16 #define SV_EVENT_SERIES_H |
17 | 17 |
18 #include "Event.h" | 18 #include "Event.h" |
19 | 19 |
20 #include <set> | 20 #include <set> |
21 | |
22 #include <QHash> | |
23 #include <QMap> | |
21 | 24 |
22 //#define DEBUG_EVENT_SERIES 1 | 25 //#define DEBUG_EVENT_SERIES 1 |
23 | 26 |
24 /** | 27 /** |
25 * Container storing a series of events, with or without durations, | 28 * Container storing a series of events, with or without durations, |
76 SVCERR << "ERROR: EventSeries::add: " | 79 SVCERR << "ERROR: EventSeries::add: " |
77 << "reached end of seam map" | 80 << "reached end of seam map" |
78 << endl; | 81 << endl; |
79 break; | 82 break; |
80 } | 83 } |
81 i->second.insert(p); | 84 i.value().insert(p); |
82 } | 85 } |
83 } | 86 } |
84 | 87 |
85 #ifdef DEBUG_EVENT_SERIES | 88 #ifdef DEBUG_EVENT_SERIES |
86 std::cerr << "after add:" << std::endl; | 89 std::cerr << "after add:" << std::endl; |
98 | 101 |
99 auto pitr = m_events.find(p); | 102 auto pitr = m_events.find(p); |
100 if (pitr == m_events.end()) { | 103 if (pitr == m_events.end()) { |
101 return; // we don't know this event | 104 return; // we don't know this event |
102 } else { | 105 } else { |
103 if (--(pitr->second) == 0) { | 106 if (--(pitr.value()) == 0) { |
104 isUnique = true; | 107 isUnique = true; |
105 m_events.erase(pitr); | 108 m_events.erase(pitr); |
106 } | 109 } |
107 --m_count; | 110 --m_count; |
108 } | 111 } |
130 // This can happen only if we have a negative | 133 // This can happen only if we have a negative |
131 // duration, which Event forbids | 134 // duration, which Event forbids |
132 throw std::logic_error("unexpectedly reached end of map"); | 135 throw std::logic_error("unexpectedly reached end of map"); |
133 } | 136 } |
134 | 137 |
135 i->second.erase(p); | 138 i.value().remove(p); |
136 } | 139 } |
137 | 140 |
138 // Tidy up by removing any entries that are now identical | 141 // Tidy up by removing any entries that are now identical |
139 // to their predecessors | 142 // to their predecessors |
140 | 143 |
145 pitr = i0; | 148 pitr = i0; |
146 --pitr; | 149 --pitr; |
147 } | 150 } |
148 | 151 |
149 for (auto i = i0; i != m_seams.end(); ++i) { | 152 for (auto i = i0; i != m_seams.end(); ++i) { |
150 if (pitr != m_seams.end() && i->second == pitr->second) { | 153 if (pitr != m_seams.end() && i.value() == pitr.value()) { |
151 redundant.push_back(i->first); | 154 redundant.push_back(i.key()); |
152 } | 155 } |
153 pitr = i; | 156 pitr = i; |
154 if (i == i1) { | 157 if (i == i1) { |
155 break; | 158 break; |
156 } | 159 } |
157 } | 160 } |
158 | 161 |
159 for (sv_frame_t f: redundant) { | 162 for (sv_frame_t f: redundant) { |
160 m_seams.erase(f); | 163 m_seams.remove(f); |
161 } | 164 } |
162 } | 165 } |
163 | 166 |
164 #ifdef DEBUG_EVENT_SERIES | 167 #ifdef DEBUG_EVENT_SERIES |
165 std::cerr << "after remove:" << std::endl; | 168 std::cerr << "after remove:" << std::endl; |
210 const sv_frame_t start = frame; | 213 const sv_frame_t start = frame; |
211 const sv_frame_t end = frame + duration; | 214 const sv_frame_t end = frame + duration; |
212 | 215 |
213 // first find any zero-duration events | 216 // first find any zero-duration events |
214 | 217 |
215 auto pitr = m_events.lower_bound(Event(start, QString())); | 218 auto pitr = m_events.lowerBound(Event(start, QString())); |
216 while (pitr != m_events.end() && pitr->first.getFrame() < end) { | 219 while (pitr != m_events.end() && pitr.key().getFrame() < end) { |
217 if (!pitr->first.hasDuration()) { | 220 if (!pitr.key().hasDuration()) { |
218 for (int i = 0; i < pitr->second; ++i) { | 221 for (int i = 0; i < pitr.value(); ++i) { |
219 span.push_back(pitr->first); | 222 span.push_back(pitr.key()); |
220 } | 223 } |
221 } | 224 } |
222 ++pitr; | 225 ++pitr; |
223 } | 226 } |
224 | 227 |
225 // now any non-zero-duration ones from the seam map | 228 // now any non-zero-duration ones from the seam map |
226 | 229 |
227 std::set<Event> found; | 230 std::set<Event> found; |
228 auto sitr = m_seams.lower_bound(start); | 231 auto sitr = m_seams.lowerBound(start); |
229 if (sitr == m_seams.end() || sitr->first > start) { | 232 if (sitr == m_seams.end() || sitr.key() > start) { |
230 if (sitr != m_seams.begin()) { | 233 if (sitr != m_seams.begin()) { |
231 --sitr; | 234 --sitr; |
232 } | 235 } |
233 } | 236 } |
234 while (sitr != m_seams.end() && sitr->first < end) { | 237 while (sitr != m_seams.end() && sitr.key() < end) { |
235 for (const auto &p: sitr->second) { | 238 for (const auto &p: sitr.value()) { |
236 found.insert(p); | 239 found.insert(p); |
237 } | 240 } |
238 ++sitr; | 241 ++sitr; |
239 } | 242 } |
240 for (const auto &p: found) { | 243 for (const auto &p: found) { |
241 int n = m_events.at(p); | 244 int n = m_events.value(p); |
242 if (n < 1) { | 245 if (n < 1) { |
243 throw std::logic_error("event is in seams but not events"); | 246 throw std::logic_error("event is in seams but not events"); |
244 } | 247 } |
245 for (int i = 0; i < n; ++i) { | 248 for (int i = 0; i < n; ++i) { |
246 span.push_back(p); | 249 span.push_back(p); |
260 EventVector getEventsCovering(sv_frame_t frame) const { | 263 EventVector getEventsCovering(sv_frame_t frame) const { |
261 EventVector cover; | 264 EventVector cover; |
262 | 265 |
263 // first find any zero-duration events | 266 // first find any zero-duration events |
264 | 267 |
265 auto pitr = m_events.lower_bound(Event(frame, QString())); | 268 auto pitr = m_events.lowerBound(Event(frame, QString())); |
266 while (pitr != m_events.end() && pitr->first.getFrame() == frame) { | 269 while (pitr != m_events.end() && pitr.key().getFrame() == frame) { |
267 if (!pitr->first.hasDuration()) { | 270 if (!pitr.key().hasDuration()) { |
268 for (int i = 0; i < pitr->second; ++i) { | 271 for (int i = 0; i < pitr.value(); ++i) { |
269 cover.push_back(pitr->first); | 272 cover.push_back(pitr.key()); |
270 } | 273 } |
271 } | 274 } |
272 ++pitr; | 275 ++pitr; |
273 } | 276 } |
274 | 277 |
275 // now any non-zero-duration ones from the seam map | 278 // now any non-zero-duration ones from the seam map. We insert |
276 | 279 // these into a std::set to recover the ordering, lost by QSet |
277 auto sitr = m_seams.lower_bound(frame); | 280 |
278 if (sitr == m_seams.end() || sitr->first > frame) { | 281 std::set<Event> found; |
282 auto sitr = m_seams.lowerBound(frame); | |
283 if (sitr == m_seams.end() || sitr.key() > frame) { | |
279 if (sitr != m_seams.begin()) { | 284 if (sitr != m_seams.begin()) { |
280 --sitr; | 285 --sitr; |
281 } | 286 } |
282 } | 287 } |
283 if (sitr != m_seams.end() && sitr->first <= frame) { | 288 if (sitr != m_seams.end() && sitr.key() <= frame) { |
284 for (const auto &p: sitr->second) { | 289 for (const auto &p: sitr.value()) { |
285 int n = m_events.at(p); | 290 found.insert(p); |
286 if (n < 1) { | 291 } |
287 throw std::logic_error("event is in seams but not events"); | 292 ++sitr; |
288 } | 293 } |
289 for (int i = 0; i < n; ++i) { | 294 for (const auto &p: found) { |
290 cover.push_back(p); | 295 int n = m_events.value(p); |
291 } | 296 if (n < 1) { |
297 throw std::logic_error("event is in seams but not events"); | |
298 } | |
299 for (int i = 0; i < n; ++i) { | |
300 cover.push_back(p); | |
292 } | 301 } |
293 } | 302 } |
294 | 303 |
295 return cover; | 304 return cover; |
296 } | 305 } |
299 /** | 308 /** |
300 * Total number of events in the series. Will exceed | 309 * Total number of events in the series. Will exceed |
301 * m_events.size() if the series contains duplicate events. | 310 * m_events.size() if the series contains duplicate events. |
302 */ | 311 */ |
303 int m_count; | 312 int m_count; |
304 | 313 |
305 /** | 314 /** |
306 * The (ordered) Events map acts as a list of all the events in | 315 * The (ordered) Events map acts as a list of all the events in |
307 * the series. For reasons of backward compatibility, we have to | 316 * the series. For reasons of backward compatibility, we have to |
308 * handle series containing multiple instances of identical | 317 * handle series containing multiple instances of identical |
309 * events; the int indexed against each event records the number | 318 * events; the int indexed against each event records the number |
314 * | 323 * |
315 * Because events are immutable, we never have to move one to a | 324 * Because events are immutable, we never have to move one to a |
316 * different "key" in this map - we only add or delete them or | 325 * different "key" in this map - we only add or delete them or |
317 * change their counts. | 326 * change their counts. |
318 */ | 327 */ |
319 typedef std::map<Event, int> Events; | 328 typedef QMap<Event, int> Events; |
320 Events m_events; | 329 Events m_events; |
321 | 330 |
322 /** | 331 /** |
323 * The FrameEventMap maps from frame number to a set of events. In | 332 * The FrameEventMap maps from frame number to a set of events. In |
324 * the seam map this is used to represent the events that are | 333 * the seam map this is used to represent the events that are |
329 * onward and disappearing again at its end frame. | 338 * onward and disappearing again at its end frame. |
330 * | 339 * |
331 * Only events with duration appear in this map; point events | 340 * Only events with duration appear in this map; point events |
332 * appear only in m_events. | 341 * appear only in m_events. |
333 */ | 342 */ |
334 typedef std::map<sv_frame_t, std::set<Event>> FrameEventMap; | 343 typedef QMap<sv_frame_t, QSet<Event>> FrameEventMap; |
335 FrameEventMap m_seams; | 344 FrameEventMap m_seams; |
336 | 345 |
337 /** Create a seam at the given frame, copying from the prior seam | 346 /** Create a seam at the given frame, copying from the prior seam |
338 * if there is one. If a seam already exists at the given frame, | 347 * if there is one. If a seam already exists at the given frame, |
339 * leave it untouched. | 348 * leave it untouched. |
340 */ | 349 */ |
341 void createSeam(sv_frame_t frame) { | 350 void createSeam(sv_frame_t frame) { |
342 auto itr = m_seams.lower_bound(frame); | 351 auto itr = m_seams.lowerBound(frame); |
343 if (itr == m_seams.end() || itr->first > frame) { | 352 if (itr == m_seams.end() || itr.key() > frame) { |
344 if (itr != m_seams.begin()) { | 353 if (itr != m_seams.begin()) { |
345 --itr; | 354 --itr; |
346 } | 355 } |
347 } | 356 } |
348 if (itr == m_seams.end()) { | 357 if (itr == m_seams.end()) { |
349 m_seams[frame] = {}; | 358 m_seams[frame] = {}; |
350 } else if (itr->first < frame) { | 359 } else if (itr.key() < frame) { |
351 m_seams[frame] = itr->second; | 360 m_seams[frame] = itr.value(); |
352 } else if (itr->first > frame) { // itr must be begin() | 361 } else if (itr.key() > frame) { // itr must be begin() |
353 m_seams[frame] = {}; | 362 m_seams[frame] = {}; |
354 } | 363 } |
355 } | 364 } |
356 | 365 |
357 #ifdef DEBUG_EVENT_SERIES | 366 #ifdef DEBUG_EVENT_SERIES |