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