Mercurial > hg > svapp
comparison framework/Document.cpp @ 683:0736beb8b852 by-id
Toward updating Document for ModelById
author | Chris Cannam |
---|---|
date | Wed, 03 Jul 2019 13:01:26 +0100 |
parents | 1f18e0f64af8 |
children | 610fa108fbcc |
comparison
equal
deleted
inserted
replaced
682:161063152ddd | 683:0736beb8b852 |
---|---|
46 #define DEBUG_DOCUMENT 1 | 46 #define DEBUG_DOCUMENT 1 |
47 | 47 |
48 //!!! still need to handle command history, documentRestored/documentModified | 48 //!!! still need to handle command history, documentRestored/documentModified |
49 | 49 |
50 Document::Document() : | 50 Document::Document() : |
51 m_mainModel(nullptr), | |
52 m_autoAlignment(false), | 51 m_autoAlignment(false), |
53 m_align(new Align()), | 52 m_align(new Align()), |
54 m_isIncomplete(false) | 53 m_isIncomplete(false) |
55 { | 54 { |
56 connect(this, | |
57 SIGNAL(modelAboutToBeDeleted(Model *)), | |
58 ModelTransformerFactory::getInstance(), | |
59 SLOT(modelAboutToBeDeleted(Model *))); | |
60 | |
61 connect(ModelTransformerFactory::getInstance(), | 55 connect(ModelTransformerFactory::getInstance(), |
62 SIGNAL(transformFailed(QString, QString)), | 56 SIGNAL(transformFailed(QString, QString)), |
63 this, | 57 this, |
64 SIGNAL(modelGenerationFailed(QString, QString))); | 58 SIGNAL(modelGenerationFailed(QString, QString))); |
65 | 59 |
66 connect(m_align, SIGNAL(alignmentComplete(AlignmentModel *)), | 60 connect(m_align, SIGNAL(alignmentComplete(ModelId)), |
67 this, SIGNAL(alignmentComplete(AlignmentModel *))); | 61 this, SIGNAL(alignmentComplete(ModelId))); |
68 } | 62 } |
69 | 63 |
70 Document::~Document() | 64 Document::~Document() |
71 { | 65 { |
72 //!!! Document should really own the command history. atm we | 66 //!!! Document should really own the command history. atm we |
83 #endif | 77 #endif |
84 while (!m_layers.empty()) { | 78 while (!m_layers.empty()) { |
85 deleteLayer(*m_layers.begin(), true); | 79 deleteLayer(*m_layers.begin(), true); |
86 } | 80 } |
87 | 81 |
88 if (!m_models.empty()) { | 82 for (auto mr: m_models) { |
89 SVDEBUG << "Document::~Document: WARNING: " | 83 ModelById::release(mr.first); |
90 << m_models.size() << " model(s) still remain -- " | 84 } |
91 << "should have been garbage collected when deleting layers" | 85 for (auto m: m_aggregateModels) { |
92 << endl; | 86 ModelById::release(m); |
93 for (ModelRecord &rec: m_models) { | 87 } |
94 Model *model = rec.model; | 88 |
95 if (model == m_mainModel) { | 89 auto mainModel = m_mainModel; |
96 // just in case! | 90 m_mainModel = {}; |
97 SVDEBUG << "Document::~Document: WARNING: Main model is also" | 91 emit mainModelChanged(m_mainModel); |
98 << " in models list!" << endl; | 92 ModelById::release(mainModel); |
99 } else if (model) { | |
100 model->aboutToDelete(); | |
101 emit modelAboutToBeDeleted(model); | |
102 delete model; | |
103 } | |
104 } | |
105 m_models.clear(); | |
106 } | |
107 | |
108 #ifdef DEBUG_DOCUMENT | |
109 SVDEBUG << "Document::~Document: About to get rid of main model" | |
110 << endl; | |
111 #endif | |
112 if (m_mainModel) { | |
113 m_mainModel->aboutToDelete(); | |
114 emit modelAboutToBeDeleted(m_mainModel); | |
115 } | |
116 | |
117 emit mainModelChanged(nullptr); | |
118 delete m_mainModel; | |
119 } | 93 } |
120 | 94 |
121 Layer * | 95 Layer * |
122 Document::createLayer(LayerFactory::LayerType type) | 96 Document::createLayer(LayerFactory::LayerType type) |
123 { | 97 { |
146 setModel(newLayer, m_mainModel); | 120 setModel(newLayer, m_mainModel); |
147 return newLayer; | 121 return newLayer; |
148 } | 122 } |
149 | 123 |
150 Layer * | 124 Layer * |
151 Document::createImportedLayer(Model *model) | 125 Document::createImportedLayer(ModelId modelId) |
152 { | 126 { |
153 LayerFactory::LayerTypeSet types = | 127 LayerFactory::LayerTypeSet types = |
154 LayerFactory::getInstance()->getValidLayerTypes(model); | 128 LayerFactory::getInstance()->getValidLayerTypes(modelId); |
155 | 129 |
156 if (types.empty()) { | 130 if (types.empty()) { |
157 SVCERR << "WARNING: Document::importLayer: no valid display layer for model" << endl; | 131 SVCERR << "WARNING: Document::importLayer: no valid display layer for model" << endl; |
158 return nullptr; | 132 return nullptr; |
159 } | 133 } |
164 Layer *newLayer = LayerFactory::getInstance()->createLayer(type); | 138 Layer *newLayer = LayerFactory::getInstance()->createLayer(type); |
165 if (!newLayer) return nullptr; | 139 if (!newLayer) return nullptr; |
166 | 140 |
167 newLayer->setObjectName(getUniqueLayerName(newLayer->objectName())); | 141 newLayer->setObjectName(getUniqueLayerName(newLayer->objectName())); |
168 | 142 |
169 addImportedModel(model); | 143 addImportedModel(modelId); |
170 setModel(newLayer, model); | 144 setModel(newLayer, modelId); |
171 | 145 |
172 //!!! and all channels | 146 //!!! and all channels |
173 setChannel(newLayer, -1); | 147 setChannel(newLayer, -1); |
174 | 148 |
175 m_layers.push_back(newLayer); | 149 m_layers.push_back(newLayer); |
184 } | 158 } |
185 | 159 |
186 Layer * | 160 Layer * |
187 Document::createEmptyLayer(LayerFactory::LayerType type) | 161 Document::createEmptyLayer(LayerFactory::LayerType type) |
188 { | 162 { |
189 if (!m_mainModel) return nullptr; | 163 if (m_mainModel.isNone()) return nullptr; |
190 | 164 |
191 Model *newModel = | 165 auto newModel = |
192 LayerFactory::getInstance()->createEmptyModel(type, m_mainModel); | 166 LayerFactory::getInstance()->createEmptyModel(type, m_mainModel); |
193 if (!newModel) return nullptr; | 167 if (!newModel) return nullptr; |
194 | 168 |
195 Layer *newLayer = createLayer(type); | 169 Layer *newLayer = createLayer(type); |
196 if (!newLayer) { | 170 if (!newLayer) { |
197 delete newModel; | |
198 return nullptr; | 171 return nullptr; |
199 } | 172 } |
200 | 173 |
201 addImportedModel(newModel); | 174 ModelById::add(newModel); |
202 setModel(newLayer, newModel); | 175 addImportedModel(newModel->getId()); |
176 setModel(newLayer, newModel->getId()); | |
203 | 177 |
204 return newLayer; | 178 return newLayer; |
205 } | 179 } |
206 | 180 |
207 Layer * | 181 Layer * |
232 vector<Layer *> | 206 vector<Layer *> |
233 Document::createDerivedLayers(const Transforms &transforms, | 207 Document::createDerivedLayers(const Transforms &transforms, |
234 const ModelTransformer::Input &input) | 208 const ModelTransformer::Input &input) |
235 { | 209 { |
236 QString message; | 210 QString message; |
237 vector<Model *> newModels = addDerivedModels(transforms, input, message, nullptr); | 211 vector<ModelId> newModels = |
212 addDerivedModels(transforms, input, message, nullptr); | |
238 | 213 |
239 if (newModels.empty()) { | 214 if (newModels.empty()) { |
240 //!!! This identifier may be wrong! | 215 //!!! This identifier may be wrong! |
241 emit modelGenerationFailed(transforms[0].getIdentifier(), message); | 216 emit modelGenerationFailed(transforms[0].getIdentifier(), message); |
242 return vector<Layer *>(); | 217 return vector<Layer *>(); |
244 //!!! This identifier may be wrong! | 219 //!!! This identifier may be wrong! |
245 emit modelGenerationWarning(transforms[0].getIdentifier(), message); | 220 emit modelGenerationWarning(transforms[0].getIdentifier(), message); |
246 } | 221 } |
247 | 222 |
248 QStringList names; | 223 QStringList names; |
249 for (int i = 0; i < (int)newModels.size(); ++i) { | 224 for (int i = 0; in_range_for(newModels, i); ++i) { |
250 names.push_back(getUniqueLayerName | 225 names.push_back(getUniqueLayerName |
251 (TransformFactory::getInstance()-> | 226 (TransformFactory::getInstance()-> |
252 getTransformFriendlyName | 227 getTransformFriendlyName |
253 (transforms[i].getIdentifier()))); | 228 (transforms[i].getIdentifier()))); |
254 } | 229 } |
273 setPrimaryLayers(vector<Layer *> layers) { | 248 setPrimaryLayers(vector<Layer *> layers) { |
274 m_primary = layers; | 249 m_primary = layers; |
275 } | 250 } |
276 | 251 |
277 void | 252 void |
278 moreModelsAvailable(vector<Model *> models) override { | 253 moreModelsAvailable(vector<ModelId> models) override { |
279 SVDEBUG << "AdditionalModelConverter::moreModelsAvailable: " << models.size() << " model(s)" << endl; | 254 SVDEBUG << "AdditionalModelConverter::moreModelsAvailable: " << models.size() << " model(s)" << endl; |
280 // We can't automatically regenerate the additional models on | 255 // We can't automatically regenerate the additional models on |
281 // reload -- we should delete them instead | 256 // reload - so they go in m_additionalModels instead of m_models |
282 QStringList names; | 257 QStringList names; |
283 foreach (Model *model, models) { | 258 foreach (ModelId modelId, models) { |
284 m_doc->addAdditionalModel(model); | 259 m_doc->addAdditionalModel(modelId); |
285 names.push_back(QString()); | 260 names.push_back(QString()); |
286 } | 261 } |
287 vector<Layer *> layers = m_doc->createLayersForDerivedModels | 262 vector<Layer *> layers = m_doc->createLayersForDerivedModels |
288 (models, names); | 263 (models, names); |
289 m_handler->layersCreated(this, m_primary, layers); | 264 m_handler->layersCreated(this, m_primary, layers); |
296 m_handler->layersCreated(this, m_primary, vector<Layer *>()); | 271 m_handler->layersCreated(this, m_primary, vector<Layer *>()); |
297 delete this; | 272 delete this; |
298 } | 273 } |
299 | 274 |
300 void cancel() { | 275 void cancel() { |
276 /*!!! todo: restore | |
301 foreach (Layer *layer, m_primary) { | 277 foreach (Layer *layer, m_primary) { |
302 Model *model = layer->getModel(); | 278 ModelId model = layer->getModel(); |
279 //!!! todo: restore this behaviour | |
303 if (model) { | 280 if (model) { |
304 model->abandon(); | 281 model->abandon(); |
305 } | 282 } |
306 } | 283 } |
284 */ | |
307 } | 285 } |
308 | 286 |
309 private: | 287 private: |
310 Document *m_doc; | 288 Document *m_doc; |
311 vector<Layer *> m_primary; | 289 vector<Layer *> m_primary; |
319 { | 297 { |
320 QString message; | 298 QString message; |
321 | 299 |
322 AdditionalModelConverter *amc = new AdditionalModelConverter(this, handler); | 300 AdditionalModelConverter *amc = new AdditionalModelConverter(this, handler); |
323 | 301 |
324 vector<Model *> newModels = addDerivedModels | 302 vector<ModelId> newModels = addDerivedModels |
325 (transforms, input, message, amc); | 303 (transforms, input, message, amc); |
326 | 304 |
327 QStringList names; | 305 QStringList names; |
328 for (int i = 0; i < (int)newModels.size(); ++i) { | 306 for (int i = 0; in_range_for(newModels, i); ++i) { |
329 names.push_back(getUniqueLayerName | 307 names.push_back(getUniqueLayerName |
330 (TransformFactory::getInstance()-> | 308 (TransformFactory::getInstance()-> |
331 getTransformFriendlyName | 309 getTransformFriendlyName |
332 (transforms[i].getIdentifier()))); | 310 (transforms[i].getIdentifier()))); |
333 } | 311 } |
354 AdditionalModelConverter *conv = static_cast<AdditionalModelConverter *>(h); | 332 AdditionalModelConverter *conv = static_cast<AdditionalModelConverter *>(h); |
355 conv->cancel(); | 333 conv->cancel(); |
356 } | 334 } |
357 | 335 |
358 vector<Layer *> | 336 vector<Layer *> |
359 Document::createLayersForDerivedModels(vector<Model *> newModels, | 337 Document::createLayersForDerivedModels(vector<ModelId> newModels, |
360 QStringList names) | 338 QStringList names) |
361 { | 339 { |
362 vector<Layer *> layers; | 340 vector<Layer *> layers; |
363 | 341 |
364 for (int i = 0; i < (int)newModels.size(); ++i) { | 342 for (int i = 0; in_range_for(newModels, i); ++i) { |
365 | 343 |
366 Model *newModel = newModels[i]; | 344 ModelId newModelId = newModels[i]; |
367 | 345 |
368 LayerFactory::LayerTypeSet types = | 346 LayerFactory::LayerTypeSet types = |
369 LayerFactory::getInstance()->getValidLayerTypes(newModel); | 347 LayerFactory::getInstance()->getValidLayerTypes(newModelId); |
370 | 348 |
371 if (types.empty()) { | 349 if (types.empty()) { |
372 SVCERR << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << names[i] << endl; | 350 SVCERR << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << names[i] << endl; |
373 //!!! inadequate cleanup: | 351 //!!! inadequate cleanup: |
374 deleteModelFromList(newModel); | 352 //!!! review: -> |
353 // deleteModelFromList(newModel); | |
375 return vector<Layer *>(); | 354 return vector<Layer *>(); |
376 } | 355 } |
377 | 356 |
378 //!!! for now, just use the first suitable layer type | 357 //!!! for now, just use the first suitable layer type |
379 | 358 |
380 Layer *newLayer = createLayer(*types.begin()); | 359 Layer *newLayer = createLayer(*types.begin()); |
381 setModel(newLayer, newModel); | 360 setModel(newLayer, newModelId); |
382 | 361 |
383 //!!! We need to clone the model when adding the layer, so that it | 362 //!!! We need to clone the model when adding the layer, so that it |
384 //can be edited without affecting other layers that are based on | 363 //can be edited without affecting other layers that are based on |
385 //the same model. Unfortunately we can't just clone it now, | 364 //the same model. Unfortunately we can't just clone it now, |
386 //because it probably hasn't been completed yet -- the transform | 365 //because it probably hasn't been completed yet -- the transform |
405 | 384 |
406 return layers; | 385 return layers; |
407 } | 386 } |
408 | 387 |
409 void | 388 void |
410 Document::setMainModel(WaveFileModel *model) | 389 Document::setMainModel(ModelId modelId) |
411 { | 390 { |
412 Model *oldMainModel = m_mainModel; | 391 ModelId oldMainModel = m_mainModel; |
413 m_mainModel = model; | 392 m_mainModel = modelId; |
414 | 393 |
415 emit modelAdded(m_mainModel); | 394 emit modelAdded(m_mainModel); |
416 if (model) { | 395 |
396 if (auto model = ModelById::get(modelId)) { | |
417 emit activity(tr("Set main model to %1").arg(model->objectName())); | 397 emit activity(tr("Set main model to %1").arg(model->objectName())); |
418 } else { | 398 } else { |
419 emit activity(tr("Clear main model")); | 399 emit activity(tr("Clear main model")); |
420 } | 400 } |
421 | 401 |
431 #ifdef DEBUG_DOCUMENT | 411 #ifdef DEBUG_DOCUMENT |
432 SVDEBUG << "Document::setMainModel: Have " | 412 SVDEBUG << "Document::setMainModel: Have " |
433 << m_layers.size() << " layers" << endl; | 413 << m_layers.size() << " layers" << endl; |
434 SVDEBUG << "Models now: "; | 414 SVDEBUG << "Models now: "; |
435 for (const auto &r: m_models) { | 415 for (const auto &r: m_models) { |
436 SVDEBUG << r.model << " "; | 416 SVDEBUG << r.first << " "; |
437 } | 417 } |
438 SVDEBUG << endl; | 418 SVDEBUG << endl; |
439 SVDEBUG << "Old main model: " << oldMainModel << endl; | 419 SVDEBUG << "Old main model: " << oldMainModel << endl; |
440 #endif | 420 #endif |
441 | 421 |
442 for (Layer *layer: m_layers) { | 422 for (Layer *layer: m_layers) { |
443 | 423 |
444 Model *model = layer->getModel(); | 424 ModelId modelId = layer->getModel(); |
445 | 425 |
446 #ifdef DEBUG_DOCUMENT | 426 #ifdef DEBUG_DOCUMENT |
447 SVDEBUG << "Document::setMainModel: inspecting model " | 427 SVDEBUG << "Document::setMainModel: inspecting model " |
448 << (model ? model->objectName(): "(null)") << " in layer " | 428 << modelId << " in layer " << layer->objectName() << endl; |
449 << layer->objectName() << endl; | 429 #endif |
450 #endif | 430 |
451 | 431 if (modelId == oldMainModel) { |
452 if (model == oldMainModel) { | |
453 #ifdef DEBUG_DOCUMENT | 432 #ifdef DEBUG_DOCUMENT |
454 SVDEBUG << "... it uses the old main model, replacing" << endl; | 433 SVDEBUG << "... it uses the old main model, replacing" << endl; |
455 #endif | 434 #endif |
456 LayerFactory::getInstance()->setModel(layer, m_mainModel); | 435 LayerFactory::getInstance()->setModel(layer, m_mainModel); |
457 continue; | 436 continue; |
458 } | 437 } |
459 | 438 |
460 if (!model) { | 439 if (modelId.isNone()) { |
461 SVCERR << "WARNING: Document::setMainModel: Null model in layer " | 440 SVCERR << "WARNING: Document::setMainModel: Null model in layer " |
462 << layer << endl; | 441 << layer << endl; |
463 // get rid of this hideous degenerate | 442 // get rid of this hideous degenerate |
464 obsoleteLayers.push_back(layer); | 443 obsoleteLayers.push_back(layer); |
465 continue; | 444 continue; |
466 } | 445 } |
467 | 446 |
468 auto mitr = findModelInList(model); | 447 if (m_models.find(modelId) == m_models.end()) { |
469 | |
470 if (mitr == m_models.end()) { | |
471 SVCERR << "WARNING: Document::setMainModel: Unknown model " | 448 SVCERR << "WARNING: Document::setMainModel: Unknown model " |
472 << model << " in layer " << layer << endl; | 449 << modelId << " in layer " << layer << endl; |
473 // and this one | 450 // and this one |
474 obsoleteLayers.push_back(layer); | 451 obsoleteLayers.push_back(layer); |
475 continue; | 452 continue; |
476 } | 453 } |
477 | 454 |
478 ModelRecord record = *mitr; | 455 ModelRecord record = m_models[modelId]; |
479 | 456 |
480 if (record.source && (record.source == oldMainModel)) { | 457 if (!record.source.isNone() && (record.source == oldMainModel)) { |
481 | 458 |
482 #ifdef DEBUG_DOCUMENT | 459 #ifdef DEBUG_DOCUMENT |
483 SVDEBUG << "... it uses a model derived from the old main model, regenerating" << endl; | 460 SVDEBUG << "... it uses a model derived from the old main model, regenerating" << endl; |
484 #endif | 461 #endif |
485 | 462 |
491 | 468 |
492 //!!! We have a problem here if the number of channels in | 469 //!!! We have a problem here if the number of channels in |
493 //the main model has changed. | 470 //the main model has changed. |
494 | 471 |
495 QString message; | 472 QString message; |
496 Model *replacementModel = | 473 ModelId replacementModel = |
497 addDerivedModel(transform, | 474 addDerivedModel(transform, |
498 ModelTransformer::Input | 475 ModelTransformer::Input |
499 (m_mainModel, record.channel), | 476 (m_mainModel, record.channel), |
500 message); | 477 message); |
501 | 478 |
502 if (!replacementModel) { | 479 if (replacementModel.isNone()) { |
503 SVCERR << "WARNING: Document::setMainModel: Failed to regenerate model for transform \"" | 480 SVCERR << "WARNING: Document::setMainModel: Failed to regenerate model for transform \"" |
504 << transformId << "\"" << " in layer " << layer << endl; | 481 << transformId << "\"" << " in layer " << layer << endl; |
505 if (failedTransformers.find(transformId) | 482 if (failedTransformers.find(transformId) |
506 == failedTransformers.end()) { | 483 == failedTransformers.end()) { |
507 emit modelRegenerationFailed(layer->objectName(), | 484 emit modelRegenerationFailed(layer->objectName(), |
515 emit modelRegenerationWarning(layer->objectName(), | 492 emit modelRegenerationWarning(layer->objectName(), |
516 transformId, | 493 transformId, |
517 message); | 494 message); |
518 } | 495 } |
519 #ifdef DEBUG_DOCUMENT | 496 #ifdef DEBUG_DOCUMENT |
520 SVDEBUG << "Replacing model " << model << " (type " | 497 SVDEBUG << "Replacing model " << modelId << ") with model " |
521 << typeid(*model).name() << ") with model " | 498 << replacementModel << ") in layer " |
522 << replacementModel << " (type " | |
523 << typeid(*replacementModel).name() << ") in layer " | |
524 << layer << " (name " << layer->objectName() << ")" | 499 << layer << " (name " << layer->objectName() << ")" |
525 << endl; | 500 << endl; |
526 | 501 |
527 RangeSummarisableTimeValueModel *rm = | 502 auto rm = ModelById::getAs<RangeSummarisableTimeValueModel>(replacementModel); |
528 dynamic_cast<RangeSummarisableTimeValueModel *>(replacementModel); | |
529 if (rm) { | 503 if (rm) { |
530 SVDEBUG << "new model has " << rm->getChannelCount() << " channels " << endl; | 504 SVDEBUG << "new model has " << rm->getChannelCount() << " channels " << endl; |
531 } else { | 505 } else { |
532 SVDEBUG << "new model " << replacementModel << " is not a RangeSummarisableTimeValueModel!" << endl; | 506 SVDEBUG << "new model " << replacementModel << " is not a RangeSummarisableTimeValueModel!" << endl; |
533 } | 507 } |
539 | 513 |
540 for (size_t k = 0; k < obsoleteLayers.size(); ++k) { | 514 for (size_t k = 0; k < obsoleteLayers.size(); ++k) { |
541 deleteLayer(obsoleteLayers[k], true); | 515 deleteLayer(obsoleteLayers[k], true); |
542 } | 516 } |
543 | 517 |
544 std::set<Model *> additionalModels; | 518 std::set<ModelId> additionalModels; |
545 for (const auto &rec : m_models) { | 519 for (const auto &rec : m_models) { |
546 if (rec.additional) { | 520 if (rec.second.additional) { |
547 additionalModels.insert(rec.model); | 521 additionalModels.insert(rec.first); |
548 } | 522 } |
549 } | 523 } |
550 for (Model *a: additionalModels) { | 524 for (ModelId a: additionalModels) { |
551 deleteModelFromList(a); | 525 m_models.erase(a); |
552 } | 526 } |
553 | 527 |
554 for (const auto &rec : m_models) { | 528 for (const auto &rec : m_models) { |
555 | 529 |
556 Model *m = rec.model; | 530 auto m = ModelById::get(rec.first); |
557 | 531 if (!m) continue; |
558 #ifdef DEBUG_DOCUMENT | 532 |
559 SVDEBUG << "considering alignment for model " << m << " (name \"" | 533 #ifdef DEBUG_DOCUMENT |
560 << m->objectName() << "\")" << endl; | 534 SVDEBUG << "considering alignment for model " << rec.first << endl; |
561 #endif | 535 #endif |
562 | 536 |
563 if (m_autoAlignment) { | 537 if (m_autoAlignment) { |
564 | 538 |
565 alignModel(m); | 539 alignModel(rec.first); |
566 | 540 |
567 } else if (oldMainModel && | 541 } else if (!oldMainModel.isNone() && |
568 (m->getAlignmentReference() == oldMainModel)) { | 542 (m->getAlignmentReference() == oldMainModel)) { |
569 | 543 |
570 alignModel(m); | 544 alignModel(rec.first); |
571 } | 545 } |
572 } | |
573 | |
574 if (oldMainModel) { | |
575 oldMainModel->aboutToDelete(); | |
576 emit modelAboutToBeDeleted(oldMainModel); | |
577 } | 546 } |
578 | 547 |
579 if (m_autoAlignment) { | 548 if (m_autoAlignment) { |
580 SVDEBUG << "Document::setMainModel: auto-alignment is on, aligning model if possible" << endl; | 549 SVDEBUG << "Document::setMainModel: auto-alignment is on, aligning model if possible" << endl; |
581 alignModel(m_mainModel); | 550 alignModel(m_mainModel); |
583 SVDEBUG << "Document::setMainModel: auto-alignment is off" << endl; | 552 SVDEBUG << "Document::setMainModel: auto-alignment is off" << endl; |
584 } | 553 } |
585 | 554 |
586 emit mainModelChanged(m_mainModel); | 555 emit mainModelChanged(m_mainModel); |
587 | 556 |
588 delete oldMainModel; | 557 ModelById::release(oldMainModel); |
589 } | 558 } |
590 | 559 |
591 void | 560 void |
592 Document::addAlreadyDerivedModel(const Transform &transform, | 561 Document::addAlreadyDerivedModel(const Transform &transform, |
593 const ModelTransformer::Input &input, | 562 const ModelTransformer::Input &input, |
594 Model *outputModelToAdd) | 563 ModelId outputModelToAdd) |
595 { | 564 { |
596 if (findModelInList(outputModelToAdd) != m_models.end()) { | 565 if (m_models.find(outputModelToAdd) != m_models.end()) { |
597 SVCERR << "WARNING: Document::addAlreadyDerivedModel: Model already added" | 566 SVCERR << "WARNING: Document::addAlreadyDerivedModel: Model already added" |
598 << endl; | 567 << endl; |
599 return; | 568 return; |
600 } | 569 } |
601 | 570 |
602 #ifdef DEBUG_DOCUMENT | 571 #ifdef DEBUG_DOCUMENT |
603 if (input.getModel()) { | 572 SVDEBUG << "Document::addAlreadyDerivedModel: source is " << input.getModel() << endl; |
604 SVDEBUG << "Document::addAlreadyDerivedModel: source is " << input.getModel() << " \"" << input.getModel()->objectName() << "\"" << endl; | |
605 } else { | |
606 SVDEBUG << "Document::addAlreadyDerivedModel: source is " << input.getModel() << endl; | |
607 } | |
608 #endif | 573 #endif |
609 | 574 |
610 ModelRecord rec; | 575 ModelRecord rec; |
611 rec.model = outputModelToAdd; | |
612 rec.source = input.getModel(); | 576 rec.source = input.getModel(); |
613 rec.channel = input.getChannel(); | 577 rec.channel = input.getChannel(); |
614 rec.transform = transform; | 578 rec.transform = transform; |
615 rec.additional = false; | 579 rec.additional = false; |
616 rec.refcount = 0; | 580 |
617 | 581 if (auto m = ModelById::get(outputModelToAdd)) { |
618 outputModelToAdd->setSourceModel(input.getModel()); | 582 m->setSourceModel(input.getModel()); |
619 | 583 } |
620 m_models.push_back(rec); | 584 |
585 m_models[outputModelToAdd] = rec; | |
621 | 586 |
622 #ifdef DEBUG_DOCUMENT | 587 #ifdef DEBUG_DOCUMENT |
623 SVDEBUG << "Document::addAlreadyDerivedModel: Added model " << outputModelToAdd << endl; | 588 SVDEBUG << "Document::addAlreadyDerivedModel: Added model " << outputModelToAdd << endl; |
624 SVDEBUG << "Models now: "; | 589 SVDEBUG << "Models now: "; |
625 for (const auto &rec : m_models) { | 590 for (const auto &rec : m_models) { |
626 SVDEBUG << rec.model << " "; | 591 SVDEBUG << rec.first << " "; |
627 } | 592 } |
628 SVDEBUG << endl; | 593 SVDEBUG << endl; |
629 #endif | 594 #endif |
630 | 595 |
631 emit modelAdded(outputModelToAdd); | 596 emit modelAdded(outputModelToAdd); |
632 } | 597 } |
633 | 598 |
634 | 599 void |
635 void | 600 Document::addImportedModel(ModelId modelId) |
636 Document::addImportedModel(Model *model) | 601 { |
637 { | 602 if (m_models.find(modelId) != m_models.end()) { |
638 if (findModelInList(model) != m_models.end()) { | |
639 SVCERR << "WARNING: Document::addImportedModel: Model already added" | 603 SVCERR << "WARNING: Document::addImportedModel: Model already added" |
640 << endl; | 604 << endl; |
641 return; | 605 return; |
642 } | 606 } |
643 | 607 |
644 ModelRecord rec; | 608 ModelRecord rec; |
645 rec.model = model; | 609 rec.source = {}; |
646 rec.source = nullptr; | |
647 rec.channel = 0; | 610 rec.channel = 0; |
648 rec.refcount = 0; | |
649 rec.additional = false; | 611 rec.additional = false; |
650 | 612 |
651 m_models.push_back(rec); | 613 m_models[modelId] = rec; |
652 | 614 |
653 #ifdef DEBUG_DOCUMENT | 615 #ifdef DEBUG_DOCUMENT |
654 SVDEBUG << "Document::addImportedModel: Added model " << model << endl; | 616 SVDEBUG << "Document::addImportedModel: Added model " << modelId << endl; |
655 SVDEBUG << "Models now: "; | 617 SVDEBUG << "Models now: "; |
656 for (const auto &rec : m_models) { | 618 for (const auto &rec : m_models) { |
657 SVDEBUG << rec.model << " "; | 619 SVDEBUG << rec.first << " "; |
658 } | 620 } |
659 SVDEBUG << endl; | 621 SVDEBUG << endl; |
660 #endif | 622 #endif |
661 | 623 |
662 if (m_autoAlignment) { | 624 if (m_autoAlignment) { |
663 SVDEBUG << "Document::addImportedModel: auto-alignment is on, aligning model if possible" << endl; | 625 SVDEBUG << "Document::addImportedModel: auto-alignment is on, aligning model if possible" << endl; |
664 alignModel(model); | 626 alignModel(modelId); |
665 } else { | 627 } else { |
666 SVDEBUG << "Document(" << this << "): addImportedModel: auto-alignment is off" << endl; | 628 SVDEBUG << "Document(" << this << "): addImportedModel: auto-alignment is off" << endl; |
667 } | 629 } |
668 | 630 |
669 emit modelAdded(model); | 631 emit modelAdded(modelId); |
670 } | 632 } |
671 | 633 |
672 void | 634 void |
673 Document::addAdditionalModel(Model *model) | 635 Document::addAdditionalModel(ModelId modelId) |
674 { | 636 { |
675 if (findModelInList(model) != m_models.end()) { | 637 if (m_models.find(modelId) != m_models.end()) { |
676 SVCERR << "WARNING: Document::addAdditionalModel: Model already added" | 638 SVCERR << "WARNING: Document::addAdditionalModel: Model already added" |
677 << endl; | 639 << endl; |
678 return; | 640 return; |
679 } | 641 } |
680 | 642 |
681 ModelRecord rec; | 643 ModelRecord rec; |
682 rec.model = model; | 644 rec.source = {}; |
683 rec.source = nullptr; | |
684 rec.channel = 0; | 645 rec.channel = 0; |
685 rec.refcount = 0; | |
686 rec.additional = true; | 646 rec.additional = true; |
687 | 647 |
688 m_models.push_back(rec); | 648 m_models[modelId] = rec; |
689 | 649 |
690 #ifdef DEBUG_DOCUMENT | 650 #ifdef DEBUG_DOCUMENT |
691 SVDEBUG << "Document::addAdditionalModel: Added model " << model << endl; | 651 SVDEBUG << "Document::addAdditionalModel: Added model " << modelId << endl; |
692 SVDEBUG << "Models now: "; | 652 SVDEBUG << "Models now: "; |
693 for (const auto &rec : m_models) { | 653 for (const auto &rec : m_models) { |
694 SVDEBUG << rec.model << " "; | 654 SVDEBUG << rec.first << " "; |
695 } | 655 } |
696 SVDEBUG << endl; | 656 SVDEBUG << endl; |
697 #endif | 657 #endif |
698 | 658 |
699 if (m_autoAlignment) { | 659 if (m_autoAlignment) { |
700 SVDEBUG << "Document::addAdditionalModel: auto-alignment is on, aligning model if possible" << endl; | 660 SVDEBUG << "Document::addAdditionalModel: auto-alignment is on, aligning model if possible" << endl; |
701 alignModel(model); | 661 alignModel(modelId); |
702 } | 662 } |
703 | 663 |
704 emit modelAdded(model); | 664 emit modelAdded(modelId); |
705 } | 665 } |
706 | 666 |
707 void | 667 void |
708 Document::addAggregateModel(AggregateWaveModel *model) | 668 Document::addAggregateModel(ModelId modelId) |
709 { | 669 { |
710 connect(model, SIGNAL(modelInvalidated()), | 670 m_aggregateModels.insert(modelId); |
711 this, SLOT(aggregateModelInvalidated())); | 671 SVDEBUG << "Document::addAggregateModel(" << modelId << ")" << endl; |
712 m_aggregateModels.insert(model); | 672 } |
713 SVDEBUG << "Document::addAggregateModel(" << model << ")" << endl; | 673 |
714 } | 674 ModelId |
715 | |
716 void | |
717 Document::aggregateModelInvalidated() | |
718 { | |
719 QObject *s = sender(); | |
720 AggregateWaveModel *aggregate = qobject_cast<AggregateWaveModel *>(s); | |
721 SVDEBUG << "Document::aggregateModelInvalidated(" << aggregate << ")" << endl; | |
722 if (aggregate) releaseModel(aggregate); | |
723 } | |
724 | |
725 Model * | |
726 Document::addDerivedModel(const Transform &transform, | 675 Document::addDerivedModel(const Transform &transform, |
727 const ModelTransformer::Input &input, | 676 const ModelTransformer::Input &input, |
728 QString &message) | 677 QString &message) |
729 { | 678 { |
730 for (auto &rec : m_models) { | 679 for (auto &rec : m_models) { |
731 if (rec.transform == transform && | 680 if (rec.second.transform == transform && |
732 rec.source == input.getModel() && | 681 rec.second.source == input.getModel() && |
733 rec.channel == input.getChannel()) { | 682 rec.second.channel == input.getChannel()) { |
734 SVDEBUG << "derived model taken from map " << endl; | 683 SVDEBUG << "derived model taken from map " << endl; |
735 return rec.model; | 684 return rec.first; |
736 } | 685 } |
737 } | 686 } |
738 | 687 |
739 Transforms tt; | 688 Transforms tt; |
740 tt.push_back(transform); | 689 tt.push_back(transform); |
741 vector<Model *> mm = addDerivedModels(tt, input, message, nullptr); | 690 vector<ModelId> mm = addDerivedModels(tt, input, message, nullptr); |
742 if (mm.empty()) return nullptr; | 691 if (mm.empty()) return {}; |
743 else return mm[0]; | 692 else return mm[0]; |
744 } | 693 } |
745 | 694 |
746 vector<Model *> | 695 vector<ModelId> |
747 Document::addDerivedModels(const Transforms &transforms, | 696 Document::addDerivedModels(const Transforms &transforms, |
748 const ModelTransformer::Input &input, | 697 const ModelTransformer::Input &input, |
749 QString &message, | 698 QString &message, |
750 AdditionalModelConverter *amc) | 699 AdditionalModelConverter *amc) |
751 { | 700 { |
752 vector<Model *> mm = | 701 vector<ModelId> mm = |
753 ModelTransformerFactory::getInstance()->transformMultiple | 702 ModelTransformerFactory::getInstance()->transformMultiple |
754 (transforms, input, message, amc); | 703 (transforms, input, message, amc); |
755 | 704 |
756 for (int j = 0; j < (int)mm.size(); ++j) { | 705 for (int j = 0; in_range_for(mm, j); ++j) { |
757 | 706 |
758 Model *model = mm[j]; | 707 ModelId modelId = mm[j]; |
708 Transform applied = transforms[j]; | |
709 | |
710 if (modelId.isNone()) { | |
711 SVCERR << "WARNING: Document::addDerivedModel: no output model for transform " << applied.getIdentifier() << endl; | |
712 continue; | |
713 } | |
759 | 714 |
760 // The transform we actually used was presumably identical to | 715 // The transform we actually used was presumably identical to |
761 // the one asked for, except that the version of the plugin | 716 // the one asked for, except that the version of the plugin |
762 // may differ. It's possible that the returned message | 717 // may differ. It's possible that the returned message |
763 // contains a warning about this; that doesn't concern us | 718 // contains a warning about this; that doesn't concern us |
766 // current plugin version. | 721 // current plugin version. |
767 | 722 |
768 //!!! would be nice to short-circuit this -- the version is | 723 //!!! would be nice to short-circuit this -- the version is |
769 //!!! static data, shouldn't have to construct a plugin for it | 724 //!!! static data, shouldn't have to construct a plugin for it |
770 //!!! (which may be expensive in Piper-world) | 725 //!!! (which may be expensive in Piper-world) |
771 | |
772 Transform applied = transforms[j]; | |
773 applied.setPluginVersion | 726 applied.setPluginVersion |
774 (TransformFactory::getInstance()-> | 727 (TransformFactory::getInstance()-> |
775 getDefaultTransformFor(applied.getIdentifier(), | 728 getDefaultTransformFor(applied.getIdentifier(), |
776 applied.getSampleRate()) | 729 applied.getSampleRate()) |
777 .getPluginVersion()); | 730 .getPluginVersion()); |
778 | 731 |
779 if (!model) { | 732 addAlreadyDerivedModel(applied, input, modelId); |
780 SVCERR << "WARNING: Document::addDerivedModel: no output model for transform " << applied.getIdentifier() << endl; | |
781 } else { | |
782 addAlreadyDerivedModel(applied, input, model); | |
783 } | |
784 } | 733 } |
785 | 734 |
786 return mm; | 735 return mm; |
787 } | 736 } |
788 | 737 |
789 void | 738 void |
790 Document::releaseModel(Model *model) // Will _not_ release main model! | 739 Document::releaseModel(ModelId modelId) // Will _not_ release main model! |
791 { | 740 { |
792 if (model == nullptr) { | 741 //!!! |
742 | |
743 SVCERR << "Document::releaseModel(" << modelId << "): STILL TO REVIEW" << endl; | |
744 | |
745 #ifdef NOT_DEFINED | |
746 | |
747 if (modelId.isNone()) { | |
793 return; | 748 return; |
794 } | 749 } |
795 | 750 |
796 #ifdef DEBUG_DOCUMENT | 751 auto model = ModelById::get(modelId); |
797 SVDEBUG << "Document::releaseModel(" << model << ", type " | 752 if (!model) { |
753 return; | |
754 } | |
755 | |
756 #ifdef DEBUG_DOCUMENT | |
757 SVDEBUG << "Document::releaseModel(" << modelId << ", type " | |
798 << model->getTypeName() << ", name \"" | 758 << model->getTypeName() << ", name \"" |
799 << model->objectName() << "\")" << endl; | 759 << model->objectName() << "\")" << endl; |
800 #endif | 760 #endif |
801 | 761 |
802 if (model == m_mainModel) { | 762 if (modelId == m_mainModel) { |
803 return; | 763 return; |
804 } | 764 } |
805 | 765 |
806 bool toDelete = false; | 766 bool toDelete = false; |
807 bool isInModelList = false; // should become true for any "normal" model | 767 bool isInModelList = false; // should become true for any "normal" model |
808 | 768 |
809 ModelList::iterator mitr = findModelInList(model); | 769 if (m_models.find(modelId) != m_models.end()) { |
810 | |
811 if (mitr != m_models.end()) { | |
812 | 770 |
813 if (mitr->refcount == 0) { | 771 if (mitr->refcount == 0) { |
814 SVCERR << "WARNING: Document::releaseModel: model " << model | 772 SVCERR << "WARNING: Document::releaseModel: model " << model |
815 << " reference count is zero already!" << endl; | 773 << " reference count is zero already!" << endl; |
816 } else { | 774 } else { |
871 #ifdef DEBUG_DOCUMENT | 829 #ifdef DEBUG_DOCUMENT |
872 SVDEBUG << "Document::releaseModel: Deleted awkward model " << model << endl; | 830 SVDEBUG << "Document::releaseModel: Deleted awkward model " << model << endl; |
873 #endif | 831 #endif |
874 } | 832 } |
875 } | 833 } |
834 | |
835 #endif | |
876 } | 836 } |
877 | 837 |
878 void | 838 void |
879 Document::deleteLayer(Layer *layer, bool force) | 839 Document::deleteLayer(Layer *layer, bool force) |
880 { | 840 { |
934 emit layerAboutToBeDeleted(layer); | 894 emit layerAboutToBeDeleted(layer); |
935 delete layer; | 895 delete layer; |
936 } | 896 } |
937 | 897 |
938 void | 898 void |
939 Document::setModel(Layer *layer, Model *model) | 899 Document::setModel(Layer *layer, ModelId modelId) |
940 { | 900 { |
941 if (model && | 901 if (!modelId.isNone() && |
942 model != m_mainModel && | 902 modelId != m_mainModel && |
943 findModelInList(model) == m_models.end()) { | 903 m_models.find(modelId) == m_models.end()) { |
944 SVCERR << "ERROR: Document::setModel: Layer " << layer | 904 SVCERR << "ERROR: Document::setModel: Layer " << layer |
945 << " (\"" << layer->objectName() | 905 << " (\"" << layer->objectName() |
946 << "\") wants to use unregistered model " << model | 906 << "\") wants to use unregistered model " << modelId |
947 << ": register the layer's model before setting it!" | 907 << ": register the layer's model before setting it!" |
948 << endl; | 908 << endl; |
949 return; | 909 return; |
950 } | 910 } |
951 | 911 |
952 Model *previousModel = layer->getModel(); | 912 ModelId previousModel = layer->getModel(); |
953 | 913 |
954 if (previousModel == model) { | 914 if (previousModel == modelId) { |
955 SVDEBUG << "NOTE: Document::setModel: Layer " << layer << " (\"" | 915 SVDEBUG << "NOTE: Document::setModel: Layer " << layer << " (\"" |
956 << layer->objectName() << "\") is already set to model " | 916 << layer->objectName() |
957 << model << " (\"" | 917 << "\") is already set to model " |
958 << (model ? model->objectName(): "(null)") | 918 << modelId << endl; |
959 << "\")" << endl; | |
960 return; | 919 return; |
961 } | 920 } |
962 | 921 /*!!! |
963 if (model && model != m_mainModel) { | 922 if (model && model != m_mainModel) { |
964 ModelList::iterator mitr = findModelInList(model); | 923 ModelList::iterator mitr = findModelInList(model); |
965 if (mitr != m_models.end()) { | 924 if (mitr != m_models.end()) { |
966 mitr->refcount ++; | 925 mitr->refcount ++; |
967 } | 926 } |
968 } | 927 } |
969 | 928 */ |
970 if (model && previousModel) { | 929 if (!modelId.isNone() && !previousModel.isNone()) { |
971 PlayParameterRepository::getInstance()->copyParameters | 930 PlayParameterRepository::getInstance()->copyParameters |
972 (previousModel, model); | 931 (previousModel.untyped, modelId.untyped); |
973 } | 932 } |
974 | 933 |
975 LayerFactory::getInstance()->setModel(layer, model); | 934 LayerFactory::getInstance()->setModel(layer, modelId); |
976 | 935 |
977 if (previousModel) { | 936 releaseModel(previousModel); |
978 releaseModel(previousModel); | |
979 } | |
980 } | 937 } |
981 | 938 |
982 void | 939 void |
983 Document::setChannel(Layer *layer, int channel) | 940 Document::setChannel(Layer *layer, int channel) |
984 { | 941 { |
986 } | 943 } |
987 | 944 |
988 void | 945 void |
989 Document::addLayerToView(View *view, Layer *layer) | 946 Document::addLayerToView(View *view, Layer *layer) |
990 { | 947 { |
991 Model *model = layer->getModel(); | 948 ModelId modelId = layer->getModel(); |
992 if (!model) { | 949 if (modelId.isNone()) { |
993 #ifdef DEBUG_DOCUMENT | 950 #ifdef DEBUG_DOCUMENT |
994 SVDEBUG << "Document::addLayerToView: Layer (\"" | 951 SVDEBUG << "Document::addLayerToView: Layer (\"" |
995 << layer->objectName() | 952 << layer->objectName() |
996 << "\") with no model being added to view: " | 953 << "\") with no model being added to view: " |
997 << "normally you want to set the model first" << endl; | 954 << "normally you want to set the model first" << endl; |
998 #endif | 955 #endif |
999 } else { | 956 } else { |
1000 if (model != m_mainModel && | 957 if (modelId != m_mainModel && |
1001 findModelInList(model) == m_models.end()) { | 958 m_models.find(modelId) == m_models.end()) { |
1002 SVCERR << "ERROR: Document::addLayerToView: Layer " << layer | 959 SVCERR << "ERROR: Document::addLayerToView: Layer " << layer |
1003 << " has unregistered model " << model | 960 << " has unregistered model " << modelId |
1004 << " -- register the layer's model before adding the layer!" << endl; | 961 << " -- register the layer's model before adding the layer!" << endl; |
1005 return; | 962 return; |
1006 } | 963 } |
1007 } | 964 } |
1008 | 965 |
1073 | 1030 |
1074 if (!duplicate) return adjusted; | 1031 if (!duplicate) return adjusted; |
1075 } | 1032 } |
1076 } | 1033 } |
1077 | 1034 |
1078 std::vector<Model *> | 1035 std::vector<ModelId> |
1079 Document::getTransformInputModels() | 1036 Document::getTransformInputModels() |
1080 { | 1037 { |
1081 std::vector<Model *> models; | 1038 std::vector<ModelId> models; |
1082 | 1039 |
1083 if (!m_mainModel) return models; | 1040 if (m_mainModel.isNone()) return models; |
1084 | 1041 |
1085 models.push_back(m_mainModel); | 1042 models.push_back(m_mainModel); |
1086 | 1043 |
1087 //!!! This will pick up all models, including those that aren't visible... | 1044 //!!! This will pick up all models, including those that aren't visible... |
1088 | 1045 |
1089 for (ModelRecord &rec: m_models) { | 1046 for (auto rec: m_models) { |
1090 | 1047 |
1091 Model *model = rec.model; | 1048 ModelId modelId = rec.first; |
1092 if (!model || model == m_mainModel) continue; | 1049 if (modelId == m_mainModel) continue; |
1093 DenseTimeValueModel *dtvm = dynamic_cast<DenseTimeValueModel *>(model); | 1050 |
1094 | 1051 auto dtvm = ModelById::getAs<DenseTimeValueModel>(modelId); |
1095 if (dtvm) { | 1052 if (dtvm) { |
1096 models.push_back(dtvm); | 1053 models.push_back(modelId); |
1097 } | 1054 } |
1098 } | 1055 } |
1099 | 1056 |
1100 return models; | 1057 return models; |
1101 } | 1058 } |
1102 | 1059 |
1060 //!!! what is this used for? | |
1103 bool | 1061 bool |
1104 Document::isKnownModel(const Model *model) const | 1062 Document::isKnownModel(const ModelId modelId) const |
1105 { | 1063 { |
1106 if (model == m_mainModel) return true; | 1064 if (modelId == m_mainModel) return true; |
1107 for (const ModelRecord &rec: m_models) { | 1065 for (auto rec: m_models) { |
1108 if (rec.model == model) return true; | 1066 if (rec.first == modelId) return true; |
1109 } | 1067 } |
1110 return false; | 1068 return false; |
1111 } | 1069 } |
1112 | 1070 |
1113 bool | 1071 bool |
1115 { | 1073 { |
1116 return Align::canAlign(); | 1074 return Align::canAlign(); |
1117 } | 1075 } |
1118 | 1076 |
1119 void | 1077 void |
1120 Document::alignModel(Model *model, bool forceRecalculate) | 1078 Document::alignModel(ModelId modelId, bool forceRecalculate) |
1121 { | 1079 { |
1122 SVDEBUG << "Document::alignModel(" << model << ", " << forceRecalculate | 1080 SVDEBUG << "Document::alignModel(" << modelId << ", " << forceRecalculate |
1123 << ") (main model is " << m_mainModel << ")" << endl; | 1081 << ") (main model is " << m_mainModel << ")" << endl; |
1124 | 1082 |
1125 RangeSummarisableTimeValueModel *rm = | 1083 auto rm = ModelById::getAs<RangeSummarisableTimeValueModel>(modelId); |
1126 dynamic_cast<RangeSummarisableTimeValueModel *>(model); | |
1127 if (!rm) { | 1084 if (!rm) { |
1128 SVDEBUG << "(model " << rm << " is not an alignable sort)" << endl; | 1085 SVDEBUG << "(model " << modelId << " is not an alignable sort)" << endl; |
1129 return; | 1086 return; |
1130 } | 1087 } |
1131 | 1088 |
1132 if (!m_mainModel) { | 1089 if (m_mainModel.isNone()) { |
1133 SVDEBUG << "(no main model to align to)" << endl; | 1090 SVDEBUG << "(no main model to align to)" << endl; |
1134 if (forceRecalculate && rm->getAlignment()) { | 1091 if (forceRecalculate && !rm->getAlignment().isNone()) { |
1135 SVDEBUG << "(but model is aligned, and forceRecalculate is true, " | 1092 SVDEBUG << "(but model is aligned, and forceRecalculate is true, " |
1136 << "so resetting alignment to nil)" << endl; | 1093 << "so resetting alignment to nil)" << endl; |
1137 rm->setAlignment(nullptr); | 1094 rm->setAlignment({}); |
1138 } | 1095 } |
1139 return; | 1096 return; |
1140 } | 1097 } |
1141 | 1098 |
1142 if (rm->getAlignmentReference() == m_mainModel) { | 1099 if (rm->getAlignmentReference() == m_mainModel) { |
1143 SVDEBUG << "(model " << rm << " is already aligned to main model " | 1100 SVDEBUG << "(model " << modelId << " is already aligned to main model " |
1144 << m_mainModel << ")" << endl; | 1101 << m_mainModel << ")" << endl; |
1145 if (!forceRecalculate) { | 1102 if (!forceRecalculate) { |
1146 return; | 1103 return; |
1147 } else { | 1104 } else { |
1148 SVDEBUG << "(but forceRecalculate is true, so realigning anyway)" | 1105 SVDEBUG << "(but forceRecalculate is true, so realigning anyway)" |
1149 << endl; | 1106 << endl; |
1150 } | 1107 } |
1151 } | 1108 } |
1152 | 1109 |
1153 if (model == m_mainModel) { | 1110 if (modelId == m_mainModel) { |
1154 // The reference has an empty alignment to itself. This makes | 1111 // The reference has an empty alignment to itself. This makes |
1155 // it possible to distinguish between the reference and any | 1112 // it possible to distinguish between the reference and any |
1156 // unaligned model just by looking at the model itself, | 1113 // unaligned model just by looking at the model itself, |
1157 // without also knowing what the main model is | 1114 // without also knowing what the main model is |
1158 SVDEBUG << "Document::alignModel(" << model | 1115 SVDEBUG << "Document::alignModel(" << modelId |
1159 << "): is main model, setting alignment to itself" << endl; | 1116 << "): is main model, setting alignment to itself" << endl; |
1160 rm->setAlignment(new AlignmentModel(model, model, nullptr)); | 1117 auto alignment = std::make_shared<AlignmentModel>(modelId, modelId, |
1118 ModelId()); | |
1119 ModelById::add(alignment); | |
1120 //!!! hang on, who tracks alignment models? | |
1121 rm->setAlignment(alignment->getId()); | |
1161 return; | 1122 return; |
1162 } | 1123 } |
1163 | 1124 |
1164 WritableWaveFileModel *w = | 1125 auto w = ModelById::getAs<WritableWaveFileModel>(modelId); |
1165 dynamic_cast<WritableWaveFileModel *>(model); | |
1166 if (w && w->getWriteProportion() < 100) { | 1126 if (w && w->getWriteProportion() < 100) { |
1167 SVDEBUG << "Document::alignModel(" << model | 1127 SVDEBUG << "Document::alignModel(" << modelId |
1168 << "): model write is not complete, deferring" | 1128 << "): model write is not complete, deferring" |
1169 << endl; | 1129 << endl; |
1170 connect(w, SIGNAL(writeCompleted()), | 1130 connect(w.get(), SIGNAL(writeCompleted()), |
1171 this, SLOT(performDeferredAlignment())); | 1131 this, SLOT(performDeferredAlignment())); |
1172 return; | 1132 return; |
1173 } | 1133 } |
1174 | 1134 |
1175 SVDEBUG << "Document::alignModel: aligning..." << endl; | 1135 SVDEBUG << "Document::alignModel: aligning..." << endl; |
1176 if (rm->getAlignmentReference() != nullptr) { | 1136 if (!rm->getAlignmentReference().isNone()) { |
1177 SVDEBUG << "(Note: model " << rm << " is currently aligned to model " | 1137 SVDEBUG << "(Note: model " << rm << " is currently aligned to model " |
1178 << rm->getAlignmentReference() << "; this will replace that)" | 1138 << rm->getAlignmentReference() << "; this will replace that)" |
1179 << endl; | 1139 << endl; |
1180 } | 1140 } |
1181 | 1141 |
1182 QString err; | 1142 QString err; |
1183 if (!m_align->alignModel(this, m_mainModel, rm, err)) { | 1143 if (!m_align->alignModel(this, m_mainModel, modelId, err)) { |
1184 SVCERR << "Alignment failed: " << err << endl; | 1144 SVCERR << "Alignment failed: " << err << endl; |
1185 emit alignmentFailed(err); | 1145 emit alignmentFailed(err); |
1186 } | 1146 } |
1187 } | 1147 } |
1188 | 1148 |
1189 void | 1149 void |
1190 Document::performDeferredAlignment() | 1150 Document::performDeferredAlignment() |
1191 { | 1151 { |
1192 QObject *s = sender(); | 1152 ModelId modelId; |
1193 Model *m = dynamic_cast<Model *>(s); | 1153 if (Model *m = qobject_cast<Model *>(sender())) { |
1194 if (!m) { | 1154 modelId = m->getId(); |
1155 } else { | |
1195 SVDEBUG << "Document::performDeferredAlignment: sender is not a Model" << endl; | 1156 SVDEBUG << "Document::performDeferredAlignment: sender is not a Model" << endl; |
1196 } else { | 1157 return; |
1197 SVDEBUG << "Document::performDeferredAlignment: aligning..." << endl; | 1158 } |
1198 alignModel(m); | 1159 |
1199 } | 1160 SVDEBUG << "Document::performDeferredAlignment: aligning..." << endl; |
1161 alignModel(modelId); | |
1200 } | 1162 } |
1201 | 1163 |
1202 void | 1164 void |
1203 Document::alignModels() | 1165 Document::alignModels() |
1204 { | 1166 { |
1205 for (const ModelRecord &rec: m_models) { | 1167 for (auto rec: m_models) { |
1206 alignModel(rec.model); | 1168 alignModel(rec.first); |
1207 } | 1169 } |
1208 alignModel(m_mainModel); | 1170 alignModel(m_mainModel); |
1209 } | 1171 } |
1210 | 1172 |
1211 void | 1173 void |
1212 Document::realignModels() | 1174 Document::realignModels() |
1213 { | 1175 { |
1214 for (const ModelRecord &rec: m_models) { | 1176 for (auto rec: m_models) { |
1215 alignModel(rec.model, true); | 1177 alignModel(rec.first, true); |
1216 } | 1178 } |
1217 alignModel(m_mainModel); | 1179 alignModel(m_mainModel); |
1218 } | 1180 } |
1219 | 1181 |
1220 Document::AddLayerCommand::AddLayerCommand(Document *d, | 1182 Document::AddLayerCommand::AddLayerCommand(Document *d, |
1360 bool asTemplate) const | 1322 bool asTemplate) const |
1361 { | 1323 { |
1362 out << indent + QString("<data%1%2>\n") | 1324 out << indent + QString("<data%1%2>\n") |
1363 .arg(extraAttributes == "" ? "" : " ").arg(extraAttributes); | 1325 .arg(extraAttributes == "" ? "" : " ").arg(extraAttributes); |
1364 | 1326 |
1365 if (m_mainModel) { | 1327 auto mainModel = ModelById::getAs<WaveFileModel>(m_mainModel); |
1328 if (mainModel) { | |
1366 | 1329 |
1367 #ifdef DEBUG_DOCUMENT | 1330 #ifdef DEBUG_DOCUMENT |
1368 SVDEBUG << "Document::toXml: writing main model" << endl; | 1331 SVDEBUG << "Document::toXml: writing main model" << endl; |
1369 #endif | 1332 #endif |
1370 | 1333 |
1371 if (asTemplate) { | 1334 if (asTemplate) { |
1372 writePlaceholderMainModel(out, indent + " "); | 1335 writePlaceholderMainModel(out, indent + " "); |
1373 } else { | 1336 } else { |
1374 m_mainModel->toXml(out, indent + " ", "mainModel=\"true\""); | 1337 mainModel->toXml(out, indent + " ", "mainModel=\"true\""); |
1375 } | 1338 } |
1376 | 1339 |
1377 PlayParameters *playParameters = | 1340 PlayParameters *playParameters = |
1378 PlayParameterRepository::getInstance()->getPlayParameters(m_mainModel); | 1341 PlayParameterRepository::getInstance()->getPlayParameters |
1342 (m_mainModel.untyped); | |
1379 if (playParameters) { | 1343 if (playParameters) { |
1380 playParameters->toXml | 1344 playParameters->toXml |
1381 (out, indent + " ", | 1345 (out, indent + " ", |
1382 QString("model=\"%1\"") | 1346 QString("model=\"%1\"") |
1383 .arg(m_mainModel->getExportId())); | 1347 .arg(mainModel->getExportId())); |
1384 } | 1348 } |
1385 } else { | 1349 } else { |
1386 #ifdef DEBUG_DOCUMENT | 1350 #ifdef DEBUG_DOCUMENT |
1387 SVDEBUG << "Document::toXml: have no main model to write" << endl; | 1351 SVDEBUG << "Document::toXml: have no main model to write" << endl; |
1388 #endif | 1352 #endif |
1389 } | 1353 } |
1390 | 1354 |
1391 // Models that are not used in a layer that is in a view should | 1355 // Models that are not used in a layer that is in a view should |
1392 // not be written. Get our list of required models first. | 1356 // not be written. Get our list of required models first. |
1393 | 1357 |
1394 std::set<const Model *> used; | 1358 std::set<ModelId> used; |
1395 | 1359 |
1396 for (LayerViewMap::const_iterator i = m_layerViewMap.begin(); | 1360 for (LayerViewMap::const_iterator i = m_layerViewMap.begin(); |
1397 i != m_layerViewMap.end(); ++i) { | 1361 i != m_layerViewMap.end(); ++i) { |
1398 | 1362 |
1399 if (i->first && !i->second.empty()) { // Layer exists, is in views | 1363 if (i->first && !i->second.empty()) { // Layer exists, is in views |
1400 Model *m = i->first->getModel(); | 1364 ModelId modelId = i->first->getModel(); |
1401 if (m) { | 1365 if (auto model = ModelById::get(modelId)) { |
1402 used.insert(m); | 1366 used.insert(modelId); |
1403 if (m->getSourceModel()) { | 1367 if (!model->getSourceModel().isNone()) { |
1404 used.insert(m->getSourceModel()); | 1368 used.insert(model->getSourceModel()); |
1405 } | 1369 } |
1406 } | 1370 } |
1407 } | 1371 } |
1408 } | 1372 } |
1409 | 1373 |
1418 // (i.e. non-derived) wave-type models first, then aggregate | 1382 // (i.e. non-derived) wave-type models first, then aggregate |
1419 // models, then models that have derivations. But we didn't do | 1383 // models, then models that have derivations. But we didn't do |
1420 // that, so existing sessions will always have the aggregate | 1384 // that, so existing sessions will always have the aggregate |
1421 // models first and we might as well stick with that. | 1385 // models first and we might as well stick with that. |
1422 | 1386 |
1423 for (std::set<Model *>::iterator i = m_aggregateModels.begin(); | 1387 for (auto modelId: m_aggregateModels) { |
1424 i != m_aggregateModels.end(); ++i) { | 1388 |
1425 | 1389 #ifdef DEBUG_DOCUMENT |
1426 #ifdef DEBUG_DOCUMENT | 1390 SVDEBUG << "Document::toXml: checking aggregate model " |
1427 SVDEBUG << "Document::toXml: checking aggregate model " << *i << endl; | 1391 << modelId << endl; |
1428 #endif | 1392 #endif |
1429 | 1393 |
1430 AggregateWaveModel *aggregate = qobject_cast<AggregateWaveModel *>(*i); | 1394 auto aggregate = ModelById::getAs<AggregateWaveModel>(modelId); |
1431 if (!aggregate) continue; | 1395 if (!aggregate) continue; |
1432 if (used.find(aggregate) == used.end()) { | 1396 if (used.find(modelId) == used.end()) { |
1433 #ifdef DEBUG_DOCUMENT | 1397 #ifdef DEBUG_DOCUMENT |
1434 SVDEBUG << "(unused, skipping)" << endl; | 1398 SVDEBUG << "(unused, skipping)" << endl; |
1435 #endif | 1399 #endif |
1436 continue; | 1400 continue; |
1437 } | 1401 } |
1441 #endif | 1405 #endif |
1442 | 1406 |
1443 aggregate->toXml(out, indent + " "); | 1407 aggregate->toXml(out, indent + " "); |
1444 } | 1408 } |
1445 | 1409 |
1446 std::set<Model *> written; | 1410 std::set<ModelId> written; |
1447 | 1411 |
1448 // Now write the other models in two passes: first the models that | 1412 // Now write the other models in two passes: first the models that |
1449 // aren't derived from anything (in case they are source | 1413 // aren't derived from anything (in case they are source |
1450 // components for an aggregate model, in which case we need to | 1414 // components for an aggregate model, in which case we need to |
1451 // have seen them before we see any models derived from aggregates | 1415 // have seen them before we see any models derived from aggregates |
1453 // have derivations. | 1417 // have derivations. |
1454 | 1418 |
1455 const int nonDerivedPass = 0, derivedPass = 1; | 1419 const int nonDerivedPass = 0, derivedPass = 1; |
1456 for (int pass = nonDerivedPass; pass <= derivedPass; ++pass) { | 1420 for (int pass = nonDerivedPass; pass <= derivedPass; ++pass) { |
1457 | 1421 |
1458 for (const ModelRecord &rec: m_models) { | 1422 for (auto rec: m_models) { |
1459 | 1423 |
1460 Model *model = rec.model; | 1424 ModelId modelId = rec.first; |
1461 | 1425 |
1462 if (used.find(model) == used.end()) continue; | 1426 if (used.find(modelId) == used.end()) continue; |
1463 | 1427 |
1464 #ifdef DEBUG_DOCUMENT | 1428 auto model = ModelById::get(modelId); |
1465 SVDEBUG << "Document::toXml: looking at model " << model | 1429 if (!model) continue; |
1466 << " (" << model->getTypeName() << ", \"" | 1430 |
1467 << model->objectName() << "\") [pass = " | 1431 #ifdef DEBUG_DOCUMENT |
1468 << pass << "]" << endl; | 1432 SVDEBUG << "Document::toXml: looking at model " << modelId |
1433 << " [pass = " << pass << "]" << endl; | |
1469 #endif | 1434 #endif |
1470 | 1435 |
1471 // We need an intelligent way to determine which models | 1436 // We need an intelligent way to determine which models |
1472 // need to be streamed (i.e. have been edited, or are | 1437 // need to be streamed (i.e. have been edited, or are |
1473 // small) and which should not be (i.e. remain as | 1438 // small) and which should not be (i.e. remain as |
1483 // intelligent guess. | 1448 // intelligent guess. |
1484 | 1449 |
1485 bool writeModel = true; | 1450 bool writeModel = true; |
1486 bool haveDerivation = false; | 1451 bool haveDerivation = false; |
1487 | 1452 |
1488 if (rec.source && rec.transform.getIdentifier() != "") { | 1453 if (!rec.second.source.isNone() && |
1454 rec.second.transform.getIdentifier() != "") { | |
1489 haveDerivation = true; | 1455 haveDerivation = true; |
1490 } | 1456 } |
1491 | 1457 |
1492 if (pass == nonDerivedPass) { | 1458 if (pass == nonDerivedPass) { |
1493 if (haveDerivation) { | 1459 if (haveDerivation) { |
1500 continue; | 1466 continue; |
1501 } | 1467 } |
1502 } | 1468 } |
1503 | 1469 |
1504 if (haveDerivation) { | 1470 if (haveDerivation) { |
1505 if (dynamic_cast<const WritableWaveFileModel *>(model)) { | 1471 if (ModelById::isa<WritableWaveFileModel>(modelId) || |
1506 writeModel = false; | 1472 ModelById::isa<DenseThreeDimensionalModel>(modelId)) { |
1507 } else if (dynamic_cast<const DenseThreeDimensionalModel *>(model)) { | |
1508 writeModel = false; | 1473 writeModel = false; |
1509 } | 1474 } |
1510 } | 1475 } |
1511 | 1476 |
1512 if (writeModel) { | 1477 if (writeModel) { |
1513 model->toXml(out, indent + " "); | 1478 model->toXml(out, indent + " "); |
1514 written.insert(model); | 1479 written.insert(modelId); |
1515 } | 1480 } |
1516 | 1481 |
1517 if (haveDerivation) { | 1482 if (haveDerivation) { |
1518 writeBackwardCompatibleDerivation(out, indent + " ", | 1483 writeBackwardCompatibleDerivation(out, indent + " ", |
1519 model, rec); | 1484 modelId, rec.second); |
1520 } | 1485 } |
1521 | 1486 |
1522 //!!! We should probably own the PlayParameterRepository | 1487 //!!! We should probably own the PlayParameterRepository |
1523 PlayParameters *playParameters = | 1488 PlayParameters *playParameters = |
1524 PlayParameterRepository::getInstance()->getPlayParameters(model); | 1489 PlayParameterRepository::getInstance()->getPlayParameters |
1490 (modelId.untyped); | |
1525 if (playParameters) { | 1491 if (playParameters) { |
1526 playParameters->toXml | 1492 playParameters->toXml |
1527 (out, indent + " ", | 1493 (out, indent + " ", |
1528 QString("model=\"%1\"") | 1494 QString("model=\"%1\"") |
1529 .arg(model->getExportId())); | 1495 .arg(model->getExportId())); |
1535 // needs a toXml that writes out the export IDs of its reference | 1501 // needs a toXml that writes out the export IDs of its reference |
1536 // and aligned models, and then streams its path model. Note that | 1502 // and aligned models, and then streams its path model. Note that |
1537 // this will only work when the alignment is complete, so we | 1503 // this will only work when the alignment is complete, so we |
1538 // should probably wait for it if it isn't already by this point. | 1504 // should probably wait for it if it isn't already by this point. |
1539 | 1505 |
1540 for (std::set<Model *>::const_iterator i = written.begin(); | 1506 for (auto modelId: written) { |
1541 i != written.end(); ++i) { | 1507 |
1542 | 1508 auto model = ModelById::get(modelId); |
1543 const Model *model = *i; | 1509 if (!model) continue; |
1544 const AlignmentModel *alignment = model->getAlignment(); | 1510 |
1511 auto alignment = ModelById::get(model->getAlignment()); | |
1545 if (!alignment) continue; | 1512 if (!alignment) continue; |
1546 | 1513 |
1547 alignment->toXml(out, indent + " "); | 1514 alignment->toXml(out, indent + " "); |
1548 } | 1515 } |
1549 | 1516 |
1555 } | 1522 } |
1556 | 1523 |
1557 void | 1524 void |
1558 Document::writePlaceholderMainModel(QTextStream &out, QString indent) const | 1525 Document::writePlaceholderMainModel(QTextStream &out, QString indent) const |
1559 { | 1526 { |
1527 auto mainModel = ModelById::get(m_mainModel); | |
1528 if (!mainModel) return; | |
1560 out << indent; | 1529 out << indent; |
1561 out << QString("<model id=\"%1\" name=\"placeholder\" sampleRate=\"%2\" type=\"wavefile\" file=\":samples/silent.wav\" mainModel=\"true\"/>\n") | 1530 out << QString("<model id=\"%1\" name=\"placeholder\" sampleRate=\"%2\" type=\"wavefile\" file=\":samples/silent.wav\" mainModel=\"true\"/>\n") |
1562 .arg(m_mainModel->getExportId()) | 1531 .arg(mainModel->getExportId()) |
1563 .arg(m_mainModel->getSampleRate()); | 1532 .arg(mainModel->getSampleRate()); |
1564 } | 1533 } |
1565 | 1534 |
1566 void | 1535 void |
1567 Document::writeBackwardCompatibleDerivation(QTextStream &out, QString indent, | 1536 Document::writeBackwardCompatibleDerivation(QTextStream &out, QString indent, |
1568 Model *targetModel, | 1537 ModelId targetModelId, |
1569 const ModelRecord &rec) const | 1538 const ModelRecord &rec) const |
1570 { | 1539 { |
1571 // There is a lot of redundancy in the XML we output here, because | 1540 // There is a lot of redundancy in the XML we output here, because |
1572 // we want it to work with older SV session file reading code as | 1541 // we want it to work with older SV session file reading code as |
1573 // well. | 1542 // well. |
1590 // dealing with a newer format, we will also write an attribute | 1559 // dealing with a newer format, we will also write an attribute |
1591 // 'type="transform"' in the derivation element. | 1560 // 'type="transform"' in the derivation element. |
1592 | 1561 |
1593 const Transform &transform = rec.transform; | 1562 const Transform &transform = rec.transform; |
1594 | 1563 |
1564 //!!! in cases like these, where we think we have the model handle | |
1565 //!!! and nobody else should be releasing it, we probably ought to | |
1566 //!!! throw std::logic_error if !targetModel | |
1567 | |
1568 auto targetModel = ModelById::get(targetModelId); | |
1569 if (!targetModel) return; | |
1570 | |
1595 // Just for reference, this is what we would write if we didn't | 1571 // Just for reference, this is what we would write if we didn't |
1596 // have to be backward compatible: | 1572 // have to be backward compatible: |
1597 // | 1573 // |
1598 // out << indent | 1574 // out << indent |
1599 // << QString("<derivation type=\"transform\" source=\"%1\" " | 1575 // << QString("<derivation type=\"transform\" source=\"%1\" " |
1621 out << indent; | 1597 out << indent; |
1622 out << QString("<derivation type=\"transform\" source=\"%1\" " | 1598 out << QString("<derivation type=\"transform\" source=\"%1\" " |
1623 "model=\"%2\" channel=\"%3\" domain=\"%4\" " | 1599 "model=\"%2\" channel=\"%3\" domain=\"%4\" " |
1624 "stepSize=\"%5\" blockSize=\"%6\" %7windowType=\"%8\" " | 1600 "stepSize=\"%5\" blockSize=\"%6\" %7windowType=\"%8\" " |
1625 "transform=\"%9\">\n") | 1601 "transform=\"%9\">\n") |
1626 .arg(rec.source->getExportId()) | 1602 .arg(ModelById::getExportId(rec.source)) |
1627 .arg(targetModel->getExportId()) | 1603 .arg(targetModel->getExportId()) |
1628 .arg(rec.channel) | 1604 .arg(rec.channel) |
1629 .arg(TransformFactory::getInstance()->getTransformInputDomain | 1605 .arg(TransformFactory::getInstance()->getTransformInputDomain |
1630 (transform.getIdentifier())) | 1606 (transform.getIdentifier())) |
1631 .arg(transform.getStepSize()) | 1607 .arg(transform.getStepSize()) |