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