# HG changeset patch # User Chris Cannam # Date 1488212797 0 # Node ID d122d3595a328054600f8ac5e78a0b34fff73af4 # Parent 0f82c719d88548314dd5c6664a382187c82065ab Store aggregate models in the document and release them when they are invalidated (because their components have been released). They're no longer leaked, but we still don't save them in the session file. diff -r 0f82c719d885 -r d122d3595a32 framework/Document.cpp --- a/framework/Document.cpp Mon Feb 27 13:24:11 2017 +0000 +++ b/framework/Document.cpp Mon Feb 27 16:26:37 2017 +0000 @@ -22,6 +22,7 @@ #include "data/model/DenseThreeDimensionalModel.h" #include "data/model/DenseTimeValueModel.h" #include "data/model/FlexiNoteModel.h" +#include "data/model/AggregateWaveModel.h" #include "layer/Layer.h" #include "widgets/CommandHistory.h" @@ -544,6 +545,7 @@ for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { if (i->second.additional) { Model *m = i->first; + m->aboutToDelete(); emit modelAboutToBeDeleted(m); delete m; } @@ -697,6 +699,22 @@ emit modelAdded(model); } +void +Document::addAggregateModel(AggregateWaveModel *model) +{ + connect(model, SIGNAL(modelInvalidated()), + this, SLOT(aggregateModelInvalidated())); + m_aggregateModels.insert(model); +} + +void +Document::aggregateModelInvalidated() +{ + QObject *s = sender(); + AggregateWaveModel *aggregate = qobject_cast(s); + if (aggregate) releaseModel(aggregate); +} + Model * Document::addDerivedModel(const Transform &transform, const ModelTransformer::Input &input, @@ -775,18 +793,20 @@ bool toDelete = false; if (m_models.find(model) != m_models.end()) { - if (m_models[model].refcount == 0) { - cerr << "WARNING: Document::releaseModel: model " << model - << " reference count is zero already!" << endl; + SVCERR << "WARNING: Document::releaseModel: model " << model + << " reference count is zero already!" << endl; } else { if (--m_models[model].refcount == 0) { toDelete = true; } } + } else if (m_aggregateModels.find(model) != m_aggregateModels.end()) { + SVDEBUG << "Document::releaseModel: is an aggregate model" << endl; + toDelete = true; } else { - cerr << "WARNING: Document::releaseModel: Unfound model " - << model << endl; + SVCERR << "WARNING: Document::releaseModel: Unfound model " + << model << endl; toDelete = true; } @@ -803,9 +823,9 @@ if (sourceCount > 0) { SVDEBUG << "Document::releaseModel: Deleting model " - << model << " even though it is source for " - << sourceCount << " other derived model(s) -- resetting " - << "their source fields appropriately" << endl; + << model << " even though it is source for " + << sourceCount << " other derived model(s) -- resetting " + << "their source fields appropriately" << endl; } model->aboutToDelete(); diff -r 0f82c719d885 -r d122d3595a32 framework/Document.h --- a/framework/Document.h Mon Feb 27 13:24:11 2017 +0000 +++ b/framework/Document.h Mon Feb 27 16:26:37 2017 +0000 @@ -29,6 +29,7 @@ class Layer; class View; class WaveFileModel; +class AggregateWaveModel; class AdditionalModelConverter; @@ -234,6 +235,17 @@ * with a layer. */ void addImportedModel(Model *); + + /** + * Add an aggregate model (one which represents a set of component + * wave models as one model per channel in a single wave + * model). Aggregate models are unusual in that they are created + * for a single transform each and have no refcount. (This + * probably isn't ideal!) They are recorded separately from other + * models, and will be deleted if any of their component models + * are removed. + */ + void addAggregateModel(AggregateWaveModel *); /** * Associate the given model with the given layer. The model must @@ -309,6 +321,9 @@ void activity(QString); +protected slots: + void aggregateModelInvalidated(); + protected: void releaseModel(Model *model); @@ -364,6 +379,8 @@ */ void addAdditionalModel(Model *); + std::set m_aggregateModels; + class AddLayerCommand : public Command { public: