comparison framework/Document.cpp @ 661:a2bf5e6c54ce single-point

Retain models in registration order, to assist in getting stable file format in load/save
author Chris Cannam
date Tue, 02 Apr 2019 14:32:24 +0100
parents 85ada073d2db
children 351b1302064e
comparison
equal deleted inserted replaced
660:85ada073d2db 661:a2bf5e6c54ce
88 if (!m_models.empty()) { 88 if (!m_models.empty()) {
89 SVDEBUG << "Document::~Document: WARNING: " 89 SVDEBUG << "Document::~Document: WARNING: "
90 << m_models.size() << " model(s) still remain -- " 90 << m_models.size() << " model(s) still remain -- "
91 << "should have been garbage collected when deleting layers" 91 << "should have been garbage collected when deleting layers"
92 << endl; 92 << endl;
93 while (!m_models.empty()) { 93 for (ModelRecord &rec: m_models) {
94 Model *model = m_models.begin()->first; 94 Model *model = rec.model;
95 if (model == m_mainModel) { 95 if (model == m_mainModel) {
96 // just in case! 96 // just in case!
97 SVDEBUG << "Document::~Document: WARNING: Main model is also" 97 SVDEBUG << "Document::~Document: WARNING: Main model is also"
98 << " in models list!" << endl; 98 << " in models list!" << endl;
99 } else if (model) { 99 } else if (model) {
100 model->aboutToDelete(); 100 model->aboutToDelete();
101 emit modelAboutToBeDeleted(model); 101 emit modelAboutToBeDeleted(model);
102 delete model; 102 delete model;
103 } 103 }
104 m_models.erase(m_models.begin()); 104 }
105 } 105 m_models.clear();
106 } 106 }
107 107
108 #ifdef DEBUG_DOCUMENT 108 #ifdef DEBUG_DOCUMENT
109 SVDEBUG << "Document::~Document: About to get rid of main model" 109 SVDEBUG << "Document::~Document: About to get rid of main model"
110 << endl; 110 << endl;
369 LayerFactory::getInstance()->getValidLayerTypes(newModel); 369 LayerFactory::getInstance()->getValidLayerTypes(newModel);
370 370
371 if (types.empty()) { 371 if (types.empty()) {
372 SVCERR << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << names[i] << endl; 372 SVCERR << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << names[i] << endl;
373 //!!! inadequate cleanup: 373 //!!! inadequate cleanup:
374 newModel->aboutToDelete(); 374 deleteModelFromList(newModel);
375 emit modelAboutToBeDeleted(newModel);
376 m_models.erase(newModel);
377 delete newModel;
378 return vector<Layer *>(); 375 return vector<Layer *>();
379 } 376 }
380 377
381 //!!! for now, just use the first suitable layer type 378 //!!! for now, just use the first suitable layer type
382 379
432 // delete any of the models. 429 // delete any of the models.
433 430
434 #ifdef DEBUG_DOCUMENT 431 #ifdef DEBUG_DOCUMENT
435 SVDEBUG << "Document::setMainModel: Have " 432 SVDEBUG << "Document::setMainModel: Have "
436 << m_layers.size() << " layers" << endl; 433 << m_layers.size() << " layers" << endl;
437 cerr << "Models now: "; 434 SVDEBUG << "Models now: ";
438 for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) { 435 for (const auto &r: m_models) {
439 cerr << i->first << " "; 436 SVDEBUG << r.model << " ";
440 } 437 }
441 SVDEBUG << endl; 438 SVDEBUG << endl;
442 SVDEBUG << "Old main model: " << oldMainModel << endl; 439 SVDEBUG << "Old main model: " << oldMainModel << endl;
443 #endif 440 #endif
444 441
467 // get rid of this hideous degenerate 464 // get rid of this hideous degenerate
468 obsoleteLayers.push_back(layer); 465 obsoleteLayers.push_back(layer);
469 continue; 466 continue;
470 } 467 }
471 468
472 if (m_models.find(model) == m_models.end()) { 469 auto mitr = findModelInList(model);
473 cerr << "WARNING: Document::setMainModel: Unknown model " 470
474 << model << " in layer " << layer << endl; 471 if (mitr == m_models.end()) {
472 SVCERR << "WARNING: Document::setMainModel: Unknown model "
473 << model << " in layer " << layer << endl;
475 // and this one 474 // and this one
476 obsoleteLayers.push_back(layer); 475 obsoleteLayers.push_back(layer);
477 continue; 476 continue;
478 } 477 }
479 478
480 if (m_models[model].source && 479 ModelRecord record = *mitr;
481 (m_models[model].source == oldMainModel)) { 480
481 if (record.source && (record.source == oldMainModel)) {
482 482
483 #ifdef DEBUG_DOCUMENT 483 #ifdef DEBUG_DOCUMENT
484 SVDEBUG << "... it uses a model derived from the old main model, regenerating" << endl; 484 SVDEBUG << "... it uses a model derived from the old main model, regenerating" << endl;
485 #endif 485 #endif
486 486
487 // This model was derived from the previous main 487 // This model was derived from the previous main
488 // model: regenerate it. 488 // model: regenerate it.
489 489
490 const Transform &transform = m_models[model].transform; 490 const Transform &transform = record.transform;
491 QString transformId = transform.getIdentifier(); 491 QString transformId = transform.getIdentifier();
492 492
493 //!!! We have a problem here if the number of channels in 493 //!!! We have a problem here if the number of channels in
494 //the main model has changed. 494 //the main model has changed.
495 495
496 QString message; 496 QString message;
497 Model *replacementModel = 497 Model *replacementModel =
498 addDerivedModel(transform, 498 addDerivedModel(transform,
499 ModelTransformer::Input 499 ModelTransformer::Input
500 (m_mainModel, m_models[model].channel), 500 (m_mainModel, record.channel),
501 message); 501 message);
502 502
503 if (!replacementModel) { 503 if (!replacementModel) {
504 SVCERR << "WARNING: Document::setMainModel: Failed to regenerate model for transform \"" 504 SVCERR << "WARNING: Document::setMainModel: Failed to regenerate model for transform \""
505 << transformId << "\"" << " in layer " << layer << endl; 505 << transformId << "\"" << " in layer " << layer << endl;
540 540
541 for (size_t k = 0; k < obsoleteLayers.size(); ++k) { 541 for (size_t k = 0; k < obsoleteLayers.size(); ++k) {
542 deleteLayer(obsoleteLayers[k], true); 542 deleteLayer(obsoleteLayers[k], true);
543 } 543 }
544 544
545 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { 545 std::set<Model *> additionalModels;
546 if (i->second.additional) { 546 for (const auto &rec : m_models) {
547 Model *m = i->first; 547 if (rec.additional) {
548 m->aboutToDelete(); 548 additionalModels.insert(rec.model);
549 emit modelAboutToBeDeleted(m); 549 }
550 delete m; 550 }
551 } 551 for (Model *a: additionalModels) {
552 } 552 deleteModelFromList(a);
553 553 }
554 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { 554
555 555 for (const auto &rec : m_models) {
556 Model *m = i->first; 556
557 Model *m = rec.model;
557 558
558 #ifdef DEBUG_DOCUMENT 559 #ifdef DEBUG_DOCUMENT
559 SVDEBUG << "considering alignment for model " << m << " (name \"" 560 SVDEBUG << "considering alignment for model " << m << " (name \""
560 << m->objectName() << "\")" << endl; 561 << m->objectName() << "\")" << endl;
561 #endif 562 #endif
589 void 590 void
590 Document::addAlreadyDerivedModel(const Transform &transform, 591 Document::addAlreadyDerivedModel(const Transform &transform,
591 const ModelTransformer::Input &input, 592 const ModelTransformer::Input &input,
592 Model *outputModelToAdd) 593 Model *outputModelToAdd)
593 { 594 {
594 if (m_models.find(outputModelToAdd) != m_models.end()) { 595 if (findModelInList(outputModelToAdd) != m_models.end()) {
595 cerr << "WARNING: Document::addAlreadyDerivedModel: Model already added" 596 SVCERR << "WARNING: Document::addAlreadyDerivedModel: Model already added"
596 << endl; 597 << endl;
597 return; 598 return;
598 } 599 }
599 600
600 #ifdef DEBUG_DOCUMENT 601 #ifdef DEBUG_DOCUMENT
604 SVDEBUG << "Document::addAlreadyDerivedModel: source is " << input.getModel() << endl; 605 SVDEBUG << "Document::addAlreadyDerivedModel: source is " << input.getModel() << endl;
605 } 606 }
606 #endif 607 #endif
607 608
608 ModelRecord rec; 609 ModelRecord rec;
610 rec.model = outputModelToAdd;
609 rec.source = input.getModel(); 611 rec.source = input.getModel();
610 rec.channel = input.getChannel(); 612 rec.channel = input.getChannel();
611 rec.transform = transform; 613 rec.transform = transform;
612 rec.additional = false; 614 rec.additional = false;
613 rec.refcount = 0; 615 rec.refcount = 0;
614 616
615 outputModelToAdd->setSourceModel(input.getModel()); 617 outputModelToAdd->setSourceModel(input.getModel());
616 618
617 m_models[outputModelToAdd] = rec; 619 m_models.push_back(rec);
618 620
619 #ifdef DEBUG_DOCUMENT 621 #ifdef DEBUG_DOCUMENT
620 cerr << "Document::addAlreadyDerivedModel: Added model " << outputModelToAdd << endl; 622 SVDEBUG << "Document::addAlreadyDerivedModel: Added model " << outputModelToAdd << endl;
621 cerr << "Models now: "; 623 SVDEBUG << "Models now: ";
622 for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) { 624 for (const auto &rec : m_models) {
623 cerr << i->first << " "; 625 SVDEBUG << rec.model << " ";
624 } 626 }
625 SVDEBUG << endl; 627 SVDEBUG << endl;
626 #endif 628 #endif
627 629
628 emit modelAdded(outputModelToAdd); 630 emit modelAdded(outputModelToAdd);
630 632
631 633
632 void 634 void
633 Document::addImportedModel(Model *model) 635 Document::addImportedModel(Model *model)
634 { 636 {
635 if (m_models.find(model) != m_models.end()) { 637 if (findModelInList(model) != m_models.end()) {
636 cerr << "WARNING: Document::addImportedModel: Model already added" 638 SVCERR << "WARNING: Document::addImportedModel: Model already added"
637 << endl; 639 << endl;
638 return; 640 return;
639 } 641 }
640 642
641 ModelRecord rec; 643 ModelRecord rec;
644 rec.model = model;
642 rec.source = nullptr; 645 rec.source = nullptr;
643 rec.channel = 0; 646 rec.channel = 0;
644 rec.refcount = 0; 647 rec.refcount = 0;
645 rec.additional = false; 648 rec.additional = false;
646 649
647 m_models[model] = rec; 650 m_models.push_back(rec);
648 651
649 #ifdef DEBUG_DOCUMENT 652 #ifdef DEBUG_DOCUMENT
650 SVDEBUG << "Document::addImportedModel: Added model " << model << endl; 653 SVDEBUG << "Document::addImportedModel: Added model " << model << endl;
651 cerr << "Models now: "; 654 SVDEBUG << "Models now: ";
652 for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) { 655 for (const auto &rec : m_models) {
653 cerr << i->first << " "; 656 SVDEBUG << rec.model << " ";
654 } 657 }
655 SVDEBUG << endl; 658 SVDEBUG << endl;
656 #endif 659 #endif
657 660
658 if (m_autoAlignment) { 661 if (m_autoAlignment) {
666 } 669 }
667 670
668 void 671 void
669 Document::addAdditionalModel(Model *model) 672 Document::addAdditionalModel(Model *model)
670 { 673 {
671 if (m_models.find(model) != m_models.end()) { 674 if (findModelInList(model) != m_models.end()) {
672 cerr << "WARNING: Document::addAdditionalModel: Model already added" 675 SVCERR << "WARNING: Document::addAdditionalModel: Model already added"
673 << endl; 676 << endl;
674 return; 677 return;
675 } 678 }
676 679
677 ModelRecord rec; 680 ModelRecord rec;
681 rec.model = model;
678 rec.source = nullptr; 682 rec.source = nullptr;
679 rec.channel = 0; 683 rec.channel = 0;
680 rec.refcount = 0; 684 rec.refcount = 0;
681 rec.additional = true; 685 rec.additional = true;
682 686
683 m_models[model] = rec; 687 m_models.push_back(rec);
684 688
685 #ifdef DEBUG_DOCUMENT 689 #ifdef DEBUG_DOCUMENT
686 SVDEBUG << "Document::addAdditionalModel: Added model " << model << endl; 690 SVDEBUG << "Document::addAdditionalModel: Added model " << model << endl;
687 cerr << "Models now: "; 691 SVDEBUG << "Models now: ";
688 for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) { 692 for (const auto &rec : m_models) {
689 cerr << i->first << " "; 693 SVDEBUG << rec.model << " ";
690 } 694 }
691 SVDEBUG << endl; 695 SVDEBUG << endl;
692 #endif 696 #endif
693 697
694 if (m_autoAlignment) { 698 if (m_autoAlignment) {
720 Model * 724 Model *
721 Document::addDerivedModel(const Transform &transform, 725 Document::addDerivedModel(const Transform &transform,
722 const ModelTransformer::Input &input, 726 const ModelTransformer::Input &input,
723 QString &message) 727 QString &message)
724 { 728 {
725 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { 729 for (auto &rec : m_models) {
726 if (i->second.transform == transform && 730 if (rec.transform == transform &&
727 i->second.source == input.getModel() && 731 rec.source == input.getModel() &&
728 i->second.channel == input.getChannel()) { 732 rec.channel == input.getChannel()) {
729 std::cerr << "derived model taken from map " << std::endl; 733 SVDEBUG << "derived model taken from map " << endl;
730 return i->first; 734 return rec.model;
731 } 735 }
732 } 736 }
733 737
734 Transforms tt; 738 Transforms tt;
735 tt.push_back(transform); 739 tt.push_back(transform);
792 return; 796 return;
793 } 797 }
794 798
795 bool toDelete = false; 799 bool toDelete = false;
796 800
797 if (m_models.find(model) != m_models.end()) { 801 ModelList::iterator mitr = findModelInList(model);
798 if (m_models[model].refcount == 0) { 802
803 if (mitr != m_models.end()) {
804 if (mitr->refcount == 0) {
799 SVCERR << "WARNING: Document::releaseModel: model " << model 805 SVCERR << "WARNING: Document::releaseModel: model " << model
800 << " reference count is zero already!" << endl; 806 << " reference count is zero already!" << endl;
801 } else { 807 } else {
802 if (--m_models[model].refcount == 0) { 808 if (--mitr->refcount == 0) {
803 toDelete = true; 809 toDelete = true;
804 } 810 }
805 } 811 }
806 } else if (m_aggregateModels.find(model) != m_aggregateModels.end()) { 812 } else if (m_aggregateModels.find(model) != m_aggregateModels.end()) {
807 SVDEBUG << "Document::releaseModel: is an aggregate model" << endl; 813 SVDEBUG << "Document::releaseModel: is an aggregate model" << endl;
814 820
815 if (toDelete) { 821 if (toDelete) {
816 822
817 int sourceCount = 0; 823 int sourceCount = 0;
818 824
819 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { 825 for (auto &rec: m_models) {
820 if (i->second.source == model) { 826 if (rec.source == model) {
821 ++sourceCount; 827 ++sourceCount;
822 i->second.source = nullptr; 828 rec.source = nullptr;
823 } 829 }
824 } 830 }
825 831
826 if (sourceCount > 0) { 832 if (sourceCount > 0) {
827 SVDEBUG << "Document::releaseModel: Deleting model " 833 SVDEBUG << "Document::releaseModel: Deleting model "
828 << model << " even though it is source for " 834 << model << " even though it is source for "
829 << sourceCount << " other derived model(s) -- resetting " 835 << sourceCount << " other derived model(s) -- resetting "
830 << "their source fields appropriately" << endl; 836 << "their source fields appropriately" << endl;
831 } 837 }
832 838
833 model->aboutToDelete(); 839 deleteModelFromList(model);
834 emit modelAboutToBeDeleted(model);
835 m_models.erase(model);
836 840
837 #ifdef DEBUG_DOCUMENT 841 #ifdef DEBUG_DOCUMENT
838 SVDEBUG << "Document::releaseModel: Deleted model " << model << endl; 842 SVDEBUG << "Document::releaseModel: Deleted model " << model << endl;
839 cerr << "Models now: "; 843 SVDEBUG << "Models now: ";
840 for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) { 844 for (const auto &r: m_models) {
841 cerr << i->first << " "; 845 SVDEBUG << r.model << " ";
842 } 846 }
843 SVDEBUG << endl; 847 SVDEBUG << endl;
844 #endif 848 #endif
845
846 delete model;
847 } 849 }
848 } 850 }
849 851
850 void 852 void
851 Document::deleteLayer(Layer *layer, bool force) 853 Document::deleteLayer(Layer *layer, bool force)
902 void 904 void
903 Document::setModel(Layer *layer, Model *model) 905 Document::setModel(Layer *layer, Model *model)
904 { 906 {
905 if (model && 907 if (model &&
906 model != m_mainModel && 908 model != m_mainModel &&
907 m_models.find(model) == m_models.end()) { 909 findModelInList(model) == m_models.end()) {
908 cerr << "ERROR: Document::setModel: Layer " << layer 910 SVCERR << "ERROR: Document::setModel: Layer " << layer
909 << " (\"" << layer->objectName() 911 << " (\"" << layer->objectName()
910 << "\") wants to use unregistered model " << model 912 << "\") wants to use unregistered model " << model
911 << ": register the layer's model before setting it!" 913 << ": register the layer's model before setting it!"
912 << endl; 914 << endl;
913 return; 915 return;
923 << "\")" << endl; 925 << "\")" << endl;
924 return; 926 return;
925 } 927 }
926 928
927 if (model && model != m_mainModel) { 929 if (model && model != m_mainModel) {
928 m_models[model].refcount ++; 930 ModelList::iterator mitr = findModelInList(model);
931 if (mitr != m_models.end()) {
932 mitr->refcount ++;
933 }
929 } 934 }
930 935
931 if (model && previousModel) { 936 if (model && previousModel) {
932 PlayParameterRepository::getInstance()->copyParameters 937 PlayParameterRepository::getInstance()->copyParameters
933 (previousModel, model); 938 (previousModel, model);
957 << "\") with no model being added to view: " 962 << "\") with no model being added to view: "
958 << "normally you want to set the model first" << endl; 963 << "normally you want to set the model first" << endl;
959 #endif 964 #endif
960 } else { 965 } else {
961 if (model != m_mainModel && 966 if (model != m_mainModel &&
962 m_models.find(model) == m_models.end()) { 967 findModelInList(model) == m_models.end()) {
963 cerr << "ERROR: Document::addLayerToView: Layer " << layer 968 SVCERR << "ERROR: Document::addLayerToView: Layer " << layer
964 << " has unregistered model " << model 969 << " has unregistered model " << model
965 << " -- register the layer's model before adding the layer!" << endl; 970 << " -- register the layer's model before adding the layer!" << endl;
966 return; 971 return;
967 } 972 }
968 } 973 }
1045 1050
1046 models.push_back(m_mainModel); 1051 models.push_back(m_mainModel);
1047 1052
1048 //!!! This will pick up all models, including those that aren't visible... 1053 //!!! This will pick up all models, including those that aren't visible...
1049 1054
1050 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { 1055 for (ModelRecord &rec: m_models) {
1051 1056
1052 Model *model = i->first; 1057 Model *model = rec.model;
1053 if (!model || model == m_mainModel) continue; 1058 if (!model || model == m_mainModel) continue;
1054 DenseTimeValueModel *dtvm = dynamic_cast<DenseTimeValueModel *>(model); 1059 DenseTimeValueModel *dtvm = dynamic_cast<DenseTimeValueModel *>(model);
1055 1060
1056 if (dtvm) { 1061 if (dtvm) {
1057 models.push_back(dtvm); 1062 models.push_back(dtvm);
1063 1068
1064 bool 1069 bool
1065 Document::isKnownModel(const Model *model) const 1070 Document::isKnownModel(const Model *model) const
1066 { 1071 {
1067 if (model == m_mainModel) return true; 1072 if (model == m_mainModel) return true;
1068 return (m_models.find(const_cast<Model *>(model)) != m_models.end()); 1073 for (const ModelRecord &rec: m_models) {
1074 if (rec.model == model) return true;
1075 }
1076 return false;
1069 } 1077 }
1070 1078
1071 bool 1079 bool
1072 Document::canAlign() 1080 Document::canAlign()
1073 { 1081 {
1113 } 1121 }
1114 1122
1115 void 1123 void
1116 Document::alignModels() 1124 Document::alignModels()
1117 { 1125 {
1118 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { 1126 for (const ModelRecord &rec: m_models) {
1119 alignModel(i->first); 1127 alignModel(rec.model);
1120 } 1128 }
1121 alignModel(m_mainModel); 1129 alignModel(m_mainModel);
1122 } 1130 }
1123 1131
1124 Document::AddLayerCommand::AddLayerCommand(Document *d, 1132 Document::AddLayerCommand::AddLayerCommand(Document *d,
1357 // have derivations. 1365 // have derivations.
1358 1366
1359 const int nonDerivedPass = 0, derivedPass = 1; 1367 const int nonDerivedPass = 0, derivedPass = 1;
1360 for (int pass = nonDerivedPass; pass <= derivedPass; ++pass) { 1368 for (int pass = nonDerivedPass; pass <= derivedPass; ++pass) {
1361 1369
1362 for (ModelMap::const_iterator i = m_models.begin(); 1370 for (const ModelRecord &rec: m_models) {
1363 i != m_models.end(); ++i) { 1371
1364 1372 Model *model = rec.model;
1365 Model *model = i->first;
1366 const ModelRecord &rec = i->second;
1367 1373
1368 if (used.find(model) == used.end()) continue; 1374 if (used.find(model) == used.end()) continue;
1369 1375
1370 #ifdef DEBUG_DOCUMENT 1376 #ifdef DEBUG_DOCUMENT
1371 SVDEBUG << "Document::toXml: looking at model " << model 1377 SVDEBUG << "Document::toXml: looking at model " << model