Mercurial > hg > svcore
comparison data/model/RegionModel.h @ 1651:7a56bb85030f single-point
Introduce deferred notifier, + start converting sparse time-value model (perhaps we should rename it too)
author | Chris Cannam |
---|---|
date | Mon, 18 Mar 2019 14:17:20 +0000 |
parents | 1cc9a0d4b1b6 |
children | 0cfb882155a6 |
comparison
equal
deleted
inserted
replaced
1650:bbfb5a1e4b84 | 1651:7a56bb85030f |
---|---|
2 | 2 |
3 /* | 3 /* |
4 Sonic Visualiser | 4 Sonic Visualiser |
5 An audio file viewer and annotation editor. | 5 An audio file viewer and annotation editor. |
6 Centre for Digital Music, Queen Mary, University of London. | 6 Centre for Digital Music, Queen Mary, University of London. |
7 This file copyright 2006 Chris Cannam. | |
8 | 7 |
9 This program is free software; you can redistribute it and/or | 8 This program is free software; you can redistribute it and/or |
10 modify it under the terms of the GNU General Public License as | 9 modify it under the terms of the GNU General Public License as |
11 published by the Free Software Foundation; either version 2 of the | 10 published by the Free Software Foundation; either version 2 of the |
12 License, or (at your option) any later version. See the file | 11 License, or (at your option) any later version. See the file |
17 #define SV_REGION_MODEL_H | 16 #define SV_REGION_MODEL_H |
18 | 17 |
19 #include "EventCommands.h" | 18 #include "EventCommands.h" |
20 #include "TabularModel.h" | 19 #include "TabularModel.h" |
21 #include "Model.h" | 20 #include "Model.h" |
21 #include "DeferredNotifier.h" | |
22 | 22 |
23 #include "base/RealTime.h" | 23 #include "base/RealTime.h" |
24 #include "base/EventSeries.h" | 24 #include "base/EventSeries.h" |
25 #include "base/UnitDatabase.h" | 25 #include "base/UnitDatabase.h" |
26 | 26 |
47 m_valueMinimum(0.f), | 47 m_valueMinimum(0.f), |
48 m_valueMaximum(0.f), | 48 m_valueMaximum(0.f), |
49 m_haveExtents(false), | 49 m_haveExtents(false), |
50 m_valueQuantization(0), | 50 m_valueQuantization(0), |
51 m_haveDistinctValues(false), | 51 m_haveDistinctValues(false), |
52 m_notifyOnAdd(notifyOnAdd), | 52 m_notifier(this, |
53 m_sinceLastNotifyMin(-1), | 53 notifyOnAdd ? |
54 m_sinceLastNotifyMax(-1), | 54 DeferredNotifier::NOTIFY_ALWAYS : |
55 DeferredNotifier::NOTIFY_DEFERRED), | |
55 m_completion(0) { | 56 m_completion(0) { |
56 } | 57 } |
57 | 58 |
58 RegionModel(sv_samplerate_t sampleRate, int resolution, | 59 RegionModel(sv_samplerate_t sampleRate, int resolution, |
59 float valueMinimum, float valueMaximum, | 60 float valueMinimum, float valueMaximum, |
63 m_valueMinimum(valueMinimum), | 64 m_valueMinimum(valueMinimum), |
64 m_valueMaximum(valueMaximum), | 65 m_valueMaximum(valueMaximum), |
65 m_haveExtents(false), | 66 m_haveExtents(false), |
66 m_valueQuantization(0), | 67 m_valueQuantization(0), |
67 m_haveDistinctValues(false), | 68 m_haveDistinctValues(false), |
68 m_notifyOnAdd(notifyOnAdd), | 69 m_notifier(this, |
69 m_sinceLastNotifyMin(-1), | 70 notifyOnAdd ? |
70 m_sinceLastNotifyMax(-1), | 71 DeferredNotifier::NOTIFY_ALWAYS : |
72 DeferredNotifier::NOTIFY_DEFERRED), | |
71 m_completion(0) { | 73 m_completion(0) { |
72 } | 74 } |
73 | 75 |
74 virtual ~RegionModel() { | 76 virtual ~RegionModel() { |
75 } | 77 } |
98 | 100 |
99 int getCompletion() const { return m_completion; } | 101 int getCompletion() const { return m_completion; } |
100 | 102 |
101 void setCompletion(int completion, bool update = true) { | 103 void setCompletion(int completion, bool update = true) { |
102 | 104 |
103 bool emitCompletionChanged = true; | 105 { QMutexLocker locker(&m_mutex); |
104 bool emitGeneralModelChanged = false; | 106 if (m_completion == completion) return; |
105 bool emitRegionChanged = false; | 107 m_completion = completion; |
106 | 108 } |
107 { | 109 |
108 QMutexLocker locker(&m_mutex); | 110 if (update) { |
109 | 111 m_notifier.makeDeferredNotifications(); |
110 if (m_completion != completion) { | 112 } |
111 m_completion = completion; | 113 |
112 | 114 emit completionChanged(); |
113 if (completion == 100) { | 115 |
114 | 116 if (completion == 100) { |
115 if (m_notifyOnAdd) { | 117 // henceforth: |
116 emitCompletionChanged = false; | 118 m_notifier.switchMode(DeferredNotifier::NOTIFY_ALWAYS); |
117 } | |
118 | |
119 m_notifyOnAdd = true; // henceforth | |
120 emitGeneralModelChanged = true; | |
121 | |
122 } else if (!m_notifyOnAdd) { | |
123 | |
124 if (update && | |
125 m_sinceLastNotifyMin >= 0 && | |
126 m_sinceLastNotifyMax >= 0) { | |
127 emitRegionChanged = true; | |
128 } | |
129 } | |
130 } | |
131 } | |
132 | |
133 if (emitCompletionChanged) { | |
134 emit completionChanged(); | |
135 } | |
136 if (emitGeneralModelChanged) { | |
137 emit modelChanged(); | 119 emit modelChanged(); |
138 } | 120 } |
139 if (emitRegionChanged) { | |
140 emit modelChangedWithin(m_sinceLastNotifyMin, m_sinceLastNotifyMax); | |
141 m_sinceLastNotifyMin = m_sinceLastNotifyMax = -1; | |
142 } | |
143 } | 121 } |
144 | 122 |
145 /** | 123 /** |
146 * Query methods. | 124 * Query methods. |
147 */ | 125 */ |
195 } | 173 } |
196 | 174 |
197 if (e.hasValue() && e.getValue() != 0.f) { | 175 if (e.hasValue() && e.getValue() != 0.f) { |
198 m_haveDistinctValues = true; | 176 m_haveDistinctValues = true; |
199 } | 177 } |
200 | |
201 sv_frame_t f = e.getFrame(); | |
202 | |
203 if (!m_notifyOnAdd) { | |
204 if (m_sinceLastNotifyMin == -1 || f < m_sinceLastNotifyMin) { | |
205 m_sinceLastNotifyMin = f; | |
206 } | |
207 if (m_sinceLastNotifyMax == -1 || f > m_sinceLastNotifyMax) { | |
208 m_sinceLastNotifyMax = f; | |
209 } | |
210 } | |
211 } | 178 } |
212 | 179 |
213 if (m_notifyOnAdd) { | 180 m_notifier.update(e.getFrame(), e.getDuration() + m_resolution); |
214 emit modelChangedWithin(e.getFrame(), | 181 |
215 e.getFrame() + e.getDuration() + m_resolution); | |
216 } | |
217 if (allChange) { | 182 if (allChange) { |
218 emit modelChanged(); | 183 emit modelChanged(); |
219 } | 184 } |
220 } | 185 } |
221 | 186 |
267 case 4: return tr("Label"); | 232 case 4: return tr("Label"); |
268 default: return tr("Unknown"); | 233 default: return tr("Unknown"); |
269 } | 234 } |
270 } | 235 } |
271 | 236 |
237 SortType getSortType(int column) const override { | |
238 if (column == 4) return SortAlphabetical; | |
239 return SortNumeric; | |
240 } | |
241 | |
272 QVariant getData(int row, int column, int role) const override { | 242 QVariant getData(int row, int column, int role) const override { |
273 | 243 |
274 if (row < 0 || row >= m_events.count()) { | 244 if (row < 0 || row >= m_events.count()) { |
275 return QVariant(); | 245 return QVariant(); |
276 } | 246 } |
309 command->remove(e0); | 279 command->remove(e0); |
310 command->add(e1); | 280 command->add(e1); |
311 return command->finish(); | 281 return command->finish(); |
312 } | 282 } |
313 | 283 |
314 SortType getSortType(int column) const override | |
315 { | |
316 if (column == 4) return SortAlphabetical; | |
317 return SortNumeric; | |
318 } | |
319 | |
320 | 284 |
321 /** | 285 /** |
322 * XmlExportable methods. | 286 * XmlExportable methods. |
323 */ | 287 */ |
324 void toXml(QTextStream &out, | 288 void toXml(QTextStream &out, |
329 (out, | 293 (out, |
330 indent, | 294 indent, |
331 QString("type=\"sparse\" dimensions=\"3\" resolution=\"%1\" " | 295 QString("type=\"sparse\" dimensions=\"3\" resolution=\"%1\" " |
332 "notifyOnAdd=\"%2\" dataset=\"%3\" subtype=\"%4\" " | 296 "notifyOnAdd=\"%2\" dataset=\"%3\" subtype=\"%4\" " |
333 "valueQuantization=\"%5\" minimum=\"%6\" maximum=\"%7\" " | 297 "valueQuantization=\"%5\" minimum=\"%6\" maximum=\"%7\" " |
334 "%8") | 298 "units=\"%8\" %9") |
335 .arg(m_resolution) | 299 .arg(m_resolution) |
336 .arg(m_notifyOnAdd ? "true" : "false") | 300 .arg("true") // always true after model reaches 100% - |
301 // subsequent events are always notified | |
337 .arg(getObjectExportId(&m_events)) | 302 .arg(getObjectExportId(&m_events)) |
338 .arg("region") | 303 .arg("region") |
339 .arg(m_valueQuantization) | 304 .arg(m_valueQuantization) |
340 .arg(m_valueMinimum) | 305 .arg(m_valueMinimum) |
341 .arg(m_valueMaximum) | 306 .arg(m_valueMaximum) |
307 .arg(encodeEntities(m_units)) | |
342 .arg(extraAttributes)); | 308 .arg(extraAttributes)); |
343 | 309 |
344 m_events.toXml(out, indent, QString("dimensions=\"3\"")); | 310 m_events.toXml(out, indent, QString("dimensions=\"3\"")); |
345 } | 311 } |
346 | 312 |
352 float m_valueMaximum; | 318 float m_valueMaximum; |
353 bool m_haveExtents; | 319 bool m_haveExtents; |
354 float m_valueQuantization; | 320 float m_valueQuantization; |
355 bool m_haveDistinctValues; | 321 bool m_haveDistinctValues; |
356 QString m_units; | 322 QString m_units; |
357 | 323 DeferredNotifier m_notifier; |
358 bool m_notifyOnAdd; | 324 int m_completion; |
359 sv_frame_t m_sinceLastNotifyMin; | |
360 sv_frame_t m_sinceLastNotifyMax; | |
361 | 325 |
362 EventSeries m_events; | 326 EventSeries m_events; |
363 | |
364 int m_completion; | |
365 | 327 |
366 mutable QMutex m_mutex; | 328 mutable QMutex m_mutex; |
367 }; | 329 }; |
368 | 330 |
369 #endif | 331 #endif |