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())